mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
ac7d53ea52
68 changed files with 1624 additions and 527 deletions
|
|
@ -1296,7 +1296,10 @@ public class PeerNameColors: Equatable {
|
|||
return PeerNameColors(
|
||||
colors: defaultSingleColors,
|
||||
darkColors: [:],
|
||||
displayOrder: [5, 3, 1, 0, 2, 4, 6]
|
||||
displayOrder: [5, 3, 1, 0, 2, 4, 6],
|
||||
profileColors: [:],
|
||||
profileDarkColors: [:],
|
||||
profileDisplayOrder: []
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1304,6 +1307,10 @@ public class PeerNameColors: Equatable {
|
|||
public let darkColors: [Int32: Colors]
|
||||
public let displayOrder: [Int32]
|
||||
|
||||
public let profileColors: [Int32: Colors]
|
||||
public let profileDarkColors: [Int32: Colors]
|
||||
public let profileDisplayOrder: [Int32]
|
||||
|
||||
public func get(_ color: PeerNameColor, dark: Bool = false) -> Colors {
|
||||
if dark, let colors = self.darkColors[color.rawValue] {
|
||||
return colors
|
||||
|
|
@ -1314,10 +1321,30 @@ public class PeerNameColors: Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
fileprivate init(colors: [Int32: Colors], darkColors: [Int32: Colors], displayOrder: [Int32]) {
|
||||
public func getProfile(_ color: PeerNameColor, dark: Bool = false) -> Colors {
|
||||
if dark, let colors = self.profileDarkColors[color.rawValue] {
|
||||
return colors
|
||||
} else if let colors = self.profileColors[color.rawValue] {
|
||||
return colors
|
||||
} else {
|
||||
return Colors(main: UIColor(rgb: 0xcc5049))
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate init(
|
||||
colors: [Int32: Colors],
|
||||
darkColors: [Int32: Colors],
|
||||
displayOrder: [Int32],
|
||||
profileColors: [Int32: Colors],
|
||||
profileDarkColors: [Int32: Colors],
|
||||
profileDisplayOrder: [Int32]
|
||||
) {
|
||||
self.colors = colors
|
||||
self.darkColors = darkColors
|
||||
self.displayOrder = displayOrder
|
||||
self.profileColors = profileColors
|
||||
self.profileDarkColors = profileDarkColors
|
||||
self.profileDisplayOrder = profileDisplayOrder
|
||||
}
|
||||
|
||||
public static func with(appConfiguration: AppConfiguration) -> PeerNameColors {
|
||||
|
|
@ -1355,10 +1382,84 @@ public class PeerNameColors: Equatable {
|
|||
displayOrder = PeerNameColors.defaultValue.displayOrder
|
||||
}
|
||||
|
||||
var profileColors = PeerNameColors.defaultSingleColors
|
||||
var profileDarkColors: [Int32: Colors] = [:]
|
||||
|
||||
if let peerColors = data["profile_colors"] as? [String: [String]] {
|
||||
for (key, values) in peerColors {
|
||||
if let index = Int32(key) {
|
||||
let colorsArray = values.compactMap { UIColor(hexString: $0) }
|
||||
if let colorValues = Colors(colors: colorsArray) {
|
||||
profileColors[index] = colorValues
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
profileColors = [
|
||||
0: Colors(main: UIColor(rgb: 0x5A8FBB), secondary: nil, tertiary: nil),
|
||||
1: Colors(main: UIColor(rgb: 0x49A355), secondary: nil, tertiary: nil),
|
||||
2: Colors(main: UIColor(rgb: 0xC27C3E), secondary: nil, tertiary: nil),
|
||||
3: Colors(main: UIColor(rgb: 0xBA5650), secondary: nil, tertiary: nil),
|
||||
4: Colors(main: UIColor(rgb: 0x956AC8), secondary: nil, tertiary: nil),
|
||||
5: Colors(main: UIColor(rgb: 0x3E97AD), secondary: nil, tertiary: nil),
|
||||
6: Colors(main: UIColor(rgb: 0xB85378), secondary: nil, tertiary: nil),
|
||||
7: Colors(main: UIColor(rgb: 0x7F8B95), secondary: nil, tertiary: nil),
|
||||
8: Colors(main: UIColor(rgb: 0x538BC2), secondary: UIColor(rgb: 0x4DA8BD), tertiary: nil),
|
||||
9: Colors(main: UIColor(rgb: 0x3D9755), secondary: UIColor(rgb: 0x89A650), tertiary: nil),
|
||||
10: Colors(main: UIColor(rgb: 0xCF7244), secondary: UIColor(rgb: 0xCC9433), tertiary: nil),
|
||||
11: Colors(main: UIColor(rgb: 0xC9565D), secondary: UIColor(rgb: 0xD97C57), tertiary: nil),
|
||||
12: Colors(main: UIColor(rgb: 0x9662D4), secondary: UIColor(rgb: 0xB966B6), tertiary: nil),
|
||||
13: Colors(main: UIColor(rgb: 0x3D95BA), secondary: UIColor(rgb: 0x50AD98), tertiary: nil),
|
||||
14: Colors(main: UIColor(rgb: 0xB04F74), secondary: UIColor(rgb: 0xD1666D), tertiary: nil),
|
||||
15: Colors(main: UIColor(rgb: 0x637482), secondary: UIColor(rgb: 0x7B8A97), tertiary: nil),
|
||||
]
|
||||
}
|
||||
|
||||
if let darkPeerColors = data["dark_profile_colors"] as? [String: [String]] {
|
||||
for (key, values) in darkPeerColors {
|
||||
if let index = Int32(key) {
|
||||
let colorsArray = values.compactMap { UIColor(hexString: $0) }
|
||||
if let colorValues = Colors(colors: colorsArray) {
|
||||
profileDarkColors[index] = colorValues
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
profileDarkColors = [
|
||||
0: Colors(main: UIColor(rgb: 0x477194), secondary: nil, tertiary: nil),
|
||||
1: Colors(main: UIColor(rgb: 0x33713B), secondary: nil, tertiary: nil),
|
||||
2: Colors(main: UIColor(rgb: 0x945E2C), secondary: nil, tertiary: nil),
|
||||
3: Colors(main: UIColor(rgb: 0x9C4540), secondary: nil, tertiary: nil),
|
||||
4: Colors(main: UIColor(rgb: 0x715099), secondary: nil, tertiary: nil),
|
||||
5: Colors(main: UIColor(rgb: 0x387E87), secondary: nil, tertiary: nil),
|
||||
6: Colors(main: UIColor(rgb: 0x944763), secondary: nil, tertiary: nil),
|
||||
7: Colors(main: UIColor(rgb: 0x435261), secondary: nil, tertiary: nil),
|
||||
8: Colors(main: UIColor(rgb: 0x38618C), secondary: UIColor(rgb: 0x458BA1), tertiary: nil),
|
||||
9: Colors(main: UIColor(rgb: 0x296A43), secondary: UIColor(rgb: 0x5F8F44), tertiary: nil),
|
||||
10: Colors(main: UIColor(rgb: 0x8F552F), secondary: UIColor(rgb: 0xA17232), tertiary: nil),
|
||||
11: Colors(main: UIColor(rgb: 0x994343), secondary: UIColor(rgb: 0xAC583E), tertiary: nil),
|
||||
12: Colors(main: UIColor(rgb: 0x634691), secondary: UIColor(rgb: 0x9250A2), tertiary: nil),
|
||||
13: Colors(main: UIColor(rgb: 0x306C7C), secondary: UIColor(rgb: 0x3E987E), tertiary: nil),
|
||||
14: Colors(main: UIColor(rgb: 0x884160), secondary: UIColor(rgb: 0xA65259), tertiary: nil),
|
||||
15: Colors(main: UIColor(rgb: 0x384654), secondary: UIColor(rgb: 0x99ACC3), tertiary: nil),
|
||||
]
|
||||
}
|
||||
|
||||
var profileDisplayOrder: [Int32] = []
|
||||
if let order = data["profile_colors_available"] as? [Double] {
|
||||
profileDisplayOrder = order.map { Int32($0) }
|
||||
}
|
||||
if profileDisplayOrder.isEmpty {
|
||||
profileDisplayOrder = Array((0 ..< profileColors.count).map { i in Int32(i) })
|
||||
}
|
||||
|
||||
return PeerNameColors(
|
||||
colors: colors,
|
||||
darkColors: darkColors,
|
||||
displayOrder: displayOrder
|
||||
displayOrder: displayOrder,
|
||||
profileColors: profileColors,
|
||||
profileDarkColors: profileDarkColors,
|
||||
profileDisplayOrder: profileDisplayOrder
|
||||
)
|
||||
} else {
|
||||
return .defaultValue
|
||||
|
|
@ -1375,6 +1476,15 @@ public class PeerNameColors: Equatable {
|
|||
if lhs.displayOrder != rhs.displayOrder {
|
||||
return false
|
||||
}
|
||||
if lhs.profileColors != rhs.profileColors {
|
||||
return false
|
||||
}
|
||||
if lhs.profileDarkColors != rhs.profileDarkColors {
|
||||
return false
|
||||
}
|
||||
if lhs.profileDisplayOrder != rhs.profileDisplayOrder {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3531,7 +3531,7 @@ public final class ChatListSearchShimmerNode: ASDisplayNode {
|
|||
|
||||
let chatListPresentationData = ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.chatFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true)
|
||||
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let timestamp1: Int32 = 100000
|
||||
var peers: [EnginePeer.Id: EnginePeer] = [:]
|
||||
peers[peer1.id] = peer1
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ final class ChatListShimmerNode: ASDisplayNode {
|
|||
|
||||
let chatListPresentationData = ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.chatFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true)
|
||||
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let timestamp1: Int32 = 100000
|
||||
let peers: [EnginePeer.Id: EnginePeer] = [:]
|
||||
let interaction = ChatListNodeInteraction(context: context, animationCache: animationCache, animationRenderer: animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _, _ in }, togglePeerSelected: { _, _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ private enum InviteContactsEntry: Comparable, Identifiable {
|
|||
} else {
|
||||
status = .none
|
||||
}
|
||||
let peer: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: contact.firstName, lastName: contact.lastName, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: contact.firstName, lastName: contact.lastName, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .peer, peer: .peer(peer: peer, chatPeer: peer), status: status, enabled: true, selection: selection, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: ChatListSearchItemHeader(type: .contacts, theme: theme, strings: strings, actionTitle: nil, action: nil), action: { _ in
|
||||
interaction.toggleContact(id)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -610,6 +610,7 @@ final class ContextSourceContainer: ASDisplayNode {
|
|||
selection: presentationData.theme.contextMenu.primaryColor.withMultipliedAlpha(0.1)
|
||||
),
|
||||
customLayout: TabSelectorComponent.CustomLayout(
|
||||
font: Font.medium(14.0),
|
||||
spacing: 9.0
|
||||
),
|
||||
items: mappedItems,
|
||||
|
|
|
|||
|
|
@ -476,6 +476,8 @@ open class NavigationBar: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static let thinBackArrowImage = generateTintedImage(image: UIImage(bundleImageName: "Navigation/BackArrow"), color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
public static let titleFont = Font.with(size: 17.0, design: .regular, weight: .semibold, traits: [.monospacedNumbers])
|
||||
|
||||
|
|
@ -729,11 +731,20 @@ open class NavigationBar: ASDisplayNode {
|
|||
self.updateAccessibilityElements()
|
||||
}
|
||||
|
||||
public var enableAutomaticBackButton: Bool = true
|
||||
|
||||
var _previousItem: NavigationPreviousAction?
|
||||
public internal(set) var previousItem: NavigationPreviousAction? {
|
||||
get {
|
||||
if !self.enableAutomaticBackButton {
|
||||
return nil
|
||||
}
|
||||
return self._previousItem
|
||||
} set(value) {
|
||||
if !self.enableAutomaticBackButton {
|
||||
self._previousItem = nil
|
||||
return
|
||||
}
|
||||
if self._previousItem != value {
|
||||
if let previousValue = self._previousItem, case let .item(itemValue) = previousValue {
|
||||
if let previousItemListenerKey = self.previousItemListenerKey {
|
||||
|
|
|
|||
|
|
@ -338,6 +338,10 @@ public final class NavigationButtonNode: ContextControllerSourceNode {
|
|||
return nil
|
||||
}
|
||||
|
||||
public var mainContentNode: ASDisplayNode? {
|
||||
return self.nodes.first
|
||||
}
|
||||
|
||||
public var pressed: (Int) -> () = { _ in }
|
||||
public var highlightChanged: (Int, Bool) -> () = { _, _ in }
|
||||
|
||||
|
|
@ -397,6 +401,8 @@ public final class NavigationButtonNode: ContextControllerSourceNode {
|
|||
}
|
||||
}
|
||||
|
||||
public var contentsColor: UIColor?
|
||||
|
||||
public func updateManualAlpha(alpha: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
for node in self.nodes {
|
||||
transition.updateAlpha(node: node, alpha: alpha)
|
||||
|
|
@ -411,6 +417,7 @@ public final class NavigationButtonNode: ContextControllerSourceNode {
|
|||
node = NavigationButtonItemNode()
|
||||
node.color = self.color
|
||||
node.rippleColor = self.rippleColor
|
||||
node.layer.layerTintColor = self.contentsColor?.cgColor
|
||||
node.highlightChanged = { [weak node, weak self] value in
|
||||
if let strongSelf = self, let node = node {
|
||||
if let index = strongSelf.nodes.firstIndex(where: { $0 === node }) {
|
||||
|
|
@ -454,6 +461,7 @@ public final class NavigationButtonNode: ContextControllerSourceNode {
|
|||
node = NavigationButtonItemNode()
|
||||
node.color = self.color
|
||||
node.rippleColor = self.rippleColor
|
||||
node.layer.layerTintColor = self.contentsColor?.cgColor
|
||||
node.highlightChanged = { [weak node, weak self] value in
|
||||
if let strongSelf = self, let node = node {
|
||||
if let index = strongSelf.nodes.firstIndex(where: { $0 === node }) {
|
||||
|
|
|
|||
|
|
@ -47,4 +47,8 @@ open class ASImageNode: ASDisplayNode {
|
|||
override public func calculateSizeThatFits(_ contrainedSize: CGSize) -> CGSize {
|
||||
return self.image?.size ?? CGSize()
|
||||
}
|
||||
|
||||
public var asdf: Int {
|
||||
return 1234
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ public protocol CustomViewControllerNavigationDataSummary: AnyObject {
|
|||
return self.prefersOnScreenNavigationHidden
|
||||
}
|
||||
|
||||
public internal(set) var previousItem: NavigationPreviousAction?
|
||||
open var previousItem: NavigationPreviousAction?
|
||||
|
||||
open var navigationPresentation: ViewControllerNavigationPresentation = .default
|
||||
open var _presentedInModal: Bool = false
|
||||
|
|
|
|||
|
|
@ -1412,7 +1412,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
}, openUrl: { _ in }, openPeer: { _ in
|
||||
}, showAll: false)
|
||||
|
||||
let peer = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
let peer = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer, text: "", attributes: [], media: [map], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
|
||||
let controller = LocationViewController(context: self.context, subject: EngineMessage(message), params: controllerParams)
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ public final class InviteLinkViewController: ViewController {
|
|||
if requestsState.importers.isEmpty && requestsState.isLoadingMore {
|
||||
count = min(4, state.count)
|
||||
loading = true
|
||||
let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
for i in 0 ..< count {
|
||||
entries.append(.request(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true))
|
||||
}
|
||||
|
|
@ -760,7 +760,7 @@ public final class InviteLinkViewController: ViewController {
|
|||
if state.importers.isEmpty && state.isLoadingMore {
|
||||
count = min(4, state.count)
|
||||
loading = true
|
||||
let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
for i in 0 ..< count {
|
||||
entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, false, true))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ swift_library(
|
|||
"//submodules/ManagedAnimationNode:ManagedAnimationNode",
|
||||
"//submodules/AvatarNode",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/TelegramUI/Components/TabSelectorComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -2,48 +2,48 @@ import Foundation
|
|||
import UIKit
|
||||
import SegmentedControlNode
|
||||
import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import TabSelectorComponent
|
||||
import Display
|
||||
|
||||
public final class ItemListControllerSegmentedTitleView: UIView {
|
||||
private let segmentedControlNode: SegmentedControlNode
|
||||
private let tabSelector = ComponentView<Empty>()
|
||||
|
||||
public var theme: PresentationTheme {
|
||||
didSet {
|
||||
self.segmentedControlNode.updateTheme(SegmentedControlTheme(theme: self.theme))
|
||||
if self.theme !== oldValue {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
public var segments: [String] {
|
||||
didSet {
|
||||
if self.segments != oldValue {
|
||||
self.segmentedControlNode.items = self.segments.map { SegmentedControlItem(title: $0) }
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var index: Int {
|
||||
get {
|
||||
return self.segmentedControlNode.selectedIndex
|
||||
}
|
||||
set {
|
||||
self.segmentedControlNode.selectedIndex = newValue
|
||||
didSet {
|
||||
if self.index != oldValue {
|
||||
self.animateLayout = true
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var validLayout: CGSize?
|
||||
private var animateLayout: Bool = false
|
||||
|
||||
public var indexUpdated: ((Int) -> Void)?
|
||||
|
||||
public init(theme: PresentationTheme, segments: [String], selectedIndex: Int) {
|
||||
self.theme = theme
|
||||
self.segments = segments
|
||||
|
||||
self.segmentedControlNode = SegmentedControlNode(theme: SegmentedControlTheme(theme: theme), items: segments.map { SegmentedControlItem(title: $0) }, selectedIndex: selectedIndex)
|
||||
self.index = selectedIndex
|
||||
|
||||
super.init(frame: CGRect())
|
||||
|
||||
self.segmentedControlNode.selectedIndexChanged = { [weak self] index in
|
||||
self?.indexUpdated?(index)
|
||||
}
|
||||
|
||||
self.addSubnode(self.segmentedControlNode)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
|
|
@ -54,7 +54,57 @@ public final class ItemListControllerSegmentedTitleView: UIView {
|
|||
super.layoutSubviews()
|
||||
|
||||
let size = self.bounds.size
|
||||
let controlSize = self.segmentedControlNode.updateLayout(.sizeToFit(maximumWidth: size.width, minimumWidth: 160.0, height: 32.0), transition: .immediate)
|
||||
self.segmentedControlNode.frame = CGRect(origin: CGPoint(x: floor((size.width - controlSize.width) / 2.0), y: floor((size.height - controlSize.height) / 2.0)), size: controlSize)
|
||||
self.validLayout = size
|
||||
self.update(transition: .immediate)
|
||||
}
|
||||
|
||||
private func update(transition: Transition) {
|
||||
guard let size = self.validLayout else {
|
||||
return
|
||||
}
|
||||
|
||||
let mappedItems = zip(0 ..< self.segments.count, self.segments).map { index, segment in
|
||||
return TabSelectorComponent.Item(
|
||||
id: AnyHashable(index),
|
||||
title: segment
|
||||
)
|
||||
}
|
||||
|
||||
var transition = transition
|
||||
if self.animateLayout {
|
||||
transition = .spring(duration: 0.4)
|
||||
self.animateLayout = false
|
||||
}
|
||||
|
||||
let tabSelectorSize = self.tabSelector.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(TabSelectorComponent(
|
||||
colors: TabSelectorComponent.Colors(
|
||||
foreground: self.theme.list.itemPrimaryTextColor.withMultipliedAlpha(0.8),
|
||||
selection: self.theme.list.itemPrimaryTextColor.withMultipliedAlpha(0.05)
|
||||
),
|
||||
customLayout: TabSelectorComponent.CustomLayout(
|
||||
font: Font.medium(15.0),
|
||||
spacing: 8.0
|
||||
),
|
||||
items: mappedItems,
|
||||
selectedId: AnyHashable(self.index),
|
||||
setSelectedId: { [weak self] id in
|
||||
guard let self, let index = id.base as? Int else {
|
||||
return
|
||||
}
|
||||
self.indexUpdated?(index)
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: size.width, height: 44.0)
|
||||
)
|
||||
let tabSelectorFrame = CGRect(origin: CGPoint(x: floor((size.width - tabSelectorSize.width) / 2.0), y: floor((size.height - tabSelectorSize.height) / 2.0)), size: tabSelectorSize)
|
||||
if let tabSelectorView = self.tabSelector.view {
|
||||
if tabSelectorView.superview == nil {
|
||||
self.addSubview(tabSelectorView)
|
||||
}
|
||||
transition.setFrame(view: tabSelectorView, frame: tabSelectorFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -854,7 +854,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI
|
|||
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1))
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
let previewText = groupLayouts.count > 1 ? presentationData.strings.Attachment_MessagesPreview : presentationData.strings.Attachment_MessagePreview
|
||||
|
||||
|
|
|
|||
|
|
@ -663,7 +663,7 @@ private func deviceContactInfoEntries(account: Account, engine: TelegramEngine,
|
|||
firstName = presentationData.strings.Message_Contact
|
||||
}
|
||||
|
||||
entries.append(.info(entries.count, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer: peer ?? EnginePeer.user(TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: firstName, lastName: isOrganization ? nil : personName.1, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)), state: ItemListAvatarAndNameInfoItemState(editingName: editingName, updatingName: nil), job: isOrganization ? nil : jobSummary, isPlain: !isShare, hiddenAvatar: hiddenAvatar))
|
||||
entries.append(.info(entries.count, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer: peer ?? EnginePeer.user(TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: firstName, lastName: isOrganization ? nil : personName.1, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)), state: ItemListAvatarAndNameInfoItemState(editingName: editingName, updatingName: nil), job: isOrganization ? nil : jobSummary, isPlain: !isShare, hiddenAvatar: hiddenAvatar))
|
||||
|
||||
if !selecting {
|
||||
if let _ = peer {
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, UIScrollViewDel
|
|||
let otherPeerId = self.context.account.peerId
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var messages = SimpleDictionary<MessageId, Message>()
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
|
||||
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
|||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
let messages = SimpleDictionary<MessageId, Message>()
|
||||
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: item.peerName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: item.peerName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
let forwardInfo = MessageForwardInfo(author: item.linkEnabled ? peers[peerId] : nil, source: nil, sourceMessageId: nil, date: 0, authorSignature: item.linkEnabled ? nil : item.peerName, psaType: nil, flags: [])
|
||||
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ class ReactionChatPreviewItemNode: ListViewItemNode {
|
|||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
let messages = SimpleDictionary<MessageId, Message>()
|
||||
|
||||
peers[userPeerId] = TelegramUser(id: userPeerId, accessHash: nil, firstName: item.strings.Settings_QuickReactionSetup_DemoMessageAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[userPeerId] = TelegramUser(id: userPeerId, accessHash: nil, firstName: item.strings.Settings_QuickReactionSetup_DemoMessageAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
let messageText = item.strings.Settings_QuickReactionSetup_DemoMessageText
|
||||
|
||||
|
|
|
|||
|
|
@ -304,14 +304,14 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
|
|||
)
|
||||
}
|
||||
|
||||
let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
|
||||
let timestamp = self.referenceTimestamp
|
||||
|
||||
|
|
@ -427,8 +427,8 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
|
|||
let otherPeerId = self.context.account.peerId
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var messages = SimpleDictionary<MessageId, Message>()
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
|
||||
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
|
|
|
|||
|
|
@ -937,12 +937,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||
)
|
||||
}
|
||||
|
||||
let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
|
||||
let timestamp = self.referenceTimestamp
|
||||
|
||||
|
|
@ -1030,8 +1030,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||
let otherPeerId = self.context.account.peerId
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var messages = SimpleDictionary<MessageId, Message>()
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
var sampleMessages: [Message] = []
|
||||
|
||||
|
|
|
|||
|
|
@ -452,15 +452,15 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
|
||||
let chatListPresentationData = ChatListPresentationData(theme: self.previewTheme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: true)
|
||||
|
||||
let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let peer7: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(6)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil))
|
||||
let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
let peer7: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(6)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil))
|
||||
|
||||
let timestamp = self.referenceTimestamp
|
||||
|
||||
|
|
@ -581,8 +581,8 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
let otherPeerId = self.context.account.peerId
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var messages = SimpleDictionary<MessageId, Message>()
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
var sampleMessages: [Message] = []
|
||||
|
||||
|
|
|
|||
|
|
@ -163,11 +163,11 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode {
|
|||
|
||||
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
|
||||
if let (author, text) = messageItem.reply {
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: author, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: messageItem.nameColor, backgroundEmojiId: messageItem.backgroundEmojiId)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: author, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: messageItem.nameColor, backgroundEmojiId: messageItem.backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
}
|
||||
|
||||
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1491,8 +1491,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
|||
let otherPeerId = self.context.account.peerId
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
let messages = SimpleDictionary<MessageId, Message>()
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil)
|
||||
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
var topMessageText = ""
|
||||
var bottomMessageText = ""
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||
}
|
||||
}
|
||||
|
||||
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId)
|
||||
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
case let .channelForbidden(flags, id, accessHash, title, untilDate):
|
||||
let info: TelegramChannelInfo
|
||||
if (flags & Int32(1 << 8)) != 0 {
|
||||
|
|
@ -162,7 +162,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||
info = .broadcast(TelegramChannelBroadcastInfo(flags: []))
|
||||
}
|
||||
|
||||
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
|
|||
}
|
||||
}
|
||||
|
||||
return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId)
|
||||
return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
} else {
|
||||
return parseTelegramGroupOrChannel(chat: rhs)
|
||||
}
|
||||
|
|
@ -266,6 +266,6 @@ func mergeChannel(lhs: TelegramChannel?, rhs: TelegramChannel) -> TelegramChanne
|
|||
|
||||
let storiesHidden: Bool? = rhs.storiesHidden ?? lhs.storiesHidden
|
||||
|
||||
return TelegramChannel(id: lhs.id, accessHash: accessHash, title: rhs.title, username: rhs.username, photo: rhs.photo, creationDate: rhs.creationDate, version: rhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: rhs.restrictionInfo, adminRights: rhs.adminRights, bannedRights: rhs.bannedRights, defaultBannedRights: rhs.defaultBannedRights, usernames: rhs.usernames, storiesHidden: storiesHidden, nameColor: rhs.nameColor, backgroundEmojiId: rhs.backgroundEmojiId)
|
||||
return TelegramChannel(id: lhs.id, accessHash: accessHash, title: rhs.title, username: rhs.username, photo: rhs.photo, creationDate: rhs.creationDate, version: rhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: rhs.restrictionInfo, adminRights: rhs.adminRights, bannedRights: rhs.bannedRights, defaultBannedRights: rhs.defaultBannedRights, usernames: rhs.usernames, storiesHidden: storiesHidden, nameColor: rhs.nameColor, backgroundEmojiId: rhs.backgroundEmojiId, profileColor: rhs.profileColor, profileBackgroundEmojiId: rhs.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ extension TelegramUser {
|
|||
|
||||
let restrictionInfo: PeerAccessRestrictionInfo? = restrictionReason.flatMap(PeerAccessRestrictionInfo.init(apiReasons:))
|
||||
|
||||
self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, firstName: firstName, lastName: lastName, username: username, phone: phone, photo: representations, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId)
|
||||
self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, firstName: firstName, lastName: lastName, username: username, phone: phone, photo: representations, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
case let .userEmpty(id):
|
||||
self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ extension TelegramUser {
|
|||
accessHash = lhs.accessHash ?? rhsAccessHashValue
|
||||
}
|
||||
|
||||
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: lhs.username, phone: lhs.phone, photo: telegramPhoto, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: lhs.usernames, storiesHidden: lhs.storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId)
|
||||
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: lhs.username, phone: lhs.phone, photo: telegramPhoto, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: lhs.usernames, storiesHidden: lhs.storiesHidden, nameColor: nameColor.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
} else {
|
||||
return TelegramUser(user: rhs)
|
||||
}
|
||||
|
|
@ -241,7 +241,7 @@ extension TelegramUser {
|
|||
storiesHidden = lhs.storiesHidden
|
||||
}
|
||||
|
||||
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: lhs.username, phone: lhs.phone, photo: photo, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus, usernames: lhs.usernames, storiesHidden: storiesHidden, nameColor: rhs.nameColor, backgroundEmojiId: rhs.backgroundEmojiId)
|
||||
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: lhs.username, phone: lhs.phone, photo: photo, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus, usernames: lhs.usernames, storiesHidden: storiesHidden, nameColor: rhs.nameColor, backgroundEmojiId: rhs.backgroundEmojiId, profileColor: rhs.profileColor, profileBackgroundEmojiId: rhs.profileBackgroundEmojiId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1121,7 +1121,7 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
if updatedState.peers[peerId] == nil {
|
||||
updatedState.updatePeer(peerId, { peer in
|
||||
if peer == nil {
|
||||
return TelegramUser(id: peerId, accessHash: nil, firstName: "Telegram Notifications", lastName: nil, username: nil, phone: nil, photo: [], botInfo: BotUserInfo(flags: [], inlinePlaceholder: nil), restrictionInfo: nil, flags: [.isVerified], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
return TelegramUser(id: peerId, accessHash: nil, firstName: "Telegram Notifications", lastName: nil, username: nil, phone: nil, photo: [], botInfo: BotUserInfo(flags: [], inlinePlaceholder: nil), restrictionInfo: nil, flags: [.isVerified], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
} else {
|
||||
return peer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ public final class TelegramChannel: Peer, Equatable {
|
|||
public let storiesHidden: Bool?
|
||||
public let nameColor: PeerNameColor?
|
||||
public let backgroundEmojiId: Int64?
|
||||
public let profileColor: PeerNameColor?
|
||||
public let profileBackgroundEmojiId: Int64?
|
||||
|
||||
public var indexName: PeerIndexNameRepresentation {
|
||||
var addressNames = self.usernames.map { $0.username }
|
||||
|
|
@ -209,7 +211,9 @@ public final class TelegramChannel: Peer, Equatable {
|
|||
usernames: [TelegramPeerUsername],
|
||||
storiesHidden: Bool?,
|
||||
nameColor: PeerNameColor?,
|
||||
backgroundEmojiId: Int64?
|
||||
backgroundEmojiId: Int64?,
|
||||
profileColor: PeerNameColor?,
|
||||
profileBackgroundEmojiId: Int64?
|
||||
) {
|
||||
self.id = id
|
||||
self.accessHash = accessHash
|
||||
|
|
@ -229,6 +233,8 @@ public final class TelegramChannel: Peer, Equatable {
|
|||
self.storiesHidden = storiesHidden
|
||||
self.nameColor = nameColor
|
||||
self.backgroundEmojiId = backgroundEmojiId
|
||||
self.profileColor = profileColor
|
||||
self.profileBackgroundEmojiId = profileBackgroundEmojiId
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -260,6 +266,8 @@ public final class TelegramChannel: Peer, Equatable {
|
|||
self.storiesHidden = decoder.decodeOptionalBoolForKey("sth")
|
||||
self.nameColor = decoder.decodeOptionalInt32ForKey("nclr").flatMap { PeerNameColor(rawValue: $0) }
|
||||
self.backgroundEmojiId = decoder.decodeOptionalInt64ForKey("bgem")
|
||||
self.profileColor = decoder.decodeOptionalInt32ForKey("pclr").flatMap { PeerNameColor(rawValue: $0) }
|
||||
self.profileBackgroundEmojiId = decoder.decodeOptionalInt64ForKey("pgem")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -327,6 +335,18 @@ public final class TelegramChannel: Peer, Equatable {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "bgem")
|
||||
}
|
||||
|
||||
if let profileColor = self.profileColor {
|
||||
encoder.encodeInt32(profileColor.rawValue, forKey: "pclr")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "pclr")
|
||||
}
|
||||
|
||||
if let profileBackgroundEmojiId = self.profileBackgroundEmojiId {
|
||||
encoder.encodeInt64(profileBackgroundEmojiId, forKey: "pgem")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "pgem")
|
||||
}
|
||||
}
|
||||
|
||||
public func isEqual(_ other: Peer) -> Bool {
|
||||
|
|
@ -373,35 +393,49 @@ public final class TelegramChannel: Peer, Equatable {
|
|||
if lhs.backgroundEmojiId != rhs.backgroundEmojiId {
|
||||
return false
|
||||
}
|
||||
if lhs.profileColor != rhs.profileColor {
|
||||
return false
|
||||
}
|
||||
if lhs.profileBackgroundEmojiId != rhs.profileBackgroundEmojiId {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
public func withUpdatedAddressName(_ addressName: String?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: addressName, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: addressName, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedAddressNames(_ addressNames: [TelegramPeerUsername]) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: addressNames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: addressNames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedDefaultBannedRights(_ defaultBannedRights: TelegramChatBannedRights?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedFlags(_ flags: TelegramChannelFlags) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedStoriesHidden(_ storiesHidden: Bool?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedNameColor(_ nameColor: PeerNameColor?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedBackgroundEmojiId(_ backgroundEmojiId: Int64?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: backgroundEmojiId)
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedProfileColor(_ profileColor: PeerNameColor?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedProfileBackgroundEmojiId(_ profileBackgroundEmojiId: Int64?) -> TelegramChannel {
|
||||
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ public final class TelegramUser: Peer, Equatable {
|
|||
public let storiesHidden: Bool?
|
||||
public let nameColor: PeerNameColor?
|
||||
public let backgroundEmojiId: Int64?
|
||||
public let profileColor: PeerNameColor?
|
||||
public let profileBackgroundEmojiId: Int64?
|
||||
|
||||
public var nameOrPhone: String {
|
||||
if let firstName = self.firstName {
|
||||
|
|
@ -198,7 +200,9 @@ public final class TelegramUser: Peer, Equatable {
|
|||
usernames: [TelegramPeerUsername],
|
||||
storiesHidden: Bool?,
|
||||
nameColor: PeerNameColor?,
|
||||
backgroundEmojiId: Int64?
|
||||
backgroundEmojiId: Int64?,
|
||||
profileColor: PeerNameColor?,
|
||||
profileBackgroundEmojiId: Int64?
|
||||
) {
|
||||
self.id = id
|
||||
self.accessHash = accessHash
|
||||
|
|
@ -215,6 +219,8 @@ public final class TelegramUser: Peer, Equatable {
|
|||
self.storiesHidden = storiesHidden
|
||||
self.nameColor = nameColor
|
||||
self.backgroundEmojiId = backgroundEmojiId
|
||||
self.profileColor = profileColor
|
||||
self.profileBackgroundEmojiId = profileBackgroundEmojiId
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -257,6 +263,8 @@ public final class TelegramUser: Peer, Equatable {
|
|||
|
||||
self.nameColor = decoder.decodeOptionalInt32ForKey("nclr").flatMap { PeerNameColor(rawValue: $0) }
|
||||
self.backgroundEmojiId = decoder.decodeOptionalInt64ForKey("bgem")
|
||||
self.profileColor = decoder.decodeOptionalInt32ForKey("pclr").flatMap { PeerNameColor(rawValue: $0) }
|
||||
self.profileBackgroundEmojiId = decoder.decodeOptionalInt64ForKey("pgem")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -328,6 +336,18 @@ public final class TelegramUser: Peer, Equatable {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "bgem")
|
||||
}
|
||||
|
||||
if let profileColor = self.profileColor {
|
||||
encoder.encodeInt32(profileColor.rawValue, forKey: "pclr")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "pclr")
|
||||
}
|
||||
|
||||
if let profileBackgroundEmojiId = self.profileBackgroundEmojiId {
|
||||
encoder.encodeInt64(profileBackgroundEmojiId, forKey: "pgem")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "pgem")
|
||||
}
|
||||
}
|
||||
|
||||
public func isEqual(_ other: Peer) -> Bool {
|
||||
|
|
@ -389,47 +409,61 @@ public final class TelegramUser: Peer, Equatable {
|
|||
if lhs.backgroundEmojiId != rhs.backgroundEmojiId {
|
||||
return false
|
||||
}
|
||||
if lhs.profileColor != rhs.profileColor {
|
||||
return false
|
||||
}
|
||||
if lhs.profileBackgroundEmojiId != rhs.profileBackgroundEmojiId {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
public func withUpdatedUsername(_ username: String?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedUsernames(_ usernames: [TelegramPeerUsername]) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedNames(firstName: String?, lastName: String?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: firstName, lastName: lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: firstName, lastName: lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedPhone(_ phone: String?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedPhoto(_ representations: [TelegramMediaImageRepresentation]) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: phone, photo: representations, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: phone, photo: representations, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedEmojiStatus(_ emojiStatus: PeerEmojiStatus?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedFlags(_ flags: UserInfoFlags) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedStoriesHidden(_ storiesHidden: Bool?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedNameColor(_ nameColor: PeerNameColor) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: nameColor, backgroundEmojiId: self.backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedBackgroundEmojiId(_ backgroundEmojiId: Int64?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: backgroundEmojiId)
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedProfileColor(_ profileColor: PeerNameColor?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func withUpdatedProfileBackgroundEmojiId(_ profileBackgroundEmojiId: Int64?) -> TelegramUser {
|
||||
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ public extension TelegramEngine {
|
|||
return _internal_updateAbout(account: self.account, about: about)
|
||||
}
|
||||
|
||||
public func updateNameColorAndEmoji(nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdateNameColorAndEmojiError> {
|
||||
return _internal_updateNameColorAndEmoji(account: self.account, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId)
|
||||
public func updateNameColorAndEmoji(nameColor: PeerNameColor, backgroundEmojiId: Int64?, profileColor: PeerNameColor?, profileBackgroundEmojiId: Int64?) -> Signal<Void, UpdateNameColorAndEmojiError> {
|
||||
return _internal_updateNameColorAndEmoji(account: self.account, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func unregisterNotificationToken(token: Data, type: NotificationTokenType, otherAccountUserIds: [PeerId.Id]) -> Signal<Never, NoError> {
|
||||
|
|
|
|||
|
|
@ -51,13 +51,13 @@ public enum UpdateNameColorAndEmojiError {
|
|||
case generic
|
||||
}
|
||||
|
||||
func _internal_updateNameColorAndEmoji(account: Account, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdateNameColorAndEmojiError> {
|
||||
func _internal_updateNameColorAndEmoji(account: Account, nameColor: PeerNameColor, backgroundEmojiId: Int64?, profileColor: PeerNameColor?, profileBackgroundEmojiId: Int64?) -> Signal<Void, UpdateNameColorAndEmojiError> {
|
||||
let flags: Int32 = (1 << 0)
|
||||
return account.postbox.transaction { transaction -> Signal<Peer, NoError> in
|
||||
guard let peer = transaction.getPeer(account.peerId) as? TelegramUser else {
|
||||
return .complete()
|
||||
}
|
||||
updatePeersCustom(transaction: transaction, peers: [peer.withUpdatedNameColor(nameColor).withUpdatedBackgroundEmojiId(backgroundEmojiId)], update: { _, updated in
|
||||
updatePeersCustom(transaction: transaction, peers: [peer.withUpdatedNameColor(nameColor).withUpdatedBackgroundEmojiId(backgroundEmojiId).withUpdatedProfileColor(profileColor).withUpdatedProfileBackgroundEmojiId(profileBackgroundEmojiId)], update: { _, updated in
|
||||
return updated
|
||||
})
|
||||
return .single(peer)
|
||||
|
|
|
|||
|
|
@ -313,7 +313,9 @@ private class AdMessagesHistoryContextImpl {
|
|||
usernames: [],
|
||||
storiesHidden: nil,
|
||||
nameColor: invite.nameColor,
|
||||
backgroundEmojiId: nil
|
||||
backgroundEmojiId: nil,
|
||||
profileColor: nil,
|
||||
profileBackgroundEmojiId: nil
|
||||
)
|
||||
case let .webPage(webPage):
|
||||
author = TelegramChannel(
|
||||
|
|
@ -334,7 +336,9 @@ private class AdMessagesHistoryContextImpl {
|
|||
usernames: [],
|
||||
storiesHidden: nil,
|
||||
nameColor: .blue,
|
||||
backgroundEmojiId: nil
|
||||
backgroundEmojiId: nil,
|
||||
profileColor: nil,
|
||||
profileBackgroundEmojiId: nil
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -510,9 +510,17 @@ public extension EnginePeer {
|
|||
return self._asPeer().nameColor
|
||||
}
|
||||
|
||||
var profileColor: PeerNameColor? {
|
||||
return self._asPeer().profileColor
|
||||
}
|
||||
|
||||
var backgroundEmojiId: Int64? {
|
||||
return self._asPeer().backgroundEmojiId
|
||||
}
|
||||
|
||||
var profileBackgroundEmojiId: Int64? {
|
||||
return self._asPeer().profileBackgroundEmojiId
|
||||
}
|
||||
}
|
||||
|
||||
public extension EnginePeer {
|
||||
|
|
|
|||
|
|
@ -715,8 +715,8 @@ public extension TelegramEngine {
|
|||
return _internal_updateBotAbout(account: self.account, peerId: peerId, about: about)
|
||||
}
|
||||
|
||||
public func updatePeerNameColorAndEmoji(peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
|
||||
return _internal_updatePeerNameColorAndEmoji(account: self.account, peerId: peerId, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId)
|
||||
public func updatePeerNameColorAndEmoji(peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?, profileColor: PeerNameColor?, profileBackgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
|
||||
return _internal_updatePeerNameColorAndEmoji(account: self.account, peerId: peerId, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId)
|
||||
}
|
||||
|
||||
public func getChatListPeers(filterPredicate: ChatListFilterPredicate) -> Signal<[EnginePeer], NoError> {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public enum UpdatePeerNameColorAndEmojiError {
|
|||
case channelBoostRequired
|
||||
}
|
||||
|
||||
func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
|
||||
func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?, profileColor: PeerNameColor?, profileBackgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, UpdatePeerNameColorAndEmojiError> in
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
if let peer = peer as? TelegramChannel, let inputChannel = apiInputChannel(peer) {
|
||||
|
|
|
|||
|
|
@ -236,6 +236,17 @@ public extension Peer {
|
|||
}
|
||||
}
|
||||
|
||||
var profileColor: PeerNameColor? {
|
||||
switch self {
|
||||
case let user as TelegramUser:
|
||||
return user.profileColor
|
||||
case let channel as TelegramChannel:
|
||||
return channel.profileColor
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var hasCustomNameColor: Bool {
|
||||
let defaultNameColor = PeerNameColor(rawValue: Int32(self.id.id._internalGetInt64Value() % 7))
|
||||
if self.nameColor != defaultNameColor {
|
||||
|
|
@ -254,6 +265,17 @@ public extension Peer {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var profileBackgroundEmojiId: Int64? {
|
||||
switch self {
|
||||
case let user as TelegramUser:
|
||||
return user.profileBackgroundEmojiId
|
||||
case let channel as TelegramChannel:
|
||||
return channel.profileBackgroundEmojiId
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension TelegramPeerUsername {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public struct PresentationResourcesRootController {
|
|||
|
||||
public static func navigationQrCodeIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.navigationQrCodeIcon.rawValue, { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Settings/QrIcon"), color: theme.rootController.navigationBar.accentTextColor)
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Settings/QrIcon"), color: .white)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1355,7 +1355,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
ignoreForward = true
|
||||
effectiveAuthor = forwardInfo.author
|
||||
if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature {
|
||||
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
}
|
||||
}
|
||||
displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil
|
||||
|
|
@ -1371,7 +1371,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
displayAuthorInfo = !mergedTop.merged && incoming
|
||||
} else if let forwardInfo = item.content.firstMessage.forwardInfo, forwardInfo.flags.contains(.isImported), let authorSignature = forwardInfo.authorSignature {
|
||||
ignoreForward = true
|
||||
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
displayAuthorInfo = !mergedTop.merged && incoming
|
||||
} else if let adAttribute = item.content.firstMessage.adAttribute, let author = item.content.firstMessage.author {
|
||||
ignoreForward = true
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible
|
|||
if let forwardInfo = content.firstMessage.forwardInfo {
|
||||
effectiveAuthor = forwardInfo.author
|
||||
if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature {
|
||||
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
}
|
||||
}
|
||||
displayAuthorInfo = incoming && effectiveAuthor != nil
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ private func filterOriginalMessageFlags(_ message: Message) -> Message {
|
|||
|
||||
private func filterMessageChannelPeer(_ peer: Peer) -> Peer {
|
||||
if let peer = peer as? TelegramChannel {
|
||||
return TelegramChannel(id: peer.id, accessHash: peer.accessHash, title: peer.title, username: peer.username, photo: peer.photo, creationDate: peer.creationDate, version: peer.version, participationStatus: peer.participationStatus, info: .group(TelegramChannelGroupInfo(flags: [])), flags: peer.flags, restrictionInfo: peer.restrictionInfo, adminRights: peer.adminRights, bannedRights: peer.bannedRights, defaultBannedRights: peer.defaultBannedRights, usernames: peer.usernames, storiesHidden: peer.storiesHidden, nameColor: peer.nameColor, backgroundEmojiId: peer.backgroundEmojiId)
|
||||
return TelegramChannel(id: peer.id, accessHash: peer.accessHash, title: peer.title, username: peer.username, photo: peer.photo, creationDate: peer.creationDate, version: peer.version, participationStatus: peer.participationStatus, info: .group(TelegramChannelGroupInfo(flags: [])), flags: peer.flags, restrictionInfo: peer.restrictionInfo, adminRights: peer.adminRights, bannedRights: peer.bannedRights, defaultBannedRights: peer.defaultBannedRights, usernames: peer.usernames, storiesHidden: peer.storiesHidden, nameColor: peer.nameColor, backgroundEmojiId: peer.backgroundEmojiId, profileColor: peer.profileColor, profileBackgroundEmojiId: peer.profileBackgroundEmojiId)
|
||||
}
|
||||
return peer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ public final class DustEffectLayer: MetalEngineSubjectLayer, MetalEngineSubject
|
|||
private func updateNeedsAnimation() {
|
||||
if !self.items.isEmpty && self.isInHierarchy {
|
||||
if self.updateLink == nil {
|
||||
self.updateLink = SharedDisplayLinkDriver.shared.add(framesPerSecond: .fps(60), { [weak self] deltaTime in
|
||||
self.updateLink = SharedDisplayLinkDriver.shared.add(framesPerSecond: .max, { [weak self] deltaTime in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2694,6 +2694,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
public let emptySearchResults: EmptySearchResults?
|
||||
public let enableLongPress: Bool
|
||||
public let selectedItems: Set<MediaId>
|
||||
public let customTintColor: UIColor?
|
||||
|
||||
public init(
|
||||
id: AnyHashable,
|
||||
|
|
@ -2716,7 +2717,8 @@ public final class EmojiPagerContentComponent: Component {
|
|||
searchIsPlaceholderOnly: Bool,
|
||||
emptySearchResults: EmptySearchResults?,
|
||||
enableLongPress: Bool,
|
||||
selectedItems: Set<MediaId>
|
||||
selectedItems: Set<MediaId>,
|
||||
customTintColor: UIColor?
|
||||
) {
|
||||
self.id = id
|
||||
self.context = context
|
||||
|
|
@ -2739,6 +2741,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
self.emptySearchResults = emptySearchResults
|
||||
self.enableLongPress = enableLongPress
|
||||
self.selectedItems = selectedItems
|
||||
self.customTintColor = customTintColor
|
||||
}
|
||||
|
||||
public func withUpdatedItemGroups(panelItemGroups: [ItemGroup], contentItemGroups: [ItemGroup], itemContentUniqueId: ContentId?, emptySearchResults: EmptySearchResults?, searchState: SearchState) -> EmojiPagerContentComponent {
|
||||
|
|
@ -2763,7 +2766,8 @@ public final class EmojiPagerContentComponent: Component {
|
|||
searchIsPlaceholderOnly: self.searchIsPlaceholderOnly,
|
||||
emptySearchResults: emptySearchResults,
|
||||
enableLongPress: self.enableLongPress,
|
||||
selectedItems: self.selectedItems
|
||||
selectedItems: self.selectedItems,
|
||||
customTintColor: self.customTintColor
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2789,7 +2793,35 @@ public final class EmojiPagerContentComponent: Component {
|
|||
searchIsPlaceholderOnly: self.searchIsPlaceholderOnly,
|
||||
emptySearchResults: emptySearchResults,
|
||||
enableLongPress: self.enableLongPress,
|
||||
selectedItems: selectedItems
|
||||
selectedItems: selectedItems,
|
||||
customTintColor: self.customTintColor
|
||||
)
|
||||
}
|
||||
|
||||
public func withCustomTintColor(_ customTintColor: UIColor?) -> EmojiPagerContentComponent {
|
||||
return EmojiPagerContentComponent(
|
||||
id: self.id,
|
||||
context: self.context,
|
||||
avatarPeer: self.avatarPeer,
|
||||
animationCache: self.animationCache,
|
||||
animationRenderer: self.animationRenderer,
|
||||
inputInteractionHolder: self.inputInteractionHolder,
|
||||
panelItemGroups: panelItemGroups,
|
||||
contentItemGroups: contentItemGroups,
|
||||
itemLayoutType: self.itemLayoutType,
|
||||
itemContentUniqueId: itemContentUniqueId,
|
||||
searchState: searchState,
|
||||
warpContentsOnEdges: self.warpContentsOnEdges,
|
||||
hideBackground: self.hideBackground,
|
||||
displaySearchWithPlaceholder: self.displaySearchWithPlaceholder,
|
||||
searchCategories: self.searchCategories,
|
||||
searchInitiallyHidden: self.searchInitiallyHidden,
|
||||
searchAlwaysActive: self.searchAlwaysActive,
|
||||
searchIsPlaceholderOnly: self.searchIsPlaceholderOnly,
|
||||
emptySearchResults: emptySearchResults,
|
||||
enableLongPress: self.enableLongPress,
|
||||
selectedItems: self.selectedItems,
|
||||
customTintColor: customTintColor
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2860,6 +2892,9 @@ public final class EmojiPagerContentComponent: Component {
|
|||
if lhs.selectedItems != rhs.selectedItems {
|
||||
return false
|
||||
}
|
||||
if lhs.customTintColor != rhs.customTintColor {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -5882,7 +5917,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
case let .custom(color):
|
||||
itemLayer.layerTintColor = color.cgColor
|
||||
case .accent:
|
||||
itemLayer.layerTintColor = keyboardChildEnvironment.theme.list.itemAccentColor.cgColor
|
||||
itemLayer.layerTintColor = component.customTintColor?.cgColor ?? keyboardChildEnvironment.theme.list.itemAccentColor.cgColor
|
||||
case .primary:
|
||||
itemLayer.layerTintColor = keyboardChildEnvironment.theme.list.itemPrimaryTextColor.cgColor
|
||||
case .none:
|
||||
|
|
@ -5928,7 +5963,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
itemSelectionLayer.backgroundColor = color.withMultipliedAlpha(0.1).cgColor
|
||||
itemSelectionLayer.tintContainerLayer.backgroundColor = UIColor.clear.cgColor
|
||||
} else if case .accent = item.tintMode {
|
||||
itemSelectionLayer.backgroundColor = keyboardChildEnvironment.theme.list.itemAccentColor.withMultipliedAlpha(0.1).cgColor
|
||||
itemSelectionLayer.backgroundColor = component.customTintColor?.withMultipliedAlpha(0.1).cgColor ?? keyboardChildEnvironment.theme.list.itemAccentColor.withMultipliedAlpha(0.1).cgColor
|
||||
itemSelectionLayer.tintContainerLayer.backgroundColor = UIColor.clear.cgColor
|
||||
} else {
|
||||
if useOpaqueTheme {
|
||||
|
|
@ -7940,7 +7975,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
itemFile: nil,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
tintMode: backgroundIconColor.flatMap { .custom($0) } ?? .accent
|
||||
tintMode: .accent
|
||||
)
|
||||
|
||||
let groupId = "recent"
|
||||
|
|
@ -8329,7 +8364,8 @@ public final class EmojiPagerContentComponent: Component {
|
|||
searchIsPlaceholderOnly: false,
|
||||
emptySearchResults: nil,
|
||||
enableLongPress: enableLongPress,
|
||||
selectedItems: selectedItems
|
||||
selectedItems: selectedItems,
|
||||
customTintColor: backgroundIconColor
|
||||
)
|
||||
}
|
||||
return emojiItems
|
||||
|
|
@ -8810,7 +8846,8 @@ public final class EmojiPagerContentComponent: Component {
|
|||
searchIsPlaceholderOnly: searchIsPlaceholderOnly,
|
||||
emptySearchResults: nil,
|
||||
enableLongPress: false,
|
||||
selectedItems: Set()
|
||||
selectedItems: Set(),
|
||||
customTintColor: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -468,7 +468,8 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
|||
searchIsPlaceholderOnly: false,
|
||||
emptySearchResults: nil,
|
||||
enableLongPress: false,
|
||||
selectedItems: Set()
|
||||
selectedItems: Set(),
|
||||
customTintColor: nil
|
||||
)
|
||||
|
||||
if let emojiSearchResult = self.immediateEmojiSearchState.result {
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ public final class EntityKeyboardComponent: Component {
|
|||
animationRenderer: maskContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: itemGroup.title ?? "",
|
||||
customTintColor: component.customTintColor,
|
||||
pressed: { [weak self] in
|
||||
self?.scrollToItemGroup(contentId: "masks", groupId: itemGroup.supergroupId, subgroupId: nil)
|
||||
}
|
||||
|
|
@ -509,6 +510,7 @@ public final class EntityKeyboardComponent: Component {
|
|||
animationRenderer: stickerContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: itemGroup.title ?? "",
|
||||
customTintColor: component.customTintColor,
|
||||
pressed: { [weak self] in
|
||||
self?.scrollToItemGroup(contentId: "stickers", groupId: itemGroup.supergroupId, subgroupId: nil)
|
||||
}
|
||||
|
|
@ -625,7 +627,7 @@ public final class EntityKeyboardComponent: Component {
|
|||
animationRenderer: emojiContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: itemGroup.title ?? "",
|
||||
customTintColor: itemGroup.customTintColor,
|
||||
customTintColor: component.customTintColor ?? itemGroup.customTintColor,
|
||||
pressed: { [weak self] in
|
||||
self?.scrollToItemGroup(contentId: "emoji", groupId: itemGroup.supergroupId, subgroupId: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,9 +169,9 @@ final class EntityKeyboardAnimationTopPanelComponent: Component {
|
|||
case .none:
|
||||
break
|
||||
case .primary:
|
||||
itemLayer.layerTintColor = component.theme.list.itemPrimaryTextColor.cgColor
|
||||
itemLayer.layerTintColor = component.customTintColor?.cgColor ?? component.theme.list.itemPrimaryTextColor.cgColor
|
||||
case .accent:
|
||||
itemLayer.layerTintColor = component.theme.list.itemAccentColor.cgColor
|
||||
itemLayer.layerTintColor = component.customTintColor?.cgColor ?? component.theme.list.itemAccentColor.cgColor
|
||||
case let .custom(color):
|
||||
itemLayer.layerTintColor = component.customTintColor?.cgColor ?? color.cgColor
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@ public final class MultiScaleTextNode: ASDisplayNode {
|
|||
return self.stateNodes[key]?.textNode
|
||||
}
|
||||
|
||||
public func updateTintColor(color: UIColor, transition: ContainedViewLayoutTransition) {
|
||||
for (_, node) in self.stateNodes {
|
||||
transition.updateTintColor(layer: node.textNode.layer, color: color)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateLayout(text: String, states: [AnyHashable: MultiScaleTextState], mainState: AnyHashable) -> [AnyHashable: MultiScaleTextLayout] {
|
||||
assert(Set(states.keys) == Set(self.stateNodes.keys))
|
||||
assert(states[mainState] != nil)
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ private func notificationsPeerCategoryEntries(peerId: EnginePeer.Id, notificatio
|
|||
}
|
||||
}
|
||||
existingThreadIds.insert(value.threadId)
|
||||
entries.append(.exception(Int32(index), presentationData.dateTimeFormat, presentationData.nameDisplayOrder, .channel(TelegramChannel(id: peerId, accessHash: nil, title: "", username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(TelegramChannelGroupInfo(flags: [])), flags: [.isForum], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)), value.threadId, value.info, title, value.notificationSettings._asNotificationSettings(), state.editing, state.revealedThreadId == value.threadId))
|
||||
entries.append(.exception(Int32(index), presentationData.dateTimeFormat, presentationData.nameDisplayOrder, .channel(TelegramChannel(id: peerId, accessHash: nil, title: "", username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(TelegramChannelGroupInfo(flags: [])), flags: [.isForum], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)), value.threadId, value.info, title, value.notificationSettings._asNotificationSettings(), state.editing, state.revealedThreadId == value.threadId))
|
||||
index += 1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ private func patternScaleValueAt(fraction: CGFloat, t: CGFloat, reverse: Bool) -
|
|||
public final class PeerInfoCoverComponent: Component {
|
||||
public let context: AccountContext
|
||||
public let peer: EnginePeer?
|
||||
public let isDark: Bool
|
||||
public let avatarCenter: CGPoint
|
||||
public let avatarScale: CGFloat
|
||||
public let avatarTransitionFraction: CGFloat
|
||||
|
|
@ -68,6 +69,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
public init(
|
||||
context: AccountContext,
|
||||
peer: EnginePeer?,
|
||||
isDark: Bool,
|
||||
avatarCenter: CGPoint,
|
||||
avatarScale: CGFloat,
|
||||
avatarTransitionFraction: CGFloat,
|
||||
|
|
@ -75,6 +77,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
) {
|
||||
self.context = context
|
||||
self.peer = peer
|
||||
self.isDark = isDark
|
||||
self.avatarCenter = avatarCenter
|
||||
self.avatarScale = avatarScale
|
||||
self.avatarTransitionFraction = avatarTransitionFraction
|
||||
|
|
@ -88,6 +91,9 @@ public final class PeerInfoCoverComponent: Component {
|
|||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
if lhs.isDark != rhs.isDark {
|
||||
return false
|
||||
}
|
||||
if lhs.avatarCenter != rhs.avatarCenter {
|
||||
return false
|
||||
}
|
||||
|
|
@ -105,6 +111,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
|
||||
public final class View: UIView {
|
||||
private let backgroundView: UIView
|
||||
private let backgroundGradientLayer: SimpleGradientLayer
|
||||
private let avatarBackgroundPatternContainer: UIView
|
||||
private let avatarBackgroundGradientLayer: SimpleGradientLayer
|
||||
private let avatarBackgroundPatternView: UIView
|
||||
|
|
@ -122,6 +129,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
|
||||
override public init(frame: CGRect) {
|
||||
self.backgroundView = UIView()
|
||||
self.backgroundGradientLayer = SimpleGradientLayer()
|
||||
self.avatarBackgroundPatternContainer = UIView()
|
||||
self.avatarBackgroundGradientLayer = SimpleGradientLayer()
|
||||
self.avatarBackgroundPatternView = UIView()
|
||||
|
|
@ -130,6 +138,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.backgroundView)
|
||||
self.layer.addSublayer(self.backgroundGradientLayer)
|
||||
self.addSubview(self.avatarBackgroundPatternContainer)
|
||||
self.avatarBackgroundPatternContainer.layer.addSublayer(self.avatarBackgroundGradientLayer)
|
||||
self.avatarBackgroundPatternContainer.addSubview(self.avatarBackgroundPatternView)
|
||||
|
|
@ -186,8 +195,8 @@ public final class PeerInfoCoverComponent: Component {
|
|||
}
|
||||
|
||||
func update(component: PeerInfoCoverComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
if self.component?.peer?.backgroundEmojiId != component.peer?.backgroundEmojiId {
|
||||
if let backgroundEmojiId = component.peer?.backgroundEmojiId, backgroundEmojiId != 0 {
|
||||
if self.component?.peer?.profileBackgroundEmojiId != component.peer?.profileBackgroundEmojiId {
|
||||
if let profileBackgroundEmojiId = component.peer?.profileBackgroundEmojiId, profileBackgroundEmojiId != 0 {
|
||||
if self.patternContentsTarget == nil {
|
||||
self.patternContentsTarget = PatternContentsTarget(imageUpdated: { [weak self] in
|
||||
guard let self else {
|
||||
|
|
@ -202,7 +211,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
self.patternFileDisposable = nil
|
||||
self.patternImageDisposable?.dispose()
|
||||
|
||||
let fileId = backgroundEmojiId
|
||||
let fileId = profileBackgroundEmojiId
|
||||
self.patternFileDisposable = (component.context.engine.stickers.resolveInlineStickers(fileIds: [fileId])
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] files in
|
||||
guard let self else {
|
||||
|
|
@ -218,6 +227,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||
self.patternFileDisposable?.dispose()
|
||||
self.patternFileDisposable = nil
|
||||
self.patternFile = nil
|
||||
self.updatePatternLayerImages()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,25 +235,45 @@ public final class PeerInfoCoverComponent: Component {
|
|||
self.state = state
|
||||
|
||||
let backgroundColor: UIColor
|
||||
var secondaryBackgroundColor: UIColor
|
||||
let patternColor: UIColor
|
||||
if let peer = component.peer, let colors = peer._asPeer().nameColor.flatMap({ component.context.peerNameColors.get($0) }) {
|
||||
backgroundColor = colors.main.withMultiplied(hue: 1.0, saturation: 0.9, brightness: 0.9)
|
||||
if let peer = component.peer, let colors = peer._asPeer().profileColor.flatMap({ component.context.peerNameColors.getProfile($0, dark: component.isDark) }) {
|
||||
backgroundColor = colors.main
|
||||
secondaryBackgroundColor = colors.secondary ?? colors.main
|
||||
patternColor = colors.main.withMultiplied(hue: 1.0, saturation: 1.0, brightness: 0.8).withMultipliedAlpha(0.8)
|
||||
} else {
|
||||
backgroundColor = .clear
|
||||
secondaryBackgroundColor = .clear
|
||||
patternColor = .clear
|
||||
}
|
||||
|
||||
self.backgroundView.backgroundColor = backgroundColor
|
||||
self.backgroundView.backgroundColor = secondaryBackgroundColor
|
||||
|
||||
self.backgroundGradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
|
||||
self.backgroundGradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
|
||||
self.backgroundGradientLayer.type = .axial
|
||||
self.backgroundGradientLayer.colors = [backgroundColor.cgColor, secondaryBackgroundColor.cgColor]
|
||||
//self.backgroundGradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor]
|
||||
self.backgroundGradientLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
|
||||
|
||||
let backgroundGradientFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - 350.0), size: CGSize(width: availableSize.width, height: 350.0))
|
||||
if !transition.animation.isImmediate {
|
||||
let previousPosition = self.backgroundGradientLayer.position
|
||||
let updatedPosition = CGPoint(x: backgroundGradientFrame.minX, y: backgroundGradientFrame.maxY)
|
||||
self.backgroundGradientLayer.bounds = CGRect(origin: CGPoint(), size: backgroundGradientFrame.size)
|
||||
self.backgroundGradientLayer.position = updatedPosition
|
||||
transition.containedViewLayoutTransition.animatePositionAdditive(layer: self.backgroundGradientLayer, offset: CGPoint(x: previousPosition.x - updatedPosition.x, y: previousPosition.y - updatedPosition.y))
|
||||
} else {
|
||||
self.backgroundGradientLayer.frame = backgroundGradientFrame
|
||||
}
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -1000.0 + availableSize.height), size: CGSize(width: availableSize.width, height: 1000.0))
|
||||
transition.containedViewLayoutTransition.updateFrameAdditive(view: self.backgroundView, frame: backgroundFrame)
|
||||
|
||||
let avatarBackgroundPatternContainerFrame = CGSize(width: 0.0, height: 0.0).centered(around: component.avatarCenter)
|
||||
transition.containedViewLayoutTransition.updateFrameAdditive(view: self.avatarBackgroundPatternContainer, frame: avatarBackgroundPatternContainerFrame)
|
||||
transition.containedViewLayoutTransition.updateSublayerTransformScaleAdditive(layer: self.avatarBackgroundPatternContainer.layer, scale: component.avatarScale)
|
||||
//transition.containedViewLayoutTransition.updateAlpha(layer: self.avatarBackgroundPatternContainer.layer, alpha: 1.0 - component.avatarTransitionFraction)
|
||||
|
||||
//self.avatarBackgroundPatternView.backgroundColor = .yellow
|
||||
transition.setFrame(view: self.avatarBackgroundPatternView, frame: CGSize(width: 200.0, height: 200.0).centered(around: CGPoint()))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode",
|
||||
"//submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent",
|
||||
"//submodules/TelegramUI/Components/LottieComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -84,12 +84,22 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
|||
self.playbackStartDisposable.dispose()
|
||||
}
|
||||
|
||||
func updateStoryView(transition: ContainedViewLayoutTransition, theme: PresentationTheme) {
|
||||
func updateStoryView(transition: ContainedViewLayoutTransition, theme: PresentationTheme, peer: Peer?) {
|
||||
var colors = AvatarNode.Colors(theme: theme)
|
||||
|
||||
let regularNavigationContentsSecondaryColor: UIColor
|
||||
if let profileColor = peer?.profileColor {
|
||||
let backgroundColor = self.context.peerNameColors.getProfile(profileColor).main
|
||||
regularNavigationContentsSecondaryColor = UIColor(white: 1.0, alpha: 0.6).blitOver(backgroundColor.withMultiplied(hue: 1.0, saturation: 2.2, brightness: 1.5), alpha: 1.0)
|
||||
} else {
|
||||
regularNavigationContentsSecondaryColor = theme.list.controlSecondaryColor
|
||||
}
|
||||
|
||||
colors.seenColors = [
|
||||
theme.list.controlSecondaryColor,
|
||||
theme.list.controlSecondaryColor
|
||||
regularNavigationContentsSecondaryColor,
|
||||
regularNavigationContentsSecondaryColor
|
||||
]
|
||||
|
||||
var storyStats: AvatarNode.StoryStats?
|
||||
if let storyData = self.storyData {
|
||||
storyStats = AvatarNode.StoryStats(
|
||||
|
|
@ -410,6 +420,6 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
self.updateStoryView(transition: .immediate, theme: theme)
|
||||
self.updateStoryView(transition: .immediate, theme: theme, peer: peer)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -819,8 +819,15 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
availablePanes = nil
|
||||
}
|
||||
|
||||
var peer: Peer?
|
||||
peer = peerView.peers[userPeerId]
|
||||
|
||||
if let user = peer as? TelegramUser, let profileColor = user.nameColor {
|
||||
peer = user.withUpdatedProfileColor(PeerNameColor(rawValue: profileColor.rawValue)).withUpdatedProfileBackgroundEmojiId(user.backgroundEmojiId)
|
||||
}
|
||||
|
||||
return PeerInfoScreenData(
|
||||
peer: peerView.peers[userPeerId],
|
||||
peer: peer,
|
||||
chatPeer: peerView.peers[peerId],
|
||||
cachedData: peerView.cachedData,
|
||||
status: status,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import ContextUI
|
|||
import AnimationUI
|
||||
import Display
|
||||
import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import LottieComponent
|
||||
|
||||
enum PeerInfoHeaderButtonKey: Hashable {
|
||||
case message
|
||||
|
|
@ -43,7 +45,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||
private let backgroundNode: NavigationBackgroundNode
|
||||
private let iconNode: ASImageNode
|
||||
private let textNode: ImmediateTextNode
|
||||
private var animationNode: AnimationNode?
|
||||
private var animatedIcon: ComponentView<Empty>?
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
private var icon: PeerInfoHeaderButtonIcon?
|
||||
|
|
@ -102,15 +104,17 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||
|
||||
@objc private func buttonPressed() {
|
||||
switch self.icon {
|
||||
case .voiceChat, .more, .leave:
|
||||
self.animationNode?.playOnce()
|
||||
default:
|
||||
break
|
||||
case .voiceChat, .more, .leave:
|
||||
if let animatedIconView = self.animatedIcon?.view as? LottieComponent.View {
|
||||
animatedIconView.playOnce()
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.action(self, nil)
|
||||
}
|
||||
|
||||
func update(size: CGSize, text: String, icon: PeerInfoHeaderButtonIcon, isActive: Bool, presentationData: PresentationData, transition: ContainedViewLayoutTransition) {
|
||||
func update(size: CGSize, text: String, icon: PeerInfoHeaderButtonIcon, isActive: Bool, presentationData: PresentationData, backgroundColor: UIColor, foregroundColor: UIColor, transition: ContainedViewLayoutTransition) {
|
||||
let previousIcon = self.icon
|
||||
let themeUpdated = self.theme != presentationData.theme
|
||||
let iconUpdated = self.icon != icon
|
||||
|
|
@ -128,78 +132,8 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||
isGestureEnabled = true
|
||||
}
|
||||
self.containerNode.isGestureEnabled = isGestureEnabled
|
||||
|
||||
let animationName: String?
|
||||
var colors: [String: UIColor] = [:]
|
||||
var playOnce = false
|
||||
var seekToEnd = false
|
||||
|
||||
let iconColor = UIColor.white
|
||||
switch icon {
|
||||
case .voiceChat:
|
||||
animationName = "anim_profilevc"
|
||||
colors = ["Line 3.Group 1.Stroke 1": iconColor,
|
||||
"Line 1.Group 1.Stroke 1": iconColor,
|
||||
"Line 2.Group 1.Stroke 1": iconColor]
|
||||
case .mute:
|
||||
animationName = "anim_profileunmute"
|
||||
colors = ["Middle.Group 1.Fill 1": iconColor,
|
||||
"Top.Group 1.Fill 1": iconColor,
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor]
|
||||
if previousIcon == .unmute {
|
||||
playOnce = true
|
||||
} else {
|
||||
seekToEnd = true
|
||||
}
|
||||
case .unmute:
|
||||
animationName = "anim_profilemute"
|
||||
colors = ["Middle.Group 1.Fill 1": iconColor,
|
||||
"Top.Group 1.Fill 1": iconColor,
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor]
|
||||
if previousIcon == .mute {
|
||||
playOnce = true
|
||||
} else {
|
||||
seekToEnd = true
|
||||
}
|
||||
case .more:
|
||||
animationName = "anim_profilemore"
|
||||
colors = ["Point 2.Group 1.Fill 1": iconColor,
|
||||
"Point 3.Group 1.Fill 1": iconColor,
|
||||
"Point 1.Group 1.Fill 1": iconColor]
|
||||
case .leave:
|
||||
animationName = "anim_profileleave"
|
||||
colors = ["Arrow.Group 2.Stroke 1": iconColor,
|
||||
"Door.Group 1.Stroke 1": iconColor,
|
||||
"Arrow.Group 1.Stroke 1": iconColor]
|
||||
default:
|
||||
animationName = nil
|
||||
}
|
||||
|
||||
if let animationName = animationName {
|
||||
let animationNode: AnimationNode
|
||||
if let current = self.animationNode {
|
||||
animationNode = current
|
||||
animationNode.setAnimation(name: animationName, colors: colors)
|
||||
} else {
|
||||
animationNode = AnimationNode(animation: animationName, colors: colors, scale: 1.0)
|
||||
self.referenceNode.addSubnode(animationNode)
|
||||
self.animationNode = animationNode
|
||||
}
|
||||
} else if let animationNode = self.animationNode {
|
||||
self.animationNode = nil
|
||||
animationNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
if playOnce {
|
||||
self.animationNode?.play()
|
||||
} else if seekToEnd {
|
||||
self.animationNode?.seekToEnd()
|
||||
}
|
||||
|
||||
//self.backgroundNode.backgroundColor = presentationData.theme.list.itemBlocksBackgroundColor
|
||||
self.iconNode.image = generateImage(iconSize, contextGenerator: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setBlendMode(.normal)
|
||||
|
|
@ -237,11 +171,75 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||
})
|
||||
}
|
||||
|
||||
let animationName: String?
|
||||
var playOnce = false
|
||||
var seekToEnd = false
|
||||
switch icon {
|
||||
case .voiceChat:
|
||||
animationName = "anim_profilevc"
|
||||
case .mute:
|
||||
animationName = "anim_profileunmute"
|
||||
if previousIcon == .unmute {
|
||||
playOnce = true
|
||||
} else {
|
||||
seekToEnd = true
|
||||
}
|
||||
case .unmute:
|
||||
animationName = "anim_profilemute"
|
||||
if previousIcon == .mute {
|
||||
playOnce = true
|
||||
} else {
|
||||
seekToEnd = true
|
||||
}
|
||||
case .more:
|
||||
animationName = "anim_profilemore"
|
||||
case .leave:
|
||||
animationName = "anim_profileleave"
|
||||
default:
|
||||
animationName = nil
|
||||
}
|
||||
|
||||
if let animationName = animationName {
|
||||
let animatedIcon: ComponentView<Empty>
|
||||
if let current = self.animatedIcon {
|
||||
animatedIcon = current
|
||||
} else {
|
||||
animatedIcon = ComponentView()
|
||||
self.animatedIcon = animatedIcon
|
||||
}
|
||||
let _ = animatedIcon.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(LottieComponent(
|
||||
content: LottieComponent.AppBundleContent(name: animationName),
|
||||
color: foregroundColor,
|
||||
startingPosition: seekToEnd ? .end : .begin
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: iconSize
|
||||
)
|
||||
} else if let animatedIcon = self.animatedIcon {
|
||||
self.animatedIcon = nil
|
||||
animatedIcon.view?.removeFromSuperview()
|
||||
}
|
||||
|
||||
if let animatedIconView = self.animatedIcon?.view as? LottieComponent.View {
|
||||
if animatedIconView.superview == nil {
|
||||
self.referenceNode.view.addSubview(animatedIconView)
|
||||
}
|
||||
if playOnce {
|
||||
animatedIconView.playOnce()
|
||||
}
|
||||
}
|
||||
|
||||
transition.updateTintColor(layer: self.iconNode.layer, color: foregroundColor)
|
||||
transition.updateTintColor(layer: self.titleNode.layer, color: foregroundColor)
|
||||
transition.updateTintColor(layer: self.textNode.layer, color: foregroundColor)
|
||||
|
||||
if isActiveUpdated {
|
||||
let alphaTransition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
|
||||
alphaTransition.updateAlpha(node: self.iconNode, alpha: isActive ? 1.0 : 0.3)
|
||||
if let animationNode = self.animationNode {
|
||||
alphaTransition.updateAlpha(node: animationNode, alpha: isActive ? 1.0 : 0.3)
|
||||
if let animatedIconView = self.animatedIcon?.view {
|
||||
alphaTransition.updateAlpha(layer: animatedIconView.layer, alpha: isActive ? 1.0 : 0.3)
|
||||
}
|
||||
alphaTransition.updateAlpha(node: self.textNode, alpha: isActive ? 1.0 : 0.3)
|
||||
}
|
||||
|
|
@ -253,9 +251,10 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.backgroundNode.update(size: size, cornerRadius: 11.0, transition: transition)
|
||||
self.backgroundNode.updateColor(color: backgroundColor, transition: transition)
|
||||
transition.updateFrame(node: self.iconNode, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: 1.0), size: iconSize))
|
||||
if let animationNode = self.animationNode {
|
||||
transition.updateFrame(node: animationNode, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: 1.0), size: iconSize))
|
||||
if let animatedIconView = self.animatedIcon?.view {
|
||||
transition.updateFrame(view: animatedIconView, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: 1.0), size: iconSize))
|
||||
}
|
||||
transition.updateFrameAdditiveToCenter(node: self.textNode, frame: CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: size.height - titleSize.height - 9.0), size: titleSize))
|
||||
|
||||
|
|
|
|||
|
|
@ -95,30 +95,14 @@ private final class MoreIconNode: ManagedAnimationNode {
|
|||
final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
||||
let containerNode: ContextControllerSourceNode
|
||||
let contextSourceNode: ContextReferenceContentNode
|
||||
private let regularTextNode: ImmediateTextNode
|
||||
private let whiteTextNode: ImmediateTextNode
|
||||
private let textNode: ImmediateTextNode
|
||||
private let iconNode: ASImageNode
|
||||
private var animationNode: MoreIconNode?
|
||||
private let backgroundNode: NavigationBackgroundNode
|
||||
|
||||
private var key: PeerInfoHeaderNavigationButtonKey?
|
||||
private var theme: PresentationTheme?
|
||||
|
||||
var isWhite: Bool = false {
|
||||
didSet {
|
||||
if self.isWhite != oldValue {
|
||||
if case .qrCode = self.key, let theme = self.theme {
|
||||
self.iconNode.image = self.isWhite ? generateTintedImage(image: PresentationResourcesRootController.navigationQrCodeIcon(theme), color: .white) : PresentationResourcesRootController.navigationQrCodeIcon(theme)
|
||||
} else if case .postStory = self.key, let theme = self.theme {
|
||||
self.iconNode.image = self.isWhite ? generateTintedImage(image: PresentationResourcesRootController.navigationPostStoryIcon(theme), color: .white) : PresentationResourcesRootController.navigationPostStoryIcon(theme)
|
||||
}
|
||||
|
||||
self.regularTextNode.isHidden = self.isWhite
|
||||
self.whiteTextNode.isHidden = !self.isWhite
|
||||
self.animationNode?.view.tintColor = self.isWhite ? .white : self.theme?.list.itemAccentColor
|
||||
self.animationNode?.imageNode.layer.layerTintColor = self.isWhite ? UIColor.white.cgColor : self.theme?.list.itemAccentColor.cgColor
|
||||
}
|
||||
}
|
||||
}
|
||||
private var contentsColor: UIColor = .white
|
||||
|
||||
var action: ((ASDisplayNode, ContextGesture?) -> Void)?
|
||||
|
||||
|
|
@ -127,22 +111,22 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||
self.containerNode = ContextControllerSourceNode()
|
||||
self.containerNode.animateScale = false
|
||||
|
||||
self.regularTextNode = ImmediateTextNode()
|
||||
self.whiteTextNode = ImmediateTextNode()
|
||||
self.whiteTextNode.isHidden = true
|
||||
self.textNode = ImmediateTextNode()
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode.displaysAsynchronously = false
|
||||
self.iconNode.displayWithoutProcessing = true
|
||||
|
||||
self.backgroundNode = NavigationBackgroundNode(color: .clear, enableBlur: true)
|
||||
|
||||
super.init(pointerStyle: .insetRectangle(-8.0, 2.0))
|
||||
|
||||
self.isAccessibilityElement = true
|
||||
self.accessibilityTraits = .button
|
||||
|
||||
self.containerNode.addSubnode(self.contextSourceNode)
|
||||
self.contextSourceNode.addSubnode(self.regularTextNode)
|
||||
self.contextSourceNode.addSubnode(self.whiteTextNode)
|
||||
self.contextSourceNode.addSubnode(self.backgroundNode)
|
||||
self.contextSourceNode.addSubnode(self.textNode)
|
||||
self.contextSourceNode.addSubnode(self.iconNode)
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
|
|
@ -162,12 +146,34 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||
self.action?(self.contextSourceNode, nil)
|
||||
}
|
||||
|
||||
func updateContentsColor(backgroundColor: UIColor, contentsColor: UIColor, transition: ContainedViewLayoutTransition) {
|
||||
self.contentsColor = contentsColor
|
||||
|
||||
self.backgroundNode.updateColor(color: backgroundColor, transition: transition)
|
||||
|
||||
transition.updateTintColor(layer: self.textNode.layer, color: self.contentsColor)
|
||||
transition.updateTintColor(layer: self.iconNode.layer, color: self.contentsColor)
|
||||
|
||||
if let animationNode = self.animationNode {
|
||||
transition.updateTintColor(layer: animationNode.imageNode.layer, color: self.contentsColor)
|
||||
}
|
||||
}
|
||||
|
||||
func update(key: PeerInfoHeaderNavigationButtonKey, presentationData: PresentationData, height: CGFloat) -> CGSize {
|
||||
let transition: ContainedViewLayoutTransition = .immediate
|
||||
|
||||
var iconOffset = CGPoint()
|
||||
switch key {
|
||||
case .back:
|
||||
iconOffset = CGPoint(x: -1.0, y: 0.0)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
let textSize: CGSize
|
||||
let isFirstTime = self.key == nil
|
||||
if self.key != key || self.theme !== presentationData.theme {
|
||||
if self.key != key {
|
||||
self.key = key
|
||||
self.theme = presentationData.theme
|
||||
|
||||
let text: String
|
||||
var accessibilityText: String
|
||||
|
|
@ -177,55 +183,64 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||
var isAnimation = false
|
||||
var animationState: MoreIconNodeState = .more
|
||||
switch key {
|
||||
case .edit:
|
||||
text = presentationData.strings.Common_Edit
|
||||
accessibilityText = text
|
||||
case .done, .cancel, .selectionDone:
|
||||
text = presentationData.strings.Common_Done
|
||||
accessibilityText = text
|
||||
isBold = true
|
||||
case .select:
|
||||
text = presentationData.strings.Common_Select
|
||||
accessibilityText = text
|
||||
case .search:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Common_Search
|
||||
icon = nil// PresentationResourcesRootController.navigationCompactSearchIcon(presentationData.theme)
|
||||
isAnimation = true
|
||||
animationState = .search
|
||||
case .editPhoto:
|
||||
text = presentationData.strings.Settings_EditPhoto
|
||||
accessibilityText = text
|
||||
case .editVideo:
|
||||
text = presentationData.strings.Settings_EditVideo
|
||||
accessibilityText = text
|
||||
case .more:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Common_More
|
||||
icon = nil// PresentationResourcesRootController.navigationMoreCircledIcon(presentationData.theme)
|
||||
isGestureEnabled = true
|
||||
isAnimation = true
|
||||
animationState = .more
|
||||
case .qrCode:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.PeerInfo_QRCode_Title
|
||||
icon = PresentationResourcesRootController.navigationQrCodeIcon(presentationData.theme)
|
||||
case .moreToSearch:
|
||||
text = ""
|
||||
accessibilityText = ""
|
||||
case .postStory:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Story_Privacy_PostStory
|
||||
icon = PresentationResourcesRootController.navigationPostStoryIcon(presentationData.theme)
|
||||
case .back:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Common_Back
|
||||
icon = NavigationBar.thinBackArrowImage
|
||||
case .edit:
|
||||
text = presentationData.strings.Common_Edit
|
||||
accessibilityText = text
|
||||
case .cancel:
|
||||
text = presentationData.strings.Common_Cancel
|
||||
accessibilityText = text
|
||||
isBold = false
|
||||
case .done, .selectionDone:
|
||||
text = presentationData.strings.Common_Done
|
||||
accessibilityText = text
|
||||
isBold = true
|
||||
case .select:
|
||||
text = presentationData.strings.Common_Select
|
||||
accessibilityText = text
|
||||
case .search:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Common_Search
|
||||
icon = nil// PresentationResourcesRootController.navigationCompactSearchIcon(presentationData.theme)
|
||||
isAnimation = true
|
||||
animationState = .search
|
||||
case .editPhoto:
|
||||
text = presentationData.strings.Settings_EditPhoto
|
||||
accessibilityText = text
|
||||
case .editVideo:
|
||||
text = presentationData.strings.Settings_EditVideo
|
||||
accessibilityText = text
|
||||
case .more:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Common_More
|
||||
icon = nil// PresentationResourcesRootController.navigationMoreCircledIcon(presentationData.theme)
|
||||
isGestureEnabled = true
|
||||
isAnimation = true
|
||||
animationState = .more
|
||||
case .qrCode:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.PeerInfo_QRCode_Title
|
||||
icon = PresentationResourcesRootController.navigationQrCodeIcon(presentationData.theme)
|
||||
case .moreToSearch:
|
||||
text = ""
|
||||
accessibilityText = ""
|
||||
case .postStory:
|
||||
text = ""
|
||||
accessibilityText = presentationData.strings.Story_Privacy_PostStory
|
||||
icon = PresentationResourcesRootController.navigationPostStoryIcon(presentationData.theme)
|
||||
}
|
||||
self.accessibilityLabel = accessibilityText
|
||||
self.containerNode.isGestureEnabled = isGestureEnabled
|
||||
|
||||
let font: UIFont = isBold ? Font.semibold(17.0) : Font.regular(17.0)
|
||||
|
||||
self.regularTextNode.attributedText = NSAttributedString(string: text, font: font, textColor: presentationData.theme.rootController.navigationBar.accentTextColor)
|
||||
self.whiteTextNode.attributedText = NSAttributedString(string: text, font: font, textColor: .white)
|
||||
self.textNode.attributedText = NSAttributedString(string: text, font: font, textColor: .white)
|
||||
transition.updateTintColor(layer: self.textNode.layer, color: self.contentsColor)
|
||||
self.iconNode.image = icon
|
||||
transition.updateTintColor(layer: self.iconNode.layer, color: self.contentsColor)
|
||||
|
||||
if isAnimation {
|
||||
self.iconNode.isHidden = true
|
||||
|
|
@ -236,9 +251,10 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||
animationNode = MoreIconNode()
|
||||
self.animationNode = animationNode
|
||||
self.contextSourceNode.addSubnode(animationNode)
|
||||
animationNode.imageNode.layer.layerTintColor = self.contentsColor.cgColor
|
||||
animationNode.customColor = .white
|
||||
}
|
||||
animationNode.customColor = .white
|
||||
animationNode.imageNode.layer.layerTintColor = self.isWhite ? UIColor.white.cgColor : presentationData.theme.rootController.navigationBar.accentTextColor.cgColor
|
||||
transition.updateTintColor(layer: animationNode.imageNode.layer, color: self.contentsColor)
|
||||
animationNode.enqueueState(animationState, animated: !isFirstTime)
|
||||
} else {
|
||||
self.iconNode.isHidden = false
|
||||
|
|
@ -248,39 +264,54 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||
}
|
||||
}
|
||||
|
||||
textSize = self.regularTextNode.updateLayout(CGSize(width: 200.0, height: .greatestFiniteMagnitude))
|
||||
let _ = self.whiteTextNode.updateLayout(CGSize(width: 200.0, height: .greatestFiniteMagnitude))
|
||||
textSize = self.textNode.updateLayout(CGSize(width: 200.0, height: .greatestFiniteMagnitude))
|
||||
} else {
|
||||
textSize = self.regularTextNode.bounds.size
|
||||
textSize = self.textNode.bounds.size
|
||||
}
|
||||
|
||||
let inset: CGFloat = 0.0
|
||||
|
||||
let resultSize: CGSize
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: inset, y: floor((height - textSize.height) / 2.0)), size: textSize)
|
||||
self.regularTextNode.frame = textFrame
|
||||
self.whiteTextNode.frame = textFrame
|
||||
self.textNode.frame = textFrame
|
||||
|
||||
if let animationNode = self.animationNode {
|
||||
let animationSize = CGSize(width: 30.0, height: 30.0)
|
||||
|
||||
animationNode.frame = CGRect(origin: CGPoint(x: inset, y: floor((height - animationSize.height) / 2.0)), size: animationSize)
|
||||
animationNode.frame = CGRect(origin: CGPoint(x: inset, y: floor((height - animationSize.height) / 2.0)), size: animationSize).offsetBy(dx: iconOffset.x, dy: iconOffset.y)
|
||||
|
||||
let size = CGSize(width: animationSize.width + inset * 2.0, height: height)
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
return size
|
||||
resultSize = size
|
||||
} else if let image = self.iconNode.image {
|
||||
self.iconNode.frame = CGRect(origin: CGPoint(x: inset, y: floor((height - image.size.height) / 2.0)), size: image.size)
|
||||
self.iconNode.frame = CGRect(origin: CGPoint(x: inset, y: floor((height - image.size.height) / 2.0)), size: image.size).offsetBy(dx: iconOffset.x, dy: iconOffset.y)
|
||||
|
||||
let size = CGSize(width: image.size.width + inset * 2.0, height: height)
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
return size
|
||||
resultSize = size
|
||||
} else {
|
||||
let size = CGSize(width: textSize.width + inset * 2.0, height: height)
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
return size
|
||||
resultSize = size
|
||||
}
|
||||
|
||||
let diameter: CGFloat = 32.0
|
||||
let backgroundWidth: CGFloat
|
||||
if self.iconNode.image != nil || self.animationNode != nil {
|
||||
backgroundWidth = diameter
|
||||
} else {
|
||||
backgroundWidth = max(diameter, resultSize.width + 12.0 * 2.0)
|
||||
}
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: floor((resultSize.width - backgroundWidth) * 0.5), y: floor((resultSize.height - diameter) * 0.5)), size: CGSize(width: backgroundWidth, height: diameter))
|
||||
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
|
||||
self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: diameter * 0.5, transition: transition)
|
||||
|
||||
self.hitTestSlop = UIEdgeInsets(top: -2.0, left: -12.0, bottom: -2.0, right: -12.0)
|
||||
|
||||
return resultSize
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import TelegramPresentationData
|
|||
import Display
|
||||
|
||||
enum PeerInfoHeaderNavigationButtonKey {
|
||||
case back
|
||||
case edit
|
||||
case done
|
||||
case cancel
|
||||
|
|
@ -33,30 +34,34 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||
private var currentLeftButtons: [PeerInfoHeaderNavigationButtonSpec] = []
|
||||
private var currentRightButtons: [PeerInfoHeaderNavigationButtonSpec] = []
|
||||
|
||||
var isWhite: Bool = false {
|
||||
didSet {
|
||||
if self.isWhite != oldValue {
|
||||
for (_, buttonNode) in self.leftButtonNodes {
|
||||
buttonNode.isWhite = self.isWhite
|
||||
}
|
||||
for (_, buttonNode) in self.rightButtonNodes {
|
||||
buttonNode.isWhite = self.isWhite
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private var backgroundContentColor: UIColor = .clear
|
||||
private var contentsColor: UIColor = .white
|
||||
|
||||
var performAction: ((PeerInfoHeaderNavigationButtonKey, ContextReferenceContentNode?, ContextGesture?) -> Void)?
|
||||
|
||||
func updateContentsColor(backgroundContentColor: UIColor, contentsColor: UIColor, transition: ContainedViewLayoutTransition) {
|
||||
self.backgroundContentColor = backgroundContentColor
|
||||
self.contentsColor = contentsColor
|
||||
|
||||
for (_, button) in self.leftButtonNodes {
|
||||
button.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, transition: transition)
|
||||
}
|
||||
for (_, button) in self.rightButtonNodes {
|
||||
button.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
func update(size: CGSize, presentationData: PresentationData, leftButtons: [PeerInfoHeaderNavigationButtonSpec], rightButtons: [PeerInfoHeaderNavigationButtonSpec], expandFraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
let sideInset: CGFloat = 24.0
|
||||
|
||||
let maximumExpandOffset: CGFloat = 14.0
|
||||
let expandOffset: CGFloat = -expandFraction * maximumExpandOffset
|
||||
|
||||
if self.currentLeftButtons != leftButtons || presentationData.strings !== self.presentationData?.strings {
|
||||
self.currentLeftButtons = leftButtons
|
||||
|
||||
var nextRegularButtonOrigin = 16.0
|
||||
var nextExpandedButtonOrigin = 16.0
|
||||
var nextRegularButtonOrigin = sideInset
|
||||
var nextExpandedButtonOrigin = sideInset
|
||||
for spec in leftButtons.reversed() {
|
||||
let buttonNode: PeerInfoHeaderNavigationButton
|
||||
var wasAdded = false
|
||||
|
|
@ -88,8 +93,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||
buttonNode.frame = buttonFrame
|
||||
buttonNode.alpha = 0.0
|
||||
transition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor)
|
||||
|
||||
buttonNode.isWhite = self.isWhite
|
||||
buttonNode.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, transition: .immediate)
|
||||
} else {
|
||||
transition.updateFrameAdditiveToCenter(node: buttonNode, frame: buttonFrame)
|
||||
transition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor)
|
||||
|
|
@ -107,8 +111,8 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
var nextRegularButtonOrigin = 16.0
|
||||
var nextExpandedButtonOrigin = 16.0
|
||||
var nextRegularButtonOrigin = sideInset
|
||||
var nextExpandedButtonOrigin = sideInset
|
||||
for spec in leftButtons.reversed() {
|
||||
if let buttonNode = self.leftButtonNodes[spec.key] {
|
||||
let buttonSize = buttonNode.bounds.size
|
||||
|
|
@ -135,8 +139,8 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||
if self.currentRightButtons != rightButtons || presentationData.strings !== self.presentationData?.strings {
|
||||
self.currentRightButtons = rightButtons
|
||||
|
||||
var nextRegularButtonOrigin = size.width - 16.0
|
||||
var nextExpandedButtonOrigin = size.width - 16.0
|
||||
var nextRegularButtonOrigin = size.width - sideInset
|
||||
var nextExpandedButtonOrigin = size.width - sideInset
|
||||
for spec in rightButtons.reversed() {
|
||||
let buttonNode: PeerInfoHeaderNavigationButton
|
||||
var wasAdded = false
|
||||
|
|
@ -174,7 +178,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||
}
|
||||
let alphaFactor: CGFloat = spec.isForExpandedView ? expandFraction : (1.0 - expandFraction)
|
||||
if wasAdded {
|
||||
buttonNode.isWhite = self.isWhite
|
||||
buttonNode.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, transition: .immediate)
|
||||
|
||||
if key == .moreToSearch {
|
||||
buttonNode.layer.animateScale(from: 0.001, to: 1.0, duration: 0.2)
|
||||
|
|
@ -211,8 +215,8 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
var nextRegularButtonOrigin = size.width - 16.0
|
||||
var nextExpandedButtonOrigin = size.width - 16.0
|
||||
var nextRegularButtonOrigin = size.width - sideInset
|
||||
var nextExpandedButtonOrigin = size.width - sideInset
|
||||
|
||||
for spec in rightButtons.reversed() {
|
||||
var key = spec.key
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ private let TitleNodeStateExpanded = 1
|
|||
|
||||
final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
private var context: AccountContext
|
||||
private weak var controller: PeerInfoScreenImpl?
|
||||
private var presentationData: PresentationData?
|
||||
private var state: PeerInfoState?
|
||||
private var peer: Peer?
|
||||
|
|
@ -159,8 +160,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
|
||||
private var validLayout: (width: CGFloat, deviceMetrics: DeviceMetrics)?
|
||||
|
||||
init(context: AccountContext, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, isMediaOnly: Bool, isSettings: Bool, forumTopicThreadId: Int64?, chatLocation: ChatLocation) {
|
||||
init(context: AccountContext, controller: PeerInfoScreenImpl, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, isMediaOnly: Bool, isSettings: Bool, forumTopicThreadId: Int64?, chatLocation: ChatLocation) {
|
||||
self.context = context
|
||||
self.controller = controller
|
||||
self.isAvatarExpanded = avatarInitiallyExpanded
|
||||
self.isOpenedFromChat = isOpenedFromChat
|
||||
self.isSettings = isSettings
|
||||
|
|
@ -481,7 +483,168 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
isForum = true
|
||||
}
|
||||
|
||||
if themeUpdated || self.currentCredibilityIcon != credibilityIcon {
|
||||
self.regularContentNode.alpha = state.isEditing ? 0.0 : 1.0
|
||||
self.editingContentNode.alpha = state.isEditing ? 1.0 : 0.0
|
||||
|
||||
let editingContentHeight = self.editingContentNode.update(width: width, safeInset: containerInset, statusBarHeight: statusBarHeight, navigationHeight: navigationHeight, isModalOverlay: isModalOverlay, peer: state.isEditing ? peer : nil, threadData: threadData, chatLocation: self.chatLocation, cachedData: cachedData, isContact: isContact, isSettings: isSettings, presentationData: presentationData, transition: transition)
|
||||
transition.updateFrame(node: self.editingContentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -contentOffset), size: CGSize(width: width, height: editingContentHeight)))
|
||||
|
||||
let avatarOverlayFarme = self.editingContentNode.convert(self.editingContentNode.avatarNode.frame, to: self)
|
||||
transition.updateFrame(node: self.avatarOverlayNode, frame: avatarOverlayFarme)
|
||||
|
||||
var transitionSourceHeight: CGFloat = 0.0
|
||||
var transitionFraction: CGFloat = 0.0
|
||||
var transitionSourceAvatarFrame: CGRect?
|
||||
var transitionSourceTitleFrame = CGRect()
|
||||
var transitionSourceSubtitleFrame = CGRect()
|
||||
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: floor((width - avatarSize) / 2.0), y: statusBarHeight + 22.0), size: CGSize(width: avatarSize, height: avatarSize))
|
||||
|
||||
self.backgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor, transition: .immediate)
|
||||
|
||||
let headerBackgroundColor: UIColor = presentationData.theme.list.blocksBackgroundColor
|
||||
|
||||
let regularNavigationContentsAccentColor: UIColor = peer?.profileColor != nil ? .white : presentationData.theme.list.itemAccentColor
|
||||
let collapsedHeaderNavigationContentsAccentColor = presentationData.theme.list.itemAccentColor
|
||||
let expandedAvatarNavigationContentsAccentColor: UIColor = .white
|
||||
|
||||
let regularNavigationContentsPrimaryColor: UIColor = peer?.profileColor != nil ? .white : presentationData.theme.list.itemPrimaryTextColor
|
||||
let collapsedHeaderNavigationContentsPrimaryColor = presentationData.theme.list.itemPrimaryTextColor
|
||||
let expandedAvatarNavigationContentsPrimaryColor: UIColor = .white
|
||||
|
||||
let regularContentButtonBackgroundColor: UIColor
|
||||
let collapsedHeaderContentButtonBackgroundColor = presentationData.theme.list.itemBlocksBackgroundColor
|
||||
let expandedAvatarContentButtonBackgroundColor: UIColor = UIColor(white: 1.0, alpha: 0.3)
|
||||
|
||||
let regularHeaderButtonBackgroundColor: UIColor
|
||||
let collapsedHeaderButtonBackgroundColor: UIColor = .clear
|
||||
let expandedAvatarHeaderButtonBackgroundColor: UIColor = UIColor(white: 1.0, alpha: 0.3)
|
||||
|
||||
let regularContentButtonForegroundColor: UIColor = peer?.profileColor != nil ? UIColor.white : presentationData.theme.list.itemAccentColor
|
||||
let collapsedHeaderContentButtonForegroundColor = presentationData.theme.list.itemAccentColor
|
||||
let expandedAvatarContentButtonForegroundColor: UIColor = .white
|
||||
|
||||
let regularNavigationContentsSecondaryColor: UIColor
|
||||
if let profileColor = peer?.profileColor {
|
||||
let backgroundColor = self.context.peerNameColors.getProfile(profileColor).main
|
||||
regularNavigationContentsSecondaryColor = UIColor(white: 1.0, alpha: 0.6).blitOver(backgroundColor.withMultiplied(hue: 1.0, saturation: 2.2, brightness: 1.5), alpha: 1.0)
|
||||
|
||||
if presentationData.theme.overallDarkAppearance {
|
||||
let baseButtonBackgroundColor: UIColor = UIColor(white: 0.0, alpha: 0.4)
|
||||
regularContentButtonBackgroundColor = baseButtonBackgroundColor.blitOver(backgroundColor.withMultiplied(hue: 1.0, saturation: 2.2, brightness: 0.7), alpha: 1.0)
|
||||
} else {
|
||||
let baseButtonBackgroundColor: UIColor = UIColor(white: 1.0, alpha: 0.3)
|
||||
regularContentButtonBackgroundColor = baseButtonBackgroundColor.blitOver(backgroundColor.withMultiplied(hue: 1.0, saturation: 0.8, brightness: 1.0), alpha: 1.0)
|
||||
}
|
||||
regularHeaderButtonBackgroundColor = regularContentButtonBackgroundColor
|
||||
} else {
|
||||
regularNavigationContentsSecondaryColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
regularContentButtonBackgroundColor = presentationData.theme.list.itemBlocksBackgroundColor
|
||||
regularHeaderButtonBackgroundColor = .clear
|
||||
}
|
||||
let collapsedHeaderNavigationContentsSecondaryColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
let expandedAvatarNavigationContentsSecondaryColor: UIColor = .white
|
||||
|
||||
let navigationContentsAccentColor: UIColor
|
||||
let navigationContentsPrimaryColor: UIColor
|
||||
let navigationContentsSecondaryColor: UIColor
|
||||
|
||||
let contentButtonBackgroundColor: UIColor
|
||||
let contentButtonForegroundColor: UIColor
|
||||
|
||||
let headerButtonBackgroundColor: UIColor
|
||||
|
||||
var effectiveSeparatorAlpha: CGFloat
|
||||
if let navigationTransition = self.navigationTransition {
|
||||
transitionSourceHeight = navigationTransition.sourceNavigationBar.backgroundNode.bounds.height
|
||||
transitionFraction = navigationTransition.fraction
|
||||
|
||||
if let avatarNavigationNode = navigationTransition.sourceNavigationBar.rightButtonNode.singleCustomNode as? ChatAvatarNavigationNode {
|
||||
if let statusView = avatarNavigationNode.statusView.view {
|
||||
transitionSourceAvatarFrame = statusView.convert(statusView.bounds, to: navigationTransition.sourceNavigationBar.view)
|
||||
} else {
|
||||
transitionSourceAvatarFrame = avatarNavigationNode.avatarNode.view.convert(avatarNavigationNode.avatarNode.view.bounds, to: navigationTransition.sourceNavigationBar.view)
|
||||
}
|
||||
transition.updateAlpha(node: self.avatarListNode.avatarContainerNode.avatarNode, alpha: 1.0 - transitionFraction)
|
||||
} else {
|
||||
if deviceMetrics.hasDynamicIsland && !isLandscape {
|
||||
transitionSourceAvatarFrame = CGRect(origin: CGPoint(x: avatarFrame.minX, y: -20.0), size: avatarFrame.size).insetBy(dx: avatarSize * 0.4, dy: avatarSize * 0.4)
|
||||
} else {
|
||||
transitionSourceAvatarFrame = avatarFrame.offsetBy(dx: 0.0, dy: -avatarFrame.maxY).insetBy(dx: avatarSize * 0.4, dy: avatarSize * 0.4)
|
||||
}
|
||||
}
|
||||
transitionSourceTitleFrame = navigationTransition.sourceTitleFrame
|
||||
transitionSourceSubtitleFrame = navigationTransition.sourceSubtitleFrame
|
||||
|
||||
transition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: 1.0 - transitionFraction)
|
||||
|
||||
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - transitionFraction), forceKeepBlur: true, transition: transition)
|
||||
effectiveSeparatorAlpha = transitionFraction
|
||||
|
||||
if self.isAvatarExpanded {
|
||||
navigationContentsAccentColor = expandedAvatarNavigationContentsAccentColor
|
||||
navigationContentsPrimaryColor = expandedAvatarNavigationContentsPrimaryColor
|
||||
navigationContentsSecondaryColor = expandedAvatarNavigationContentsSecondaryColor
|
||||
|
||||
contentButtonBackgroundColor = expandedAvatarContentButtonBackgroundColor
|
||||
contentButtonForegroundColor = expandedAvatarContentButtonForegroundColor
|
||||
|
||||
headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor
|
||||
} else {
|
||||
navigationContentsAccentColor = regularNavigationContentsAccentColor
|
||||
navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor
|
||||
navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor
|
||||
|
||||
contentButtonBackgroundColor = regularContentButtonBackgroundColor
|
||||
contentButtonForegroundColor = regularContentButtonForegroundColor
|
||||
|
||||
headerButtonBackgroundColor = regularHeaderButtonBackgroundColor
|
||||
}
|
||||
|
||||
if self.isAvatarExpanded, case .animated = transition, transitionFraction == 1.0 {
|
||||
self.avatarListNode.animateAvatarCollapse(transition: transition)
|
||||
}
|
||||
self.avatarClippingNode.clipsToBounds = false
|
||||
} else {
|
||||
let contentOffset = max(0.0, contentOffset - 140.0)
|
||||
let backgroundTransitionFraction: CGFloat = max(0.0, min(1.0, contentOffset / 30.0))
|
||||
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - backgroundTransitionFraction), forceKeepBlur: true, transition: transition)
|
||||
|
||||
transition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: state.isEditing ? 0.0 : (1.0 - backgroundTransitionFraction))
|
||||
|
||||
if state.isEditing {
|
||||
navigationContentsAccentColor = collapsedHeaderNavigationContentsAccentColor
|
||||
navigationContentsPrimaryColor = collapsedHeaderNavigationContentsPrimaryColor
|
||||
navigationContentsSecondaryColor = collapsedHeaderNavigationContentsSecondaryColor
|
||||
contentButtonBackgroundColor = collapsedHeaderContentButtonBackgroundColor
|
||||
contentButtonForegroundColor = collapsedHeaderContentButtonForegroundColor
|
||||
|
||||
headerButtonBackgroundColor = collapsedHeaderButtonBackgroundColor
|
||||
} else if self.isAvatarExpanded {
|
||||
navigationContentsAccentColor = expandedAvatarNavigationContentsAccentColor
|
||||
navigationContentsPrimaryColor = expandedAvatarNavigationContentsPrimaryColor
|
||||
navigationContentsSecondaryColor = expandedAvatarNavigationContentsSecondaryColor
|
||||
contentButtonBackgroundColor = expandedAvatarContentButtonBackgroundColor
|
||||
contentButtonForegroundColor = expandedAvatarContentButtonForegroundColor
|
||||
|
||||
headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor
|
||||
} else {
|
||||
navigationContentsAccentColor = regularNavigationContentsAccentColor.mixedWith(collapsedHeaderNavigationContentsAccentColor, alpha: backgroundTransitionFraction)
|
||||
navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor.mixedWith(collapsedHeaderNavigationContentsPrimaryColor, alpha: backgroundTransitionFraction)
|
||||
navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor.mixedWith(collapsedHeaderNavigationContentsSecondaryColor, alpha: backgroundTransitionFraction)
|
||||
|
||||
contentButtonBackgroundColor = regularContentButtonBackgroundColor.mixedWith(collapsedHeaderContentButtonBackgroundColor, alpha: backgroundTransitionFraction)
|
||||
contentButtonForegroundColor = regularContentButtonForegroundColor.mixedWith(collapsedHeaderContentButtonForegroundColor, alpha: backgroundTransitionFraction)
|
||||
|
||||
headerButtonBackgroundColor = regularHeaderButtonBackgroundColor.mixedWith(collapsedHeaderButtonBackgroundColor, alpha: backgroundTransitionFraction)
|
||||
}
|
||||
|
||||
effectiveSeparatorAlpha = backgroundTransitionFraction
|
||||
|
||||
self.avatarClippingNode.clipsToBounds = true
|
||||
}
|
||||
|
||||
do {
|
||||
self.currentCredibilityIcon = credibilityIcon
|
||||
|
||||
var currentEmojiStatus: PeerEmojiStatus?
|
||||
|
|
@ -492,11 +655,11 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
emojiRegularStatusContent = .none
|
||||
emojiExpandedStatusContent = .none
|
||||
case .premium:
|
||||
emojiRegularStatusContent = .premium(color: UIColor.white)
|
||||
emojiExpandedStatusContent = .premium(color: UIColor(rgb: 0xffffff, alpha: 0.75))
|
||||
emojiRegularStatusContent = .premium(color: navigationContentsAccentColor)
|
||||
emojiExpandedStatusContent = .premium(color: navigationContentsAccentColor)
|
||||
case .verified:
|
||||
emojiRegularStatusContent = .verified(fillColor: presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .large)
|
||||
emojiExpandedStatusContent = .verified(fillColor: UIColor(rgb: 0xffffff, alpha: 0.75), foregroundColor: .clear, sizeType: .large)
|
||||
emojiExpandedStatusContent = .verified(fillColor: navigationContentsAccentColor, foregroundColor: .clear, sizeType: .large)
|
||||
case .fake:
|
||||
emojiRegularStatusContent = .text(color: presentationData.theme.chat.message.incoming.scamColor, string: presentationData.strings.Message_FakeAccount.uppercased())
|
||||
emojiExpandedStatusContent = emojiRegularStatusContent
|
||||
|
|
@ -505,14 +668,14 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
emojiExpandedStatusContent = emojiRegularStatusContent
|
||||
case let .emojiStatus(emojiStatus):
|
||||
currentEmojiStatus = emojiStatus
|
||||
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: UIColor.white, loopMode: .forever)
|
||||
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: UIColor(rgb: 0xffffff, alpha: 0.15), themeColor: UIColor.white, loopMode: .forever)
|
||||
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: navigationContentsAccentColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||
}
|
||||
|
||||
let animateStatusIcon = !self.titleCredibilityIconView.bounds.isEmpty
|
||||
//let animateStatusIcon = !self.titleCredibilityIconView.bounds.isEmpty
|
||||
|
||||
let iconSize = self.titleCredibilityIconView.update(
|
||||
transition: animateStatusIcon ? Transition(animation: .curve(duration: 0.3, curve: .easeInOut)) : .immediate,
|
||||
transition: Transition(transition),
|
||||
component: AnyComponent(EmojiStatusComponent(
|
||||
context: self.context,
|
||||
animationCache: self.animationCache,
|
||||
|
|
@ -568,7 +731,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
containerSize: CGSize(width: 34.0, height: 34.0)
|
||||
)
|
||||
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
||||
transition: animateStatusIcon ? Transition(animation: .curve(duration: 0.3, curve: .easeInOut)) : .immediate,
|
||||
transition: Transition(transition),
|
||||
component: AnyComponent(EmojiStatusComponent(
|
||||
context: self.context,
|
||||
animationCache: self.animationCache,
|
||||
|
|
@ -591,76 +754,37 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
self.titleExpandedCredibilityIconSize = expandedIconSize
|
||||
}
|
||||
|
||||
self.regularContentNode.alpha = state.isEditing ? 0.0 : 1.0
|
||||
self.editingContentNode.alpha = state.isEditing ? 1.0 : 0.0
|
||||
self.navigationButtonContainer.updateContentsColor(backgroundContentColor: headerButtonBackgroundColor, contentsColor: navigationContentsAccentColor, transition: transition)
|
||||
|
||||
let editingContentHeight = self.editingContentNode.update(width: width, safeInset: containerInset, statusBarHeight: statusBarHeight, navigationHeight: navigationHeight, isModalOverlay: isModalOverlay, peer: state.isEditing ? peer : nil, threadData: threadData, chatLocation: self.chatLocation, cachedData: cachedData, isContact: isContact, isSettings: isSettings, presentationData: presentationData, transition: transition)
|
||||
transition.updateFrame(node: self.editingContentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -contentOffset), size: CGSize(width: width, height: editingContentHeight)))
|
||||
|
||||
let avatarOverlayFarme = self.editingContentNode.convert(self.editingContentNode.avatarNode.frame, to: self)
|
||||
transition.updateFrame(node: self.avatarOverlayNode, frame: avatarOverlayFarme)
|
||||
|
||||
var transitionSourceHeight: CGFloat = 0.0
|
||||
var transitionFraction: CGFloat = 0.0
|
||||
var transitionSourceAvatarFrame: CGRect?
|
||||
var transitionSourceTitleFrame = CGRect()
|
||||
var transitionSourceSubtitleFrame = CGRect()
|
||||
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: floor((width - avatarSize) / 2.0), y: statusBarHeight + 22.0), size: CGSize(width: avatarSize, height: avatarSize))
|
||||
|
||||
self.backgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor, transition: .immediate)
|
||||
|
||||
let headerBackgroundColor: UIColor = presentationData.theme.list.blocksBackgroundColor
|
||||
let _ = headerBackgroundColor
|
||||
|
||||
var effectiveSeparatorAlpha: CGFloat
|
||||
if let navigationTransition = self.navigationTransition {
|
||||
transitionSourceHeight = navigationTransition.sourceNavigationBar.backgroundNode.bounds.height
|
||||
transitionFraction = navigationTransition.fraction
|
||||
|
||||
if let avatarNavigationNode = navigationTransition.sourceNavigationBar.rightButtonNode.singleCustomNode as? ChatAvatarNavigationNode {
|
||||
if let statusView = avatarNavigationNode.statusView.view {
|
||||
transitionSourceAvatarFrame = statusView.convert(statusView.bounds, to: navigationTransition.sourceNavigationBar.view)
|
||||
} else {
|
||||
transitionSourceAvatarFrame = avatarNavigationNode.avatarNode.view.convert(avatarNavigationNode.avatarNode.view.bounds, to: navigationTransition.sourceNavigationBar.view)
|
||||
}
|
||||
transition.updateAlpha(node: self.avatarListNode.avatarContainerNode.avatarNode, alpha: 1.0 - transitionFraction)
|
||||
} else {
|
||||
if deviceMetrics.hasDynamicIsland && !isLandscape {
|
||||
transitionSourceAvatarFrame = CGRect(origin: CGPoint(x: avatarFrame.minX, y: -20.0), size: avatarFrame.size).insetBy(dx: avatarSize * 0.4, dy: avatarSize * 0.4)
|
||||
} else {
|
||||
transitionSourceAvatarFrame = avatarFrame.offsetBy(dx: 0.0, dy: -avatarFrame.maxY).insetBy(dx: avatarSize * 0.4, dy: avatarSize * 0.4)
|
||||
}
|
||||
self.titleNode.updateTintColor(color: navigationContentsPrimaryColor, transition: transition)
|
||||
self.subtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition)
|
||||
self.panelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition)
|
||||
self.nextPanelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition)
|
||||
if let navigationBar = self.controller?.navigationBar {
|
||||
if let mainContentNode = navigationBar.backButtonNode.mainContentNode {
|
||||
transition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor)
|
||||
}
|
||||
transitionSourceTitleFrame = navigationTransition.sourceTitleFrame
|
||||
transitionSourceSubtitleFrame = navigationTransition.sourceSubtitleFrame
|
||||
|
||||
transition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: 1.0 - transitionFraction)
|
||||
transition.updateTintColor(layer: navigationBar.backButtonArrow.layer, color: navigationContentsAccentColor)
|
||||
|
||||
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - transitionFraction), forceKeepBlur: true, transition: transition)
|
||||
effectiveSeparatorAlpha = transitionFraction
|
||||
|
||||
if self.isAvatarExpanded, case .animated = transition, transitionFraction == 1.0 {
|
||||
self.avatarListNode.animateAvatarCollapse(transition: transition)
|
||||
if let mainContentNode = navigationBar.leftButtonNode.mainContentNode {
|
||||
transition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor)
|
||||
}
|
||||
self.avatarClippingNode.clipsToBounds = false
|
||||
} else {
|
||||
let contentOffset = max(0.0, contentOffset - 140.0)
|
||||
let backgroundTransitionFraction: CGFloat = max(0.0, min(1.0, contentOffset / 30.0))
|
||||
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - backgroundTransitionFraction), forceKeepBlur: true, transition: transition)
|
||||
transition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: state.isEditing ? 0.0 : 1.0)
|
||||
|
||||
effectiveSeparatorAlpha = backgroundTransitionFraction
|
||||
|
||||
self.avatarClippingNode.clipsToBounds = true
|
||||
navigationBar.rightButtonNode.contentsColor = navigationContentsAccentColor
|
||||
navigationBar.leftButtonNode.contentsColor = navigationContentsAccentColor
|
||||
navigationBar.backButtonNode.contentsColor = navigationContentsAccentColor
|
||||
}
|
||||
|
||||
var titleBrightness: CGFloat = 0.0
|
||||
navigationContentsPrimaryColor.getHue(nil, saturation: nil, brightness: &titleBrightness, alpha: nil)
|
||||
self.controller?.setStatusBarStyle(titleBrightness > 0.5 ? .White : .Black, animated: !isFirstTime)
|
||||
|
||||
self.avatarListNode.avatarContainerNode.updateTransitionFraction(transitionFraction, transition: transition)
|
||||
self.avatarListNode.listContainerNode.currentItemNode?.updateTransitionFraction(transitionFraction, transition: transition)
|
||||
self.avatarOverlayNode.updateTransitionFraction(transitionFraction, transition: transition)
|
||||
|
||||
if self.navigationTitle != presentationData.strings.EditProfile_Title || themeUpdated {
|
||||
self.navigationTitleNode.attributedText = NSAttributedString(string: presentationData.strings.EditProfile_Title, font: Font.semibold(17.0), textColor: UIColor.white)
|
||||
self.navigationTitleNode.attributedText = NSAttributedString(string: presentationData.strings.EditProfile_Title, font: Font.semibold(17.0), textColor: .white)
|
||||
}
|
||||
|
||||
let navigationTitleSize = self.navigationTitleNode.updateLayout(CGSize(width: width, height: navigationHeight))
|
||||
|
|
@ -727,7 +851,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
}
|
||||
|
||||
titleStringText = title
|
||||
titleAttributes = MultiScaleTextState.Attributes(font: Font.medium(28.0), color: UIColor.white)
|
||||
titleAttributes = MultiScaleTextState.Attributes(font: Font.medium(28.0), color: .white)
|
||||
smallTitleAttributes = MultiScaleTextState.Attributes(font: Font.medium(28.0), color: .white)
|
||||
|
||||
if self.isSettings, let user = peer as? TelegramUser {
|
||||
|
|
@ -737,10 +861,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
subtitle = "\(subtitle) • @\(mainUsername)"
|
||||
}
|
||||
subtitleStringText = subtitle
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(17.0), color: UIColor.white.withMultipliedAlpha(0.7))
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor(white: 1.0, alpha: 0.7))
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(17.0), color: .white)
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white))
|
||||
} else if let _ = threadData {
|
||||
let subtitleColor: UIColor
|
||||
subtitleColor = UIColor.white
|
||||
|
|
@ -750,9 +874,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
|
||||
subtitleStringText = statusText
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.semibold(16.0), color: subtitleColor)
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor(white: 1.0, alpha: 0.7))
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white))
|
||||
|
||||
subtitleIsButton = true
|
||||
|
||||
|
|
@ -762,26 +886,26 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
if panelStatusData.isActivity {
|
||||
subtitleColor = UIColor.white
|
||||
} else {
|
||||
subtitleColor = UIColor.white.withAlphaComponent(0.7)
|
||||
subtitleColor = UIColor.white
|
||||
}
|
||||
panelSubtitleString = (panelStatusData.text, MultiScaleTextState.Attributes(font: Font.regular(17.0), color: subtitleColor))
|
||||
}
|
||||
if let nextPanelStatusData = maybeNextPanelStatusData {
|
||||
nextPanelSubtitleString = (nextPanelStatusData.text, MultiScaleTextState.Attributes(font: Font.regular(17.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
nextPanelSubtitleString = (nextPanelStatusData.text, MultiScaleTextState.Attributes(font: Font.regular(17.0), color: .white))
|
||||
}
|
||||
} else if let statusData = statusData {
|
||||
let subtitleColor: UIColor
|
||||
if statusData.isActivity {
|
||||
subtitleColor = UIColor.white
|
||||
} else {
|
||||
subtitleColor = UIColor.white.withMultipliedAlpha(0.7)
|
||||
subtitleColor = UIColor.white
|
||||
}
|
||||
|
||||
subtitleStringText = statusData.text
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(17.0), color: subtitleColor)
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor(white: 1.0, alpha: 0.7))
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white))
|
||||
|
||||
let (maybePanelStatusData, maybeNextPanelStatusData, _) = panelStatusData
|
||||
if let panelStatusData = maybePanelStatusData {
|
||||
|
|
@ -789,30 +913,30 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
if panelStatusData.isActivity {
|
||||
subtitleColor = UIColor.white
|
||||
} else {
|
||||
subtitleColor = UIColor.white.withMultipliedAlpha(0.7)
|
||||
subtitleColor = UIColor.white
|
||||
}
|
||||
panelSubtitleString = (panelStatusData.text, MultiScaleTextState.Attributes(font: Font.regular(17.0), color: subtitleColor))
|
||||
}
|
||||
if let nextPanelStatusData = maybeNextPanelStatusData {
|
||||
nextPanelSubtitleString = (nextPanelStatusData.text, MultiScaleTextState.Attributes(font: Font.regular(17.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
nextPanelSubtitleString = (nextPanelStatusData.text, MultiScaleTextState.Attributes(font: Font.regular(17.0), color: .white))
|
||||
}
|
||||
} else {
|
||||
subtitleStringText = " "
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7))
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7))
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white))
|
||||
}
|
||||
} else {
|
||||
titleStringText = " "
|
||||
titleAttributes = MultiScaleTextState.Attributes(font: Font.regular(24.0), color: UIColor.white)
|
||||
titleAttributes = MultiScaleTextState.Attributes(font: Font.regular(24.0), color: .white)
|
||||
smallTitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(24.0), color: .white)
|
||||
|
||||
subtitleStringText = " "
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7))
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7))
|
||||
subtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
smallSubtitleAttributes = MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white)
|
||||
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: UIColor.white.withMultipliedAlpha(0.7)))
|
||||
usernameString = ("", MultiScaleTextState.Attributes(font: Font.regular(16.0), color: .white))
|
||||
}
|
||||
|
||||
let textSideInset: CGFloat = 36.0
|
||||
|
|
@ -868,16 +992,16 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
if let current = self.subtitleArrowNode {
|
||||
subtitleArrowNode = current
|
||||
if themeUpdated {
|
||||
subtitleArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: UIColor.white.withMultipliedAlpha(0.5))
|
||||
subtitleArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
} else {
|
||||
subtitleArrowNode = ASImageNode()
|
||||
self.subtitleArrowNode = subtitleArrowNode
|
||||
self.subtitleNode.insertSubnode(subtitleArrowNode, at: 1)
|
||||
|
||||
subtitleArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: UIColor.white.withMultipliedAlpha(0.5))
|
||||
subtitleArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
subtitleBackgroundNode.backgroundColor = UIColor.white.withMultipliedAlpha(0.1)
|
||||
subtitleBackgroundNode.backgroundColor = .white.withMultipliedAlpha(0.1)
|
||||
let subtitleSize = subtitleNodeLayout[TitleNodeStateRegular]!.size
|
||||
var subtitleBackgroundFrame = CGRect(origin: CGPoint(), size: subtitleSize).offsetBy(dx: -subtitleSize.width * 0.5, dy: -subtitleSize.height * 0.5).insetBy(dx: -6.0, dy: -4.0)
|
||||
subtitleBackgroundFrame.size.width += 12.0
|
||||
|
|
@ -965,7 +1089,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
collapsedTransitionOffset = -10.0 * navigationTransition.fraction
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.titleCredibilityIconView, frame: CGRect(origin: CGPoint(x: titleSize.width + 4.0 + collapsedTransitionOffset, y: floor((titleSize.height - credibilityIconSize.height) / 2.0) + 2.0), size: credibilityIconSize))
|
||||
transition.updateFrame(view: self.titleCredibilityIconView, frame: CGRect(origin: CGPoint(x: titleSize.width + 4.0 + collapsedTransitionOffset, y: floor((titleSize.height - credibilityIconSize.height) / 2.0)), size: credibilityIconSize))
|
||||
transition.updateFrame(view: self.titleExpandedCredibilityIconView, frame: CGRect(origin: CGPoint(x: titleExpandedSize.width + 4.0, y: floor((titleExpandedSize.height - titleExpandedCredibilityIconSize.height) / 2.0) + 1.0), size: titleExpandedCredibilityIconSize))
|
||||
}
|
||||
|
||||
|
|
@ -1097,6 +1221,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
}
|
||||
avatarOffset = 0.0
|
||||
} else {
|
||||
//
|
||||
avatarScale = 1.0 * (1.0 - titleCollapseFraction) + avatarMinScale * titleCollapseFraction
|
||||
avatarOffset = apparentTitleLockOffset + 0.0 * (1.0 - titleCollapseFraction) + 10.0 * titleCollapseFraction
|
||||
}
|
||||
|
|
@ -1190,7 +1315,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
}
|
||||
} else {
|
||||
var trueAvatarSize = avatarFrame.size
|
||||
if let storyStats = self.avatarListNode.avatarContainerNode.avatarNode.storyStats, storyStats.unseenCount != 0 {
|
||||
if let storyStats = self.avatarListNode.avatarContainerNode.avatarNode.storyStats, storyStats.totalCount != 0 {
|
||||
trueAvatarSize.width -= 3.0 * 4.0
|
||||
trueAvatarSize.height -= 3.0 * 4.0
|
||||
}
|
||||
|
|
@ -1551,7 +1676,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
isActive = buttonKey == highlightedButton
|
||||
}
|
||||
|
||||
buttonNode.update(size: buttonFrame.size, text: buttonText, icon: buttonIcon, isActive: isActive, presentationData: presentationData, transition: buttonTransition)
|
||||
buttonNode.update(size: buttonFrame.size, text: buttonText, icon: buttonIcon, isActive: isActive, presentationData: presentationData, backgroundColor: contentButtonBackgroundColor, foregroundColor: contentButtonForegroundColor, transition: buttonTransition)
|
||||
|
||||
if wasAdded {
|
||||
buttonNode.alpha = 0.0
|
||||
|
|
@ -1621,6 +1746,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
component: AnyComponent(PeerInfoCoverComponent(
|
||||
context: self.context,
|
||||
peer: peer.flatMap(EnginePeer.init),
|
||||
isDark: presentationData.theme.overallDarkAppearance,
|
||||
avatarCenter: apparentAvatarFrame.center,
|
||||
avatarScale: avatarScale,
|
||||
avatarTransitionFraction: max(0.0, min(1.0, titleCollapseFraction + transitionFraction * 2.0)),
|
||||
|
|
|
|||
|
|
@ -2256,7 +2256,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
if case let .replyThread(message) = chatLocation {
|
||||
forumTopicThreadId = Int64(message.messageId.id)
|
||||
}
|
||||
self.headerNode = PeerInfoHeaderNode(context: context, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, isMediaOnly: self.isMediaOnly, isSettings: isSettings, forumTopicThreadId: forumTopicThreadId, chatLocation: self.chatLocation)
|
||||
self.headerNode = PeerInfoHeaderNode(context: context, controller: controller, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, isMediaOnly: self.isMediaOnly, isSettings: isSettings, forumTopicThreadId: forumTopicThreadId, chatLocation: self.chatLocation)
|
||||
self.paneContainerNode = PeerInfoPaneContainerNode(context: context, updatedPresentationData: controller.updatedPresentationData, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, isMediaOnly: self.isMediaOnly)
|
||||
|
||||
super.init()
|
||||
|
|
@ -3301,6 +3301,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
return
|
||||
}
|
||||
switch key {
|
||||
case .back:
|
||||
strongSelf.controller?.dismiss()
|
||||
case .edit:
|
||||
if case let .replyThread(message) = strongSelf.chatLocation {
|
||||
let threadId = Int64(message.messageId.id)
|
||||
|
|
@ -3353,7 +3355,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
}
|
||||
})
|
||||
strongSelf.controller?.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, style: .plain, target: strongSelf, action: #selector(strongSelf.editingCancelPressed)), animated: true)
|
||||
}
|
||||
case .done, .cancel:
|
||||
strongSelf.view.endEditing(true)
|
||||
|
|
@ -3669,7 +3670,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
UIView.transition(with: strongSelf.view, duration: 0.3, options: [.transitionCrossDissolve], animations: {
|
||||
}, completion: nil)
|
||||
strongSelf.controller?.navigationItem.setLeftBarButton(nil, animated: true)
|
||||
}
|
||||
(strongSelf.controller?.parent as? TabBarController)?.updateIsTabBarHidden(false, transition: .animated(duration: 0.3, curve: .linear))
|
||||
case .select:
|
||||
|
|
@ -4015,11 +4015,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
self.storiesReady.set(false)
|
||||
let expiringStoryList = PeerExpiringStoryListContext(account: context.account, peerId: peerId)
|
||||
self.expiringStoryList = expiringStoryList
|
||||
self.storyUploadProgressDisposable = (context.engine.messages.allStoriesUploadProgress()
|
||||
|> map { value -> Float? in
|
||||
return value[peerId]
|
||||
}
|
||||
|> distinctUntilChanged).startStrict(next: { [weak self] value in
|
||||
self.storyUploadProgressDisposable = (
|
||||
combineLatest(context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> distinctUntilChanged,
|
||||
context.engine.messages.allStoriesUploadProgress()
|
||||
|> map { value -> Float? in
|
||||
return value[peerId]
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
)).startStrict(next: { [weak self] peer, value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -4030,7 +4034,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
|
||||
if self.headerNode.avatarListNode.avatarContainerNode.storyProgress != mappedValue {
|
||||
self.headerNode.avatarListNode.avatarContainerNode.storyProgress = mappedValue
|
||||
self.headerNode.avatarListNode.avatarContainerNode.updateStoryView(transition: .immediate, theme: self.presentationData.theme)
|
||||
self.headerNode.avatarListNode.avatarContainerNode.updateStoryView(transition: .immediate, theme: self.presentationData.theme, peer: peer?._asPeer())
|
||||
}
|
||||
})
|
||||
self.expiringStoryListDisposable = (combineLatest(queue: .mainQueue(),
|
||||
|
|
@ -9977,11 +9981,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
self.paneContainerNode.update(size: self.paneContainerNode.bounds.size, sideInset: layout.safeInsets.left, bottomInset: bottomInset, visibleHeight: visibleHeight, expansionFraction: effectiveAreaExpansionFraction, presentationData: self.presentationData, data: self.data, transition: transition)
|
||||
|
||||
transition.updateFrame(node: self.headerNode.navigationButtonContainer, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left, y: layout.statusBarHeight ?? 0.0), size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight)))
|
||||
self.headerNode.navigationButtonContainer.isWhite = true//self.headerNode.isAvatarExpanded
|
||||
|
||||
|
||||
var leftNavigationButtons: [PeerInfoHeaderNavigationButtonSpec] = []
|
||||
var rightNavigationButtons: [PeerInfoHeaderNavigationButtonSpec] = []
|
||||
if self.state.isEditing {
|
||||
leftNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .cancel, isForExpandedView: false))
|
||||
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .done, isForExpandedView: false))
|
||||
} else {
|
||||
if self.isSettings {
|
||||
|
|
@ -10017,6 +10022,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .selectionDone, isForExpandedView: true))
|
||||
}
|
||||
}
|
||||
if leftNavigationButtons.isEmpty, let controller = self.controller, let previousItem = controller.previousItem {
|
||||
switch previousItem {
|
||||
case .close, .item:
|
||||
leftNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .back, isForExpandedView: false))
|
||||
}
|
||||
}
|
||||
self.headerNode.navigationButtonContainer.update(size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight), presentationData: self.presentationData, leftButtons: leftNavigationButtons, rightButtons: rightNavigationButtons, expandFraction: effectiveAreaExpansionFraction, transition: transition)
|
||||
}
|
||||
}
|
||||
|
|
@ -10120,9 +10131,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
|
||||
private func updateNavigationExpansionPresentation(isExpanded: Bool, animated: Bool) {
|
||||
if let controller = self.controller {
|
||||
controller.setStatusBarStyle(.White, animated: animated)
|
||||
|
||||
/*if let controller = self.controller {
|
||||
if animated {
|
||||
UIView.transition(with: controller.controllerNode.headerNode.navigationButtonContainer.view, duration: 0.3, options: [.transitionCrossDissolve], animations: {
|
||||
}, completion: nil)
|
||||
|
|
@ -10143,7 +10152,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
), strings: baseNavigationBarPresentationData.strings)
|
||||
|
||||
controller.setNavigationBarPresentationData(navigationBarPresentationData, animated: animated)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
|
||||
|
|
@ -10310,6 +10319,16 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
}
|
||||
}
|
||||
|
||||
override public var previousItem: NavigationPreviousAction? {
|
||||
didSet {
|
||||
if self.isNodeLoaded {
|
||||
if let (layout, navigationHeight) = self.validLayout {
|
||||
self.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var validLayout: (layout: ContainerViewLayout, navigationHeight: CGFloat)?
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool = false, hintGroupInCommon: PeerId? = nil, requestsContext: PeerInvitationImportersContext? = nil, forumTopicThread: ChatReplyThreadMessage? = nil) {
|
||||
|
|
@ -10337,8 +10356,8 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
super.init(navigationBarPresentationData: NavigationBarPresentationData(
|
||||
theme: NavigationBarTheme(
|
||||
buttonColor: .white,
|
||||
disabledButtonColor: baseNavigationBarPresentationData.theme.disabledButtonColor,
|
||||
primaryTextColor: baseNavigationBarPresentationData.theme.primaryTextColor,
|
||||
disabledButtonColor: .white,
|
||||
primaryTextColor: .white,
|
||||
backgroundColor: .clear,
|
||||
enableBackgroundBlur: false,
|
||||
separatorColor: .clear,
|
||||
|
|
@ -10346,6 +10365,8 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
badgeStrokeColor: baseNavigationBarPresentationData.theme.badgeStrokeColor,
|
||||
badgeTextColor: baseNavigationBarPresentationData.theme.badgeTextColor
|
||||
), strings: baseNavigationBarPresentationData.strings))
|
||||
|
||||
self.navigationBar?.enableAutomaticBackButton = false
|
||||
|
||||
if isSettings {
|
||||
let activeSessionsContextAndCountSignal = deferred { () -> Signal<(ActiveSessionsContext, Int, WebSessionsContext)?, NoError> in
|
||||
|
|
@ -10557,8 +10578,6 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
}
|
||||
}
|
||||
|
||||
self.setStatusBarStyle(.White, animated: false)
|
||||
|
||||
self.scrollToTop = { [weak self] in
|
||||
self?.controllerNode.scrollToTop()
|
||||
}
|
||||
|
|
@ -11056,7 +11075,7 @@ private final class PeerInfoNavigationTransitionNode: ASDisplayNode, CustomNavig
|
|||
|
||||
if let currentBackButtonArrow = topNavigationBar.makeTransitionBackArrowNode(accentColor: .white) {
|
||||
self.currentBackButtonArrow = currentBackButtonArrow
|
||||
self.addSubnode(currentBackButtonArrow)
|
||||
//self.addSubnode(currentBackButtonArrow)
|
||||
}
|
||||
|
||||
if let headerView = bottomNavigationBar.customHeaderContentView as? ChatListHeaderComponent.View {
|
||||
|
|
@ -11070,7 +11089,7 @@ private final class PeerInfoNavigationTransitionNode: ASDisplayNode, CustomNavig
|
|||
|
||||
if let currentBackButton = topNavigationBar.makeTransitionBackButtonNode(accentColor: .white) {
|
||||
self.currentBackButton = currentBackButton
|
||||
self.addSubnode(currentBackButton)
|
||||
//self.addSubnode(currentBackButton)
|
||||
}
|
||||
|
||||
if let headerView = bottomNavigationBar.customHeaderContentView as? ChatListHeaderComponent.View {
|
||||
|
|
@ -11142,10 +11161,12 @@ private final class PeerInfoNavigationTransitionNode: ASDisplayNode, CustomNavig
|
|||
if let backArrowView = headerView.backArrowView {
|
||||
let previousBackButtonArrowFrame = backArrowView.convert(backArrowView.bounds, to: bottomNavigationBar.view)
|
||||
previousBackButtonArrow.frame = previousBackButtonArrowFrame
|
||||
transition.updateAlpha(layer: previousBackButtonArrow.layer, alpha: fraction)
|
||||
}
|
||||
} else {
|
||||
let previousBackButtonArrowFrame = bottomNavigationBar.backButtonArrow.view.convert(bottomNavigationBar.backButtonArrow.view.bounds, to: bottomNavigationBar.view)
|
||||
previousBackButtonArrow.frame = previousBackButtonArrowFrame
|
||||
transition.updateAlpha(layer: previousBackButtonArrow.layer, alpha: fraction)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ swift_library(
|
|||
"//submodules/SolidRoundedButtonNode",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/PremiumUI",
|
||||
"//submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent",
|
||||
"//submodules/AvatarNode",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ final class EmojiPickerItem: ListViewItem, ItemListItem {
|
|||
let strings: PresentationStrings
|
||||
let emojiContent: EmojiPagerContentComponent
|
||||
let backgroundIconColor: UIColor
|
||||
let isProfileColor: Bool
|
||||
let hasRemoveButton: Bool
|
||||
let sectionId: ItemListSectionId
|
||||
|
||||
init(
|
||||
|
|
@ -24,6 +26,8 @@ final class EmojiPickerItem: ListViewItem, ItemListItem {
|
|||
strings: PresentationStrings,
|
||||
emojiContent: EmojiPagerContentComponent,
|
||||
backgroundIconColor: UIColor,
|
||||
isProfileColor: Bool,
|
||||
hasRemoveButton: Bool,
|
||||
sectionId: ItemListSectionId
|
||||
) {
|
||||
self.context = context
|
||||
|
|
@ -31,6 +35,8 @@ final class EmojiPickerItem: ListViewItem, ItemListItem {
|
|||
self.strings = strings
|
||||
self.emojiContent = emojiContent
|
||||
self.backgroundIconColor = backgroundIconColor
|
||||
self.isProfileColor = isProfileColor
|
||||
self.hasRemoveButton = hasRemoveButton
|
||||
self.sectionId = sectionId
|
||||
}
|
||||
|
||||
|
|
@ -103,13 +109,20 @@ final class EmojiPickerItemNode: ListViewItemNode {
|
|||
}
|
||||
|
||||
func asyncLayout() -> (_ item: EmojiPickerItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||
let currentItem = self.item
|
||||
|
||||
return { item, params, neighbors in
|
||||
let insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
|
||||
var contentSize = CGSize(width: params.width, height: params.availableHeight - 452.0)
|
||||
var contentHeight: CGFloat
|
||||
if item.isProfileColor {
|
||||
contentHeight = params.availableHeight - 352.0 - 10.0
|
||||
if item.hasRemoveButton {
|
||||
contentHeight -= 44.0
|
||||
}
|
||||
} else {
|
||||
contentHeight = params.availableHeight - 452.0
|
||||
}
|
||||
var contentSize = CGSize(width: params.width, height: contentHeight)
|
||||
if params.width <= 320.0 {
|
||||
contentSize.height += 77.0
|
||||
}
|
||||
|
|
@ -121,16 +134,6 @@ final class EmojiPickerItemNode: ListViewItemNode {
|
|||
return (layout, { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.item = item
|
||||
|
||||
if let currentItem, currentItem.backgroundIconColor != item.backgroundIconColor {
|
||||
if let snapshot = strongSelf.view.snapshotView(afterScreenUpdates: false) {
|
||||
snapshot.frame = CGRect(origin: CGPoint(x: 0.0, y: -insets.top), size: snapshot.frame.size)
|
||||
strongSelf.view.addSubview(snapshot)
|
||||
snapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: 0.25, removeOnCompletion: false, completion: { _ in
|
||||
snapshot.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode {
|
|||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var messages = SimpleDictionary<MessageId, Message>()
|
||||
|
||||
peers[authorPeerId] = TelegramUser(id: authorPeerId, accessHash: nil, firstName: messageItem.author, lastName: "", username: nil, phone: nil, photo: messageItem.photo, botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: messageItem.nameColor, backgroundEmojiId: messageItem.backgroundEmojiId)
|
||||
peers[authorPeerId] = TelegramUser(id: authorPeerId, accessHash: nil, firstName: messageItem.author, lastName: "", username: nil, phone: nil, photo: messageItem.photo, botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: messageItem.nameColor, backgroundEmojiId: messageItem.backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
|
||||
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
|
||||
if let (_, text) = messageItem.reply {
|
||||
|
|
@ -296,7 +296,7 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode {
|
|||
headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset)
|
||||
headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: .immediate)
|
||||
} else {
|
||||
headerNode = header.node(synchronousLoad: false)
|
||||
headerNode = header.node(synchronousLoad: true)
|
||||
if headerNode.item !== header {
|
||||
header.updateNode(headerNode, previous: nil, next: nil)
|
||||
headerNode.item = header
|
||||
|
|
|
|||
|
|
@ -287,13 +287,15 @@ final class PeerNameColorItem: ListViewItem, ItemListItem {
|
|||
|
||||
let theme: PresentationTheme
|
||||
let colors: PeerNameColors
|
||||
let currentColor: PeerNameColor
|
||||
let isProfile: Bool
|
||||
let currentColor: PeerNameColor?
|
||||
let updated: (PeerNameColor) -> Void
|
||||
let tag: ItemListItemTag?
|
||||
|
||||
init(theme: PresentationTheme, colors: PeerNameColors, currentColor: PeerNameColor, updated: @escaping (PeerNameColor) -> Void, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId) {
|
||||
init(theme: PresentationTheme, colors: PeerNameColors, isProfile: Bool, currentColor: PeerNameColor?, updated: @escaping (PeerNameColor) -> Void, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId) {
|
||||
self.theme = theme
|
||||
self.colors = colors
|
||||
self.isProfile = isProfile
|
||||
self.currentColor = currentColor
|
||||
self.updated = updated
|
||||
self.tag = tag
|
||||
|
|
@ -436,7 +438,13 @@ final class PeerNameColorItemNode: ListViewItemNode, ItemListItemNode {
|
|||
let options = ListViewDeleteAndInsertOptions()
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if !self.initialized || transition.updatePosition || !self.tapping {
|
||||
if let index = item.colors.displayOrder.firstIndex(where: { $0 == item.currentColor.rawValue }) {
|
||||
let displayOrder: [Int32]
|
||||
if item.isProfile {
|
||||
displayOrder = item.colors.profileDisplayOrder
|
||||
} else {
|
||||
displayOrder = item.colors.displayOrder
|
||||
}
|
||||
if let index = displayOrder.firstIndex(where: { $0 == item.currentColor?.rawValue }) {
|
||||
scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-70.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down)
|
||||
self.initialized = true
|
||||
}
|
||||
|
|
@ -492,12 +500,17 @@ final class PeerNameColorItemNode: ListViewItemNode, ItemListItemNode {
|
|||
let hasCorners = itemListHasRoundedBlockLayout(params)
|
||||
var hasTopCorners = false
|
||||
var hasBottomCorners = false
|
||||
switch neighbors.top {
|
||||
if item.currentColor != nil {
|
||||
switch neighbors.top {
|
||||
case .sameSection(false):
|
||||
strongSelf.topStripeNode.isHidden = true
|
||||
default:
|
||||
hasTopCorners = true
|
||||
strongSelf.topStripeNode.isHidden = hasCorners
|
||||
}
|
||||
} else {
|
||||
strongSelf.topStripeNode.isHidden = true
|
||||
hasTopCorners = true
|
||||
}
|
||||
let bottomStripeInset: CGFloat
|
||||
let bottomStripeOffset: CGFloat
|
||||
|
|
@ -531,10 +544,21 @@ final class PeerNameColorItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
var entries: [PeerNameColorEntry] = []
|
||||
|
||||
let displayOrder: [Int32]
|
||||
if item.isProfile {
|
||||
displayOrder = item.colors.profileDisplayOrder
|
||||
} else {
|
||||
displayOrder = item.colors.displayOrder
|
||||
}
|
||||
var i: Int = 0
|
||||
for index in item.colors.displayOrder {
|
||||
for index in displayOrder {
|
||||
let color = PeerNameColor(rawValue: index)
|
||||
let colors = item.colors.get(color, dark: item.theme.overallDarkAppearance)
|
||||
let colors: PeerNameColors.Colors
|
||||
if item.isProfile {
|
||||
colors = item.colors.getProfile(color, dark: item.theme.overallDarkAppearance)
|
||||
} else {
|
||||
colors = item.colors.get(color, dark: item.theme.overallDarkAppearance)
|
||||
}
|
||||
entries.append(.color(i, color, colors, item.theme.overallDarkAppearance, color == item.currentColor))
|
||||
|
||||
i += 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,274 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import Postbox
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import ComponentFlow
|
||||
import PeerInfoCoverComponent
|
||||
import AvatarNode
|
||||
import EmojiStatusComponent
|
||||
|
||||
final class PeerNameColorProfilePreviewItem: ListViewItem, ItemListItem {
|
||||
let context: AccountContext
|
||||
let theme: PresentationTheme
|
||||
let componentTheme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let sectionId: ItemListSectionId
|
||||
let peer: EnginePeer?
|
||||
let nameDisplayOrder: PresentationPersonNameOrder
|
||||
|
||||
init(context: AccountContext, theme: PresentationTheme, componentTheme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, peer: EnginePeer?, nameDisplayOrder: PresentationPersonNameOrder) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.componentTheme = componentTheme
|
||||
self.strings = strings
|
||||
self.sectionId = sectionId
|
||||
self.peer = peer
|
||||
self.nameDisplayOrder = nameDisplayOrder
|
||||
}
|
||||
|
||||
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
async {
|
||||
let node = PeerNameColorProfilePreviewItemNode()
|
||||
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||
|
||||
node.contentSize = layout.contentSize
|
||||
node.insets = layout.insets
|
||||
|
||||
Queue.mainQueue().async {
|
||||
completion(node, {
|
||||
return (nil, { _ in apply() })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||
Queue.mainQueue().async {
|
||||
if let nodeValue = node() as? PeerNameColorProfilePreviewItemNode {
|
||||
let makeLayout = nodeValue.asyncLayout()
|
||||
|
||||
async {
|
||||
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||
Queue.mainQueue().async {
|
||||
completion(layout, { _ in
|
||||
apply()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class PeerNameColorProfilePreviewItemNode: ListViewItemNode {
|
||||
private let background = ComponentView<Empty>()
|
||||
private let avatarNode: AvatarNode
|
||||
private let title = ComponentView<Empty>()
|
||||
private let subtitle = ComponentView<Empty>()
|
||||
private var icon: ComponentView<Empty>?
|
||||
|
||||
private let topStripeNode: ASDisplayNode
|
||||
private let bottomStripeNode: ASDisplayNode
|
||||
private let maskNode: ASImageNode
|
||||
|
||||
private var item: PeerNameColorProfilePreviewItem?
|
||||
|
||||
init() {
|
||||
self.topStripeNode = ASDisplayNode()
|
||||
self.topStripeNode.isLayerBacked = true
|
||||
|
||||
self.bottomStripeNode = ASDisplayNode()
|
||||
self.bottomStripeNode.isLayerBacked = true
|
||||
|
||||
self.maskNode = ASImageNode()
|
||||
|
||||
let avatarFont = avatarPlaceholderFont(size: floor(100.0 * 16.0 / 37.0))
|
||||
self.avatarNode = AvatarNode(font: avatarFont)
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: PeerNameColorProfilePreviewItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||
return { [weak self] item, params, neighbors in
|
||||
let separatorHeight = UIScreenPixel
|
||||
|
||||
let contentSize = CGSize(width: params.width, height: 210.0)
|
||||
var insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
if params.width <= 320.0 {
|
||||
insets.top = 0.0
|
||||
}
|
||||
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||
let layoutSize = layout.size
|
||||
|
||||
return (layout, { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.item = item
|
||||
|
||||
self.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
self.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
if self.topStripeNode.supernode == nil {
|
||||
self.addSubnode(self.topStripeNode)
|
||||
}
|
||||
if self.bottomStripeNode.supernode == nil {
|
||||
self.addSubnode(self.bottomStripeNode)
|
||||
}
|
||||
if self.maskNode.supernode == nil {
|
||||
self.addSubnode(self.maskNode)
|
||||
}
|
||||
|
||||
let hasCorners = itemListHasRoundedBlockLayout(params)
|
||||
var hasTopCorners = false
|
||||
var hasBottomCorners = false
|
||||
switch neighbors.top {
|
||||
case .sameSection(false):
|
||||
self.topStripeNode.isHidden = true
|
||||
default:
|
||||
hasTopCorners = true
|
||||
self.topStripeNode.isHidden = hasCorners
|
||||
}
|
||||
let bottomStripeInset: CGFloat
|
||||
let bottomStripeOffset: CGFloat
|
||||
switch neighbors.bottom {
|
||||
case .sameSection(false):
|
||||
bottomStripeInset = 0.0
|
||||
bottomStripeOffset = -separatorHeight
|
||||
self.bottomStripeNode.isHidden = item.peer?.profileColor == nil
|
||||
default:
|
||||
bottomStripeInset = 0.0
|
||||
bottomStripeOffset = 0.0
|
||||
hasBottomCorners = true
|
||||
self.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
self.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.componentTheme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
|
||||
let coverFrame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
|
||||
let avatarSize: CGFloat = 104.0
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: floor((coverFrame.width - avatarSize) * 0.5), y: coverFrame.minY + 24.0), size: CGSize(width: avatarSize, height: avatarSize))
|
||||
|
||||
let _ = self.background.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(PeerInfoCoverComponent(
|
||||
context: item.context,
|
||||
peer: item.peer,
|
||||
isDark: item.theme.overallDarkAppearance,
|
||||
avatarCenter: avatarFrame.center,
|
||||
avatarScale: 1.0,
|
||||
avatarTransitionFraction: 0.0,
|
||||
patternTransitionFraction: 0.0
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: coverFrame.size
|
||||
)
|
||||
if let backgroundView = self.background.view {
|
||||
if backgroundView.superview == nil {
|
||||
backgroundView.clipsToBounds = true
|
||||
self.view.insertSubview(backgroundView, at: 0)
|
||||
}
|
||||
backgroundView.frame = coverFrame
|
||||
}
|
||||
|
||||
let clipStyle: AvatarNodeClipStyle
|
||||
switch item.peer {
|
||||
case let .channel(channel) where channel.isForum:
|
||||
clipStyle = .roundedRect
|
||||
default:
|
||||
clipStyle = .round
|
||||
}
|
||||
self.avatarNode.setPeer(
|
||||
context: item.context,
|
||||
theme: item.theme,
|
||||
peer: item.peer,
|
||||
clipStyle: clipStyle,
|
||||
synchronousLoad: true,
|
||||
displayDimensions: avatarFrame.size
|
||||
)
|
||||
if self.avatarNode.supernode == nil {
|
||||
self.addSubnode(self.avatarNode)
|
||||
}
|
||||
self.avatarNode.frame = avatarFrame.offsetBy(dx: coverFrame.minX, dy: coverFrame.minY)
|
||||
|
||||
let backgroundColor: UIColor
|
||||
let titleColor: UIColor
|
||||
let subtitleColor: UIColor
|
||||
if let peer = item.peer, let profileColor = peer.profileColor {
|
||||
titleColor = .white
|
||||
backgroundColor = item.context.peerNameColors.getProfile(profileColor).main
|
||||
subtitleColor = UIColor(white: 1.0, alpha: 0.6).blitOver(backgroundColor.withMultiplied(hue: 1.0, saturation: 2.2, brightness: 1.5), alpha: 1.0)
|
||||
} else {
|
||||
titleColor = item.theme.list.itemPrimaryTextColor
|
||||
subtitleColor = item.theme.list.itemSecondaryTextColor
|
||||
backgroundColor = .clear
|
||||
}
|
||||
|
||||
let titleString: String = item.peer?.displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) ?? " "
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Text(
|
||||
text: titleString, font: Font.semibold(28.0), color: titleColor
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: coverFrame.width - 16.0, height: 100.0)
|
||||
)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: coverFrame.minX + floor((coverFrame.width - titleSize.width) * 0.5), y: avatarFrame.maxY + 10.0), size: titleSize)
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
self.view.addSubview(titleView)
|
||||
}
|
||||
titleView.frame = titleFrame
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let subtitleString: String = "last seen just now"
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Text(
|
||||
text: subtitleString, font: Font.regular(18.0), color: subtitleColor
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: coverFrame.width - 16.0, height: 100.0)
|
||||
)
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: coverFrame.minX + floor((coverFrame.width - subtitleSize.width) * 0.5), y: titleFrame.maxY + 3.0), size: subtitleSize)
|
||||
if let subtitleView = self.subtitle.view {
|
||||
if subtitleView.superview == nil {
|
||||
self.view.addSubview(subtitleView)
|
||||
}
|
||||
subtitleView.frame = subtitleFrame
|
||||
}
|
||||
|
||||
self.maskNode.frame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
self.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
self.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||
}
|
||||
|
||||
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,12 +16,12 @@ import PremiumUI
|
|||
|
||||
private final class PeerNameColorScreenArguments {
|
||||
let context: AccountContext
|
||||
let updateNameColor: (PeerNameColor) -> Void
|
||||
let updateNameColor: (PeerNameColor?) -> Void
|
||||
let updateBackgroundEmojiId: (Int64?) -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
updateNameColor: @escaping (PeerNameColor) -> Void,
|
||||
updateNameColor: @escaping (PeerNameColor?) -> Void,
|
||||
updateBackgroundEmojiId: @escaping (Int64?) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
|
|
@ -39,7 +39,9 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
enum StableId: Hashable {
|
||||
case colorHeader
|
||||
case colorMessage
|
||||
case colorProfile
|
||||
case colorPicker
|
||||
case removeColor
|
||||
case colorDescription
|
||||
case backgroundEmojiHeader
|
||||
case backgroundEmoji
|
||||
|
|
@ -47,14 +49,16 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
|
||||
case colorHeader(String)
|
||||
case colorMessage(wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, items: [PeerNameColorChatPreviewItem.MessageItem])
|
||||
case colorPicker(colors: PeerNameColors, currentColor: PeerNameColor)
|
||||
case colorProfile(peer: EnginePeer?, nameDisplayOrder: PresentationPersonNameOrder)
|
||||
case colorPicker(colors: PeerNameColors, currentColor: PeerNameColor?, isProfile: Bool)
|
||||
case removeColor
|
||||
case colorDescription(String)
|
||||
case backgroundEmojiHeader(String, String?)
|
||||
case backgroundEmoji(EmojiPagerContentComponent, UIColor)
|
||||
case backgroundEmoji(EmojiPagerContentComponent, UIColor, Bool, Bool)
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .colorHeader, .colorMessage, .colorPicker, .colorDescription:
|
||||
case .colorHeader, .colorMessage, .colorProfile, .colorPicker, .removeColor, .colorDescription:
|
||||
return PeerNameColorScreenSection.nameColor.rawValue
|
||||
case .backgroundEmojiHeader, .backgroundEmoji:
|
||||
return PeerNameColorScreenSection.backgroundEmoji.rawValue
|
||||
|
|
@ -67,8 +71,12 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
return .colorHeader
|
||||
case .colorMessage:
|
||||
return .colorMessage
|
||||
case .colorProfile:
|
||||
return .colorProfile
|
||||
case .colorPicker:
|
||||
return .colorPicker
|
||||
case .removeColor:
|
||||
return.removeColor
|
||||
case .colorDescription:
|
||||
return .colorDescription
|
||||
case .backgroundEmojiHeader:
|
||||
|
|
@ -84,14 +92,18 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
return 0
|
||||
case .colorMessage:
|
||||
return 1
|
||||
case .colorPicker:
|
||||
case .colorProfile:
|
||||
return 2
|
||||
case .colorDescription:
|
||||
case .colorPicker:
|
||||
return 3
|
||||
case .backgroundEmojiHeader:
|
||||
case .removeColor:
|
||||
return 4
|
||||
case .backgroundEmoji:
|
||||
case .colorDescription:
|
||||
return 5
|
||||
case .backgroundEmojiHeader:
|
||||
return 6
|
||||
case .backgroundEmoji:
|
||||
return 7
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,8 +121,26 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
case let .colorPicker(lhsColors, lhsCurrentColor):
|
||||
if case let .colorPicker(rhsColors, rhsCurrentColor) = rhs, lhsColors == rhsColors, lhsCurrentColor == rhsCurrentColor {
|
||||
case let .colorProfile(lhsPeer, lhsNameDisplayOrder):
|
||||
if case let .colorProfile(rhsPeer, rhsNameDisplayOrder) = rhs {
|
||||
if lhsPeer != rhsPeer {
|
||||
return false
|
||||
}
|
||||
if lhsNameDisplayOrder != rhsNameDisplayOrder {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .colorPicker(lhsColors, lhsCurrentColor, lhsIsProfile):
|
||||
if case let .colorPicker(rhsColors, rhsCurrentColor, rhsIsProfile) = rhs, lhsColors == rhsColors, lhsCurrentColor == rhsCurrentColor, lhsIsProfile == rhsIsProfile {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .removeColor:
|
||||
if case .removeColor = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
|
@ -127,8 +157,8 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
case let .backgroundEmoji(lhsEmojiContent, lhsBackgroundIconColor):
|
||||
if case let .backgroundEmoji(rhsEmojiContent, rhsBackgroundIconColor) = rhs, lhsEmojiContent == rhsEmojiContent, lhsBackgroundIconColor == rhsBackgroundIconColor {
|
||||
case let .backgroundEmoji(lhsEmojiContent, lhsBackgroundIconColor, lhsIsProfile, lhsHasRemoveButton):
|
||||
if case let .backgroundEmoji(rhsEmojiContent, rhsBackgroundIconColor, rhsIsProfile, rhsHasRemoveButton) = rhs, lhsEmojiContent == rhsEmojiContent, lhsBackgroundIconColor == rhsBackgroundIconColor, lhsIsProfile == rhsIsProfile, lhsHasRemoveButton == rhsHasRemoveButton {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
|
@ -157,25 +187,42 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||
wallpaper: wallpaper,
|
||||
dateTimeFormat: dateTimeFormat,
|
||||
nameDisplayOrder: nameDisplayOrder,
|
||||
messageItems: items)
|
||||
case let .colorPicker(colors, currentColor):
|
||||
messageItems: items
|
||||
)
|
||||
case let .colorProfile(peer, nameDisplayOrder):
|
||||
return PeerNameColorProfilePreviewItem(
|
||||
context: arguments.context,
|
||||
theme: presentationData.theme,
|
||||
componentTheme: presentationData.theme,
|
||||
strings: presentationData.strings,
|
||||
sectionId: self.section,
|
||||
peer: peer,
|
||||
nameDisplayOrder: nameDisplayOrder
|
||||
)
|
||||
case let .colorPicker(colors, currentColor, isProfile):
|
||||
return PeerNameColorItem(
|
||||
theme: presentationData.theme,
|
||||
colors: colors,
|
||||
isProfile: isProfile,
|
||||
currentColor: currentColor,
|
||||
updated: { color in
|
||||
arguments.updateNameColor(color)
|
||||
},
|
||||
sectionId: self.section
|
||||
)
|
||||
case .removeColor:
|
||||
//TODO:localize
|
||||
return ItemListActionItem(presentationData: presentationData, title: "Reset Profile Color", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.updateNameColor(nil)
|
||||
})
|
||||
case let .colorDescription(text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .backgroundEmojiHeader(text, action):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, actionText: action, action: action != nil ? {
|
||||
arguments.updateBackgroundEmojiId(0)
|
||||
} : nil, sectionId: self.section)
|
||||
case let .backgroundEmoji(emojiContent, backgroundIconColor):
|
||||
return EmojiPickerItem(context: arguments.context, theme: presentationData.theme, strings: presentationData.strings, emojiContent: emojiContent, backgroundIconColor: backgroundIconColor, sectionId: self.section)
|
||||
case let .backgroundEmoji(emojiContent, backgroundIconColor, isProfileColor, hasRemoveButton):
|
||||
return EmojiPickerItem(context: arguments.context, theme: presentationData.theme, strings: presentationData.strings, emojiContent: emojiContent, backgroundIconColor: backgroundIconColor, isProfileColor: isProfileColor, hasRemoveButton: hasRemoveButton, sectionId: self.section)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -185,6 +232,13 @@ private struct PeerNameColorScreenState: Equatable {
|
|||
var updatedBackgroundEmojiId: Int64?
|
||||
var inProgress: Bool = false
|
||||
var needsBoosts: Bool = false
|
||||
|
||||
var updatedProfileColor: PeerNameColor?
|
||||
var hasUpdatedProfileColor: Bool = false
|
||||
var updatedProfileBackgroundEmojiId: Int64?
|
||||
var hasUpdatedProfileBackgroundEmojiId: Bool = false
|
||||
|
||||
var selectedTabIndex: Int = 0
|
||||
}
|
||||
|
||||
private func peerNameColorScreenEntries(
|
||||
|
|
@ -222,6 +276,20 @@ private func peerNameColorScreenEntries(
|
|||
backgroundEmojiId = nil
|
||||
}
|
||||
|
||||
let profileColor: PeerNameColor?
|
||||
if state.hasUpdatedProfileColor {
|
||||
profileColor = state.updatedProfileColor
|
||||
} else {
|
||||
profileColor = peer.profileColor
|
||||
}
|
||||
var selectedProfileEmojiId: Int64?
|
||||
if state.hasUpdatedProfileBackgroundEmojiId {
|
||||
selectedProfileEmojiId = state.updatedProfileBackgroundEmojiId
|
||||
} else {
|
||||
selectedProfileEmojiId = peer.profileBackgroundEmojiId
|
||||
}
|
||||
let profileColors = profileColor.flatMap { profileColor in nameColors.getProfile(profileColor, dark: presentationData.theme.overallDarkAppearance) }
|
||||
|
||||
let replyText: String
|
||||
let messageText: String
|
||||
if case .channel = peer {
|
||||
|
|
@ -242,27 +310,83 @@ private func peerNameColorScreenEntries(
|
|||
linkPreview: (presentationData.strings.NameColor_ChatPreview_LinkSite, presentationData.strings.NameColor_ChatPreview_LinkTitle, presentationData.strings.NameColor_ChatPreview_LinkText),
|
||||
text: messageText
|
||||
)
|
||||
entries.append(.colorMessage(
|
||||
wallpaper: presentationData.chatWallpaper,
|
||||
fontSize: presentationData.chatFontSize,
|
||||
bubbleCorners: presentationData.chatBubbleCorners,
|
||||
dateTimeFormat: presentationData.dateTimeFormat,
|
||||
nameDisplayOrder: presentationData.nameDisplayOrder,
|
||||
items: [messageItem]
|
||||
))
|
||||
entries.append(.colorPicker(
|
||||
colors: nameColors,
|
||||
currentColor: nameColor
|
||||
))
|
||||
if case .channel = peer {
|
||||
entries.append(.colorDescription(presentationData.strings.NameColor_ChatPreview_Description_Channel))
|
||||
if state.selectedTabIndex == 0 {
|
||||
entries.append(.colorMessage(
|
||||
wallpaper: presentationData.chatWallpaper,
|
||||
fontSize: presentationData.chatFontSize,
|
||||
bubbleCorners: presentationData.chatBubbleCorners,
|
||||
dateTimeFormat: presentationData.dateTimeFormat,
|
||||
nameDisplayOrder: presentationData.nameDisplayOrder,
|
||||
items: [messageItem]
|
||||
))
|
||||
} else {
|
||||
entries.append(.colorDescription(presentationData.strings.NameColor_ChatPreview_Description_Account))
|
||||
var updatedPeer = peer
|
||||
switch updatedPeer {
|
||||
case let .user(user):
|
||||
updatedPeer = .user(user.withUpdatedNameColor(nameColor).withUpdatedBackgroundEmojiId(backgroundEmojiId).withUpdatedProfileColor(profileColor).withUpdatedProfileBackgroundEmojiId(selectedProfileEmojiId))
|
||||
case let .channel(channel):
|
||||
updatedPeer = .channel(channel.withUpdatedNameColor(nameColor).withUpdatedBackgroundEmojiId(backgroundEmojiId).withUpdatedProfileColor(profileColor).withUpdatedProfileBackgroundEmojiId(selectedProfileEmojiId))
|
||||
default:
|
||||
break
|
||||
}
|
||||
entries.append(.colorProfile(
|
||||
peer: updatedPeer,
|
||||
nameDisplayOrder: presentationData.nameDisplayOrder
|
||||
))
|
||||
}
|
||||
if state.selectedTabIndex == 0 {
|
||||
entries.append(.colorPicker(
|
||||
colors: nameColors,
|
||||
currentColor: nameColor,
|
||||
isProfile: false
|
||||
))
|
||||
} else {
|
||||
entries.append(.colorPicker(
|
||||
colors: nameColors,
|
||||
currentColor: profileColor,
|
||||
isProfile: true
|
||||
))
|
||||
}
|
||||
if state.selectedTabIndex == 1 && profileColor != nil {
|
||||
entries.append(.removeColor)
|
||||
}
|
||||
|
||||
if let emojiContent {
|
||||
entries.append(.backgroundEmojiHeader(presentationData.strings.NameColor_BackgroundEmoji_Title, backgroundEmojiId != nil ? presentationData.strings.NameColor_BackgroundEmoji_Remove : nil))
|
||||
entries.append(.backgroundEmoji(emojiContent, colors.main))
|
||||
if state.selectedTabIndex == 0 {
|
||||
if case .channel = peer {
|
||||
entries.append(.colorDescription(presentationData.strings.NameColor_ChatPreview_Description_Channel))
|
||||
} else {
|
||||
entries.append(.colorDescription(presentationData.strings.NameColor_ChatPreview_Description_Account))
|
||||
}
|
||||
|
||||
if let emojiContent {
|
||||
var selectedItems = Set<MediaId>()
|
||||
if let backgroundEmojiId {
|
||||
selectedItems.insert(MediaId(namespace: Namespaces.Media.CloudFile, id: backgroundEmojiId))
|
||||
}
|
||||
let emojiContent = emojiContent.withSelectedItems(selectedItems).withCustomTintColor(colors.main)
|
||||
|
||||
entries.append(.backgroundEmojiHeader(presentationData.strings.NameColor_BackgroundEmoji_Title, (backgroundEmojiId != nil && backgroundEmojiId != 0) ? presentationData.strings.NameColor_BackgroundEmoji_Remove : nil))
|
||||
entries.append(.backgroundEmoji(emojiContent, colors.main, false, false))
|
||||
}
|
||||
} else {
|
||||
if let emojiContent, profileColors != nil {
|
||||
var selectedItems = Set<MediaId>()
|
||||
if let selectedProfileEmojiId {
|
||||
selectedItems.insert(MediaId(namespace: Namespaces.Media.CloudFile, id: selectedProfileEmojiId))
|
||||
}
|
||||
let emojiContent = emojiContent.withSelectedItems(selectedItems).withCustomTintColor(profileColors?.main)
|
||||
|
||||
//TODO:localize
|
||||
entries.append(.backgroundEmojiHeader("ADD ICON TO PROFILE", (selectedProfileEmojiId != nil && selectedProfileEmojiId != 0) ? presentationData.strings.NameColor_BackgroundEmoji_Remove : nil))
|
||||
entries.append(.backgroundEmoji(emojiContent, profileColors?.main ?? presentationData.theme.list.itemSecondaryTextColor, true, profileColor != nil))
|
||||
} else {
|
||||
//TODO:localize
|
||||
if case .channel = peer {
|
||||
entries.append(.colorDescription("Choose a color for channel's profile"))
|
||||
} else {
|
||||
entries.append(.colorDescription("Choose a color for your profile"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -300,14 +424,27 @@ public func PeerNameColorScreen(
|
|||
updateNameColor: { color in
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.updatedNameColor = color
|
||||
|
||||
if state.selectedTabIndex == 0 {
|
||||
if let color {
|
||||
updatedState.updatedNameColor = color
|
||||
}
|
||||
} else {
|
||||
updatedState.updatedProfileColor = color
|
||||
updatedState.hasUpdatedProfileColor = true
|
||||
}
|
||||
return updatedState
|
||||
}
|
||||
},
|
||||
updateBackgroundEmojiId: { emojiId in
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.updatedBackgroundEmojiId = emojiId
|
||||
if state.selectedTabIndex == 0 {
|
||||
updatedState.updatedBackgroundEmojiId = emojiId
|
||||
} else {
|
||||
updatedState.hasUpdatedProfileBackgroundEmojiId = true
|
||||
updatedState.updatedProfileBackgroundEmojiId = emojiId
|
||||
}
|
||||
return updatedState
|
||||
}
|
||||
}
|
||||
|
|
@ -321,12 +458,24 @@ public func PeerNameColorScreen(
|
|||
peerId = channelId
|
||||
}
|
||||
|
||||
let emojiContent = combineLatest(
|
||||
context.sharedContext.presentationData,
|
||||
statePromise.get(),
|
||||
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
let emojiContent = EmojiPagerContentComponent.emojiInputData(
|
||||
context: context,
|
||||
animationCache: context.animationCache,
|
||||
animationRenderer: context.animationRenderer,
|
||||
isStandalone: false,
|
||||
subject: .backgroundIcon,
|
||||
hasTrending: false,
|
||||
topReactionItems: [],
|
||||
areUnicodeEmojiEnabled: false,
|
||||
areCustomEmojiEnabled: true,
|
||||
chatPeerId: context.account.peerId,
|
||||
selectedItems: Set(),
|
||||
backgroundIconColor: nil
|
||||
)
|
||||
|> mapToSignal { presentationData, state, peer -> Signal<EmojiPagerContentComponent, NoError> in
|
||||
/*let emojiContent: Signal<EmojiPagerContentComponent, NoError> = combineLatest(
|
||||
context.sharedContext.presentationData
|
||||
)
|
||||
|> mapToSignal { presentationData, state, peer -> Signal<(EmojiPagerContentComponent, EmojiPagerContentComponent), NoError> in
|
||||
var selectedEmojiId: Int64?
|
||||
if let updatedBackgroundEmojiId = state.updatedBackgroundEmojiId {
|
||||
selectedEmojiId = updatedBackgroundEmojiId
|
||||
|
|
@ -339,7 +488,22 @@ public func PeerNameColorScreen(
|
|||
} else {
|
||||
nameColor = (peer?.nameColor ?? .blue)
|
||||
}
|
||||
|
||||
var selectedProfileEmojiId: Int64?
|
||||
if state.hasUpdatedProfileBackgroundEmojiId {
|
||||
selectedProfileEmojiId = state.updatedProfileBackgroundEmojiId
|
||||
} else {
|
||||
selectedProfileEmojiId = peer?.profileBackgroundEmojiId
|
||||
}
|
||||
let profileColor: PeerNameColor?
|
||||
if state.hasUpdatedProfileColor {
|
||||
profileColor = state.updatedProfileColor
|
||||
} else {
|
||||
profileColor = peer?.profileColor
|
||||
}
|
||||
|
||||
let color = context.peerNameColors.get(nameColor, dark: presentationData.theme.overallDarkAppearance)
|
||||
let profileColorValue: UIColor? = profileColor.flatMap { profileColor in context.peerNameColors.getProfile(profileColor, dark: presentationData.theme.overallDarkAppearance).main }
|
||||
|
||||
let selectedItems: [EngineMedia.Id]
|
||||
if let selectedEmojiId, selectedEmojiId != 0 {
|
||||
|
|
@ -348,21 +512,13 @@ public func PeerNameColorScreen(
|
|||
selectedItems = []
|
||||
}
|
||||
|
||||
return EmojiPagerContentComponent.emojiInputData(
|
||||
context: context,
|
||||
animationCache: context.animationCache,
|
||||
animationRenderer: context.animationRenderer,
|
||||
isStandalone: false,
|
||||
subject: .backgroundIcon,
|
||||
hasTrending: false,
|
||||
topReactionItems: [],
|
||||
areUnicodeEmojiEnabled: false,
|
||||
areCustomEmojiEnabled: true,
|
||||
chatPeerId: context.account.peerId,
|
||||
selectedItems: Set(selectedItems),
|
||||
backgroundIconColor: color.main
|
||||
)
|
||||
}
|
||||
let selectedProfileItems: [EngineMedia.Id]
|
||||
if let selectedProfileEmojiId, selectedProfileEmojiId != 0 {
|
||||
selectedProfileItems = [EngineMedia.Id(namespace: Namespaces.Media.CloudFile, id: selectedProfileEmojiId)]
|
||||
} else {
|
||||
selectedProfileItems = []
|
||||
}
|
||||
}*/
|
||||
|
||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
||||
let signal = combineLatest(queue: .mainQueue(),
|
||||
|
|
@ -375,17 +531,15 @@ public func PeerNameColorScreen(
|
|||
|> deliverOnMainQueue
|
||||
|> map { presentationData, state, availableReactions, peer, emojiContent -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let isPremium = peer?.isPremium ?? false
|
||||
let title: String
|
||||
let buttonTitle: String
|
||||
let isLocked: Bool
|
||||
switch subject {
|
||||
case .account:
|
||||
title = presentationData.strings.NameColor_Title_Account
|
||||
isLocked = !isPremium
|
||||
case .channel:
|
||||
title = presentationData.strings.NameColor_Title_Channel
|
||||
isLocked = false
|
||||
}
|
||||
let _ = isLocked
|
||||
|
||||
let backgroundEmojiId: Int64
|
||||
if let updatedBackgroundEmojiId = state.updatedBackgroundEmojiId {
|
||||
|
|
@ -400,8 +554,9 @@ public func PeerNameColorScreen(
|
|||
} else {
|
||||
buttonTitle = presentationData.strings.NameColor_ApplyColor
|
||||
}
|
||||
let _ = buttonTitle
|
||||
|
||||
let footerItem = ApplyColorFooterItem(
|
||||
/*let footerItem = ApplyColorFooterItem(
|
||||
theme: presentationData.theme,
|
||||
title: buttonTitle,
|
||||
locked: isLocked,
|
||||
|
|
@ -432,7 +587,7 @@ public func PeerNameColorScreen(
|
|||
presentImpl?(controller)
|
||||
}
|
||||
}
|
||||
)
|
||||
)*/
|
||||
|
||||
emojiContent.inputInteractionHolder.inputInteraction = EmojiPagerContentComponent.InputInteraction(
|
||||
performItemAction: { _, item, _, _, _, _ in
|
||||
|
|
@ -512,11 +667,37 @@ public func PeerNameColorScreen(
|
|||
emojiContent: emojiContent
|
||||
)
|
||||
|
||||
//TODO:localize
|
||||
let controllerState = ItemListControllerState(
|
||||
presentationData: ItemListPresentationData(presentationData),
|
||||
title: .text(title),
|
||||
title: .sectionControl(["Name", "Profile"], state.selectedTabIndex),
|
||||
leftNavigationButton: nil,
|
||||
rightNavigationButton: nil,
|
||||
rightNavigationButton: ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||
if !isLocked {
|
||||
applyChangesImpl?()
|
||||
} else {
|
||||
HapticFeedback().impact(.light)
|
||||
let controller = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .premiumPaywall(
|
||||
title: nil,
|
||||
text: presentationData.strings.NameColor_TooltipPremium_Account,
|
||||
customUndoText: nil,
|
||||
timeout: nil,
|
||||
linkAction: nil
|
||||
),
|
||||
elevatedLayout: false,
|
||||
action: { action in
|
||||
if case .info = action {
|
||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .nameColor, forceDark: false, dismissed: nil)
|
||||
pushImpl?(controller)
|
||||
}
|
||||
return true
|
||||
}
|
||||
)
|
||||
presentImpl?(controller)
|
||||
}
|
||||
}),
|
||||
backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back),
|
||||
animateChanges: false
|
||||
)
|
||||
|
|
@ -524,7 +705,7 @@ public func PeerNameColorScreen(
|
|||
presentationData: ItemListPresentationData(presentationData),
|
||||
entries: entries,
|
||||
style: .blocks,
|
||||
footerItem: footerItem,
|
||||
footerItem: nil,
|
||||
animateChanges: false
|
||||
)
|
||||
|
||||
|
|
@ -536,6 +717,13 @@ public func PeerNameColorScreen(
|
|||
|
||||
let controller = ItemListController(context: context, state: signal)
|
||||
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
controller.titleControlValueChanged = { value in
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.selectedTabIndex = value
|
||||
return state
|
||||
}
|
||||
}
|
||||
presentImpl = { [weak controller] c in
|
||||
guard let controller else {
|
||||
return
|
||||
|
|
@ -596,7 +784,7 @@ public func PeerNameColorScreen(
|
|||
return
|
||||
}
|
||||
let state = stateValue.with { $0 }
|
||||
if state.updatedNameColor == nil && state.updatedBackgroundEmojiId == nil {
|
||||
if state.updatedNameColor == nil && state.updatedBackgroundEmojiId == nil && !state.hasUpdatedProfileColor && !state.hasUpdatedProfileBackgroundEmojiId {
|
||||
dismissImpl?()
|
||||
return
|
||||
}
|
||||
|
|
@ -607,9 +795,12 @@ public func PeerNameColorScreen(
|
|||
let backgroundEmojiId = state.updatedBackgroundEmojiId ?? peer.backgroundEmojiId
|
||||
let colors = context.peerNameColors.get(nameColor ?? .blue, dark: presentationData.theme.overallDarkAppearance)
|
||||
|
||||
let profileColor = state.hasUpdatedProfileColor ? state.updatedProfileColor : peer.profileColor
|
||||
let profileBackgroundEmojiId = state.hasUpdatedProfileBackgroundEmojiId ? state.updatedProfileBackgroundEmojiId : peer.profileBackgroundEmojiId
|
||||
|
||||
switch subject {
|
||||
case .account:
|
||||
let _ = context.engine.accountData.updateNameColorAndEmoji(nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0).startStandalone()
|
||||
let _ = context.engine.accountData.updateNameColorAndEmoji(nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0, profileColor: profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId ?? 0).startStandalone()
|
||||
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
Queue.mainQueue().after(0.25) {
|
||||
|
|
@ -627,7 +818,7 @@ public func PeerNameColorScreen(
|
|||
updatedState.inProgress = true
|
||||
return updatedState
|
||||
}
|
||||
let _ = (context.engine.peers.updatePeerNameColorAndEmoji(peerId: peerId, nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0)
|
||||
let _ = (context.engine.peers.updatePeerNameColorAndEmoji(peerId: peerId, nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0, profileColor: profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId ?? 0)
|
||||
|> deliverOnMainQueue).startStandalone(next: {
|
||||
}, error: { error in
|
||||
if case .channelBoostRequired = error {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import UndoUI
|
||||
|
||||
|
|
@ -19,9 +19,11 @@ public final class TabSelectorComponent: Component {
|
|||
}
|
||||
|
||||
public struct CustomLayout: Equatable {
|
||||
public var font: UIFont
|
||||
public var spacing: CGFloat
|
||||
|
||||
public init(spacing: CGFloat) {
|
||||
public init(font: UIFont, spacing: CGFloat) {
|
||||
self.font = font
|
||||
self.spacing = spacing
|
||||
}
|
||||
}
|
||||
|
|
@ -113,8 +115,8 @@ public final class TabSelectorComponent: Component {
|
|||
let spacing: CGFloat = component.customLayout?.spacing ?? 2.0
|
||||
|
||||
let itemFont: UIFont
|
||||
if component.customLayout != nil {
|
||||
itemFont = Font.medium(14.0)
|
||||
if let customLayout = component.customLayout {
|
||||
itemFont = customLayout.font
|
||||
} else {
|
||||
itemFont = Font.semibold(14.0)
|
||||
}
|
||||
|
|
|
|||
3
submodules/TelegramUI/Images.xcassets/Navigation/BackArrow.imageset/BackArrow.svg
vendored
Normal file
3
submodules/TelegramUI/Images.xcassets/Navigation/BackArrow.imageset/BackArrow.svg
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="9" height="16" viewBox="0 0 9 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 1L1 8L8 15" stroke="black" stroke-width="1.66" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 209 B |
12
submodules/TelegramUI/Images.xcassets/Navigation/BackArrow.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Navigation/BackArrow.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "BackArrow.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"provides-namespace" : true
|
||||
}
|
||||
}
|
||||
|
|
@ -348,6 +348,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
UIDevice.current.isBatteryMonitoringEnabled = true
|
||||
}
|
||||
|
||||
|
||||
let clearNotificationsManager = ClearNotificationsManager(getNotificationIds: { completion in
|
||||
if #available(iOS 10.0, *) {
|
||||
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { notifications in
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ private func pollResultsControllerEntries(presentationData: PresentationData, po
|
|||
displayCount = Int(voterCount)
|
||||
}
|
||||
for peerIndex in 0 ..< displayCount {
|
||||
let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil)
|
||||
let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
|
||||
let peer = EngineRenderedPeer(peer: EnginePeer(fakeUser))
|
||||
entries.append(.optionPeer(optionId: i, index: peerIndex, peer: peer, optionText: optionTextHeader, optionAdditionalText: optionAdditionalTextHeader, optionCount: voterCount, optionExpanded: false, opaqueIdentifier: option.opaqueIdentifier, shimmeringAlternation: peerIndex % 2, isFirstInOption: peerIndex == 0))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue