mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 00:21:12 +00:00
ChatListNode: improved archive handling
ItemListEditableNode: improved swipe actions
This commit is contained in:
parent
61c1d8d350
commit
6b8adfc5b0
@ -316,15 +316,10 @@ public final class AvatarNode: ASDisplayNode {
|
||||
|
||||
let colorIndex: Int
|
||||
if let parameters = parameters as? AvatarNodeParameters {
|
||||
if case .archivedChatsIcon = parameters.icon {
|
||||
let path = UIBezierPath(roundedRect: bounds, cornerRadius: floor(bounds.width / 3.8))
|
||||
path.addClip()
|
||||
} else {
|
||||
context.beginPath()
|
||||
context.addEllipse(in: CGRect(x: 0.0, y: 0.0, width: bounds.size.width, height:
|
||||
bounds.size.height))
|
||||
context.clip()
|
||||
}
|
||||
context.beginPath()
|
||||
context.addEllipse(in: CGRect(x: 0.0, y: 0.0, width: bounds.size.width, height:
|
||||
bounds.size.height))
|
||||
context.clip()
|
||||
|
||||
if let explicitColorIndex = parameters.explicitColorIndex {
|
||||
colorIndex = explicitColorIndex
|
||||
@ -349,8 +344,8 @@ public final class AvatarNode: ASDisplayNode {
|
||||
colorsArray = savedMessagesColors
|
||||
} else if case .editAvatarIcon = parameters.icon, let theme = parameters.theme {
|
||||
colorsArray = [theme.list.blocksBackgroundColor.cgColor, theme.list.blocksBackgroundColor.cgColor]
|
||||
} else if case .archivedChatsIcon = parameters.icon {
|
||||
let color = UIColor(rgb: 0x4ac058)
|
||||
} else if case .archivedChatsIcon = parameters.icon, let theme = parameters.theme {
|
||||
let color = theme.chatList.neutralAvatarColor
|
||||
colorsArray = [color.cgColor, color.cgColor]
|
||||
} else {
|
||||
colorsArray = grayscaleColors
|
||||
|
@ -1981,6 +1981,15 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
||||
return chatLocationInfoReady
|
||||
})
|
||||
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.crashOnLongQueries {
|
||||
let _ = (self.ready.get()
|
||||
|> filter({ $0 })
|
||||
|> take(1)
|
||||
|> timeout(0.8, queue: .concurrentDefaultQueue(), alternate: Signal { _ in
|
||||
preconditionFailure()
|
||||
})).start()
|
||||
}
|
||||
|
||||
self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in
|
||||
if let strongSelf = self {
|
||||
let offsetAlpha: CGFloat
|
||||
|
@ -13,10 +13,10 @@ private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBa
|
||||
let scrollToItem: ListViewScrollToItem
|
||||
let targetProgress: CGFloat
|
||||
if searchNode.expansionProgress < 0.6 {
|
||||
scrollToItem = ListViewScrollToItem(index: 1, position: .top(-navigationBarSearchContentHeight), animated: true, curve: .Default(duration: 0.3), directionHint: .Up)
|
||||
scrollToItem = ListViewScrollToItem(index: 0, position: .top(-navigationBarSearchContentHeight), animated: true, curve: .Default(duration: 0.3), directionHint: .Up)
|
||||
targetProgress = 0.0
|
||||
} else {
|
||||
scrollToItem = ListViewScrollToItem(index: 1, position: .top(0.0), animated: true, curve: .Default(duration: 0.3), directionHint: .Up)
|
||||
scrollToItem = ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: 0.3), directionHint: .Up)
|
||||
targetProgress = 1.0
|
||||
}
|
||||
searchNode.updateExpansionProgress(targetProgress, animated: true)
|
||||
@ -35,7 +35,7 @@ private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBa
|
||||
}
|
||||
})
|
||||
|
||||
if let sortItemNode = sortItemNode {
|
||||
if false, let sortItemNode = sortItemNode {
|
||||
let itemFrame = sortItemNode.apparentFrame
|
||||
if itemFrame.contains(CGPoint(x: 0.0, y: listNode.insets.top)) {
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
@ -744,13 +744,13 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
|
||||
}
|
||||
}*/
|
||||
|
||||
/*self.chatListDisplayNode.chatListNode.contentScrollingEnded = { [weak self] listView in
|
||||
self.chatListDisplayNode.chatListNode.contentScrollingEnded = { [weak self] listView in
|
||||
if let strongSelf = self, let searchContentNode = strongSelf.searchContentNode {
|
||||
return fixListNodeScrolling(listView, searchNode: searchContentNode)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
self.chatListDisplayNode.toolbarActionSelected = { [weak self] left in
|
||||
self?.toolbarActionSelected(left: left)
|
||||
|
@ -133,6 +133,47 @@ final class ChatListControllerNode: ASDisplayNode {
|
||||
insets.left += layout.safeInsets.left
|
||||
insets.right += layout.safeInsets.right
|
||||
|
||||
if let toolbar = self.toolbar {
|
||||
var tabBarHeight: CGFloat
|
||||
var options: ContainerViewLayoutInsetOptions = []
|
||||
if layout.metrics.widthClass == .regular {
|
||||
options.insert(.input)
|
||||
}
|
||||
let bottomInset: CGFloat = layout.insets(options: options).bottom
|
||||
if !layout.safeInsets.left.isZero {
|
||||
tabBarHeight = 34.0 + bottomInset
|
||||
insets.bottom += 34.0
|
||||
} else {
|
||||
tabBarHeight = 49.0 + bottomInset
|
||||
insets.bottom += 49.0
|
||||
}
|
||||
|
||||
let tabBarFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - tabBarHeight), size: CGSize(width: layout.size.width, height: tabBarHeight))
|
||||
|
||||
if let toolbarNode = self.toolbarNode {
|
||||
transition.updateFrame(node: toolbarNode, frame: tabBarFrame)
|
||||
toolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: bottomInset, toolbar: toolbar, transition: transition)
|
||||
} else {
|
||||
let toolbarNode = ToolbarNode(theme: TabBarControllerTheme(rootControllerTheme: self.presentationData.theme), displaySeparator: true, left: { [weak self] in
|
||||
self?.toolbarActionSelected?(true)
|
||||
}, right: { [weak self] in
|
||||
self?.toolbarActionSelected?(false)
|
||||
})
|
||||
toolbarNode.frame = tabBarFrame
|
||||
toolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: bottomInset, toolbar: toolbar, transition: .immediate)
|
||||
self.addSubnode(toolbarNode)
|
||||
self.toolbarNode = toolbarNode
|
||||
if transition.isAnimated {
|
||||
toolbarNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
} else if let toolbarNode = self.toolbarNode {
|
||||
self.toolbarNode = nil
|
||||
transition.updateAlpha(node: toolbarNode, alpha: 0.0, completion: { [weak toolbarNode] _ in
|
||||
toolbarNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
|
||||
self.chatListNode.bounds = CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height)
|
||||
self.chatListNode.position = CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0)
|
||||
|
||||
@ -177,45 +218,6 @@ final class ChatListControllerNode: ASDisplayNode {
|
||||
if let searchDisplayController = self.searchDisplayController {
|
||||
searchDisplayController.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition)
|
||||
}
|
||||
|
||||
if let toolbar = self.toolbar {
|
||||
var tabBarHeight: CGFloat
|
||||
var options: ContainerViewLayoutInsetOptions = []
|
||||
if layout.metrics.widthClass == .regular {
|
||||
options.insert(.input)
|
||||
}
|
||||
let bottomInset: CGFloat = layout.insets(options: options).bottom
|
||||
if !layout.safeInsets.left.isZero {
|
||||
tabBarHeight = 34.0 + bottomInset
|
||||
} else {
|
||||
tabBarHeight = 49.0 + bottomInset
|
||||
}
|
||||
|
||||
let tabBarFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - tabBarHeight), size: CGSize(width: layout.size.width, height: tabBarHeight))
|
||||
|
||||
if let toolbarNode = self.toolbarNode {
|
||||
transition.updateFrame(node: toolbarNode, frame: tabBarFrame)
|
||||
toolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: bottomInset, toolbar: toolbar, transition: transition)
|
||||
} else {
|
||||
let toolbarNode = ToolbarNode(theme: TabBarControllerTheme(rootControllerTheme: self.presentationData.theme), displaySeparator: true, left: { [weak self] in
|
||||
self?.toolbarActionSelected?(true)
|
||||
}, right: { [weak self] in
|
||||
self?.toolbarActionSelected?(false)
|
||||
})
|
||||
toolbarNode.frame = tabBarFrame
|
||||
toolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: bottomInset, toolbar: toolbar, transition: .immediate)
|
||||
self.addSubnode(toolbarNode)
|
||||
self.toolbarNode = toolbarNode
|
||||
if transition.isAnimated {
|
||||
toolbarNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
} else if let toolbarNode = self.toolbarNode {
|
||||
self.toolbarNode = nil
|
||||
transition.updateAlpha(node: toolbarNode, alpha: 0.0, completion: { [weak toolbarNode] _ in
|
||||
toolbarNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func activateSearch(placeholderNode: SearchBarPlaceholderNode) {
|
||||
|
@ -35,6 +35,10 @@ class ChatListItem: ListViewItem {
|
||||
|
||||
let selectable: Bool = true
|
||||
|
||||
var approximateHeight: CGFloat {
|
||||
return self.hiddenOffset ? 0.0 : 44.0
|
||||
}
|
||||
|
||||
let header: ListViewItemHeader?
|
||||
|
||||
init(presentationData: ChatListPresentationData, account: Account, peerGroupId: PeerGroupId?, index: ChatListIndex, content: ChatListItemContent, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, header: ListViewItemHeader?, enableContextActions: Bool, hiddenOffset: Bool, interaction: ChatListNodeInteraction) {
|
||||
@ -837,7 +841,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
var layoutOffset: CGFloat = 0.0
|
||||
if item.hiddenOffset {
|
||||
layoutOffset = -itemHeight
|
||||
//layoutOffset = -itemHeight
|
||||
}
|
||||
|
||||
let rawContentRect = CGRect(origin: CGPoint(x: 2.0, y: layoutOffset + 8.0), size: CGSize(width: params.width - leftInset - params.rightInset - 10.0 - 1.0 - editingOffset, height: itemHeight - 12.0 - 9.0))
|
||||
@ -918,11 +922,18 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
|
||||
let insets = ChatListItemNode.insets(first: first, last: last, firstWithHeader: firstWithHeader)
|
||||
let layout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: max(0.0, itemHeight + layoutOffset)), insets: insets)
|
||||
var heightOffset: CGFloat = 0.0
|
||||
if item.hiddenOffset {
|
||||
heightOffset = -itemHeight
|
||||
}
|
||||
let layout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: max(0.0, itemHeight + heightOffset)), insets: insets)
|
||||
|
||||
return (layout, { [weak self] synchronousLoads, animated in
|
||||
if let strongSelf = self {
|
||||
strongSelf.layoutParams = (item, first, last, firstWithHeader, nextIsPinned, params)
|
||||
if true || !animated {
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, layout.contentSize.height - itemHeight, 0.0)
|
||||
}
|
||||
|
||||
if let _ = updatedTheme {
|
||||
strongSelf.separatorNode.backgroundColor = item.presentationData.theme.chatList.itemSeparatorColor
|
||||
@ -1049,21 +1060,10 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
let previousBadgeFrame = strongSelf.badgeNode.frame
|
||||
let badgeFrame = CGRect(x: contentRect.maxX - badgeLayout.width, y: contentRect.maxY - badgeLayout.height - 2.0, width: badgeLayout.width, height: badgeLayout.height)
|
||||
|
||||
if !previousBadgeFrame.width.isZero && !badgeFrame.width.isZero && badgeFrame != previousBadgeFrame {
|
||||
if animateContent {
|
||||
strongSelf.badgeNode.frame = badgeFrame
|
||||
strongSelf.badgeNode.layer.animateFrame(from: previousBadgeFrame, to: badgeFrame, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut)
|
||||
} else {
|
||||
transition.updateFrame(node: strongSelf.badgeNode, frame: badgeFrame)
|
||||
}
|
||||
} else {
|
||||
strongSelf.badgeNode.frame = badgeFrame
|
||||
}
|
||||
transition.updateFrame(node: strongSelf.badgeNode, frame: badgeFrame)
|
||||
}
|
||||
|
||||
if currentMentionBadgeImage != nil || currentBadgeBackgroundImage != nil {
|
||||
let previousBadgeFrame = strongSelf.mentionBadgeNode.frame
|
||||
|
||||
let mentionBadgeOffset: CGFloat
|
||||
if badgeLayout.width.isZero {
|
||||
mentionBadgeOffset = contentRect.maxX - mentionBadgeLayout.width
|
||||
@ -1072,13 +1072,8 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
|
||||
let badgeFrame = CGRect(x: mentionBadgeOffset, y: contentRect.maxY - mentionBadgeLayout.height - 2.0, width: mentionBadgeLayout.width, height: mentionBadgeLayout.height)
|
||||
strongSelf.mentionBadgeNode.position = badgeFrame.center
|
||||
strongSelf.mentionBadgeNode.bounds = CGRect(origin: CGPoint(), size: badgeFrame.size)
|
||||
|
||||
if animateContent && !previousBadgeFrame.width.isZero && !badgeFrame.width.isZero && badgeFrame != previousBadgeFrame {
|
||||
strongSelf.mentionBadgeNode.layer.animatePosition(from: previousBadgeFrame.center, to: badgeFrame.center, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut)
|
||||
strongSelf.mentionBadgeNode.layer.animateBounds(from: CGRect(origin: CGPoint(), size: previousBadgeFrame.size), to: CGRect(origin: CGPoint(), size: badgeFrame.size), duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut)
|
||||
}
|
||||
transition.updateFrame(node: strongSelf.mentionBadgeNode, frame: badgeFrame)
|
||||
}
|
||||
|
||||
if let currentPinnedIconImage = currentPinnedIconImage {
|
||||
@ -1219,7 +1214,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
|
||||
let separatorInset: CGFloat
|
||||
if (!nextIsPinned && item.index.pinningIndex != nil) || last || groupHiddenByDefault {
|
||||
if (!nextIsPinned && item.index.pinningIndex != nil) || last {
|
||||
separatorInset = 0.0
|
||||
} else {
|
||||
separatorInset = editingOffset + leftInset + rawContentRect.origin.x
|
||||
@ -1227,7 +1222,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
transition.updateFrame(node: strongSelf.separatorNode, frame: CGRect(origin: CGPoint(x: separatorInset, y: layoutOffset + itemHeight - separatorHeight), size: CGSize(width: params.width - separatorInset, height: separatorHeight)))
|
||||
|
||||
transition.updateFrame(node: strongSelf.backgroundNode, frame: CGRect(origin: CGPoint(), size: layout.contentSize))
|
||||
transition.updateFrame(node: strongSelf.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: itemHeight)))
|
||||
if item.selected {
|
||||
strongSelf.backgroundNode.backgroundColor = theme.itemSelectedBackgroundColor
|
||||
} else if item.index.pinningIndex != nil {
|
||||
@ -1291,7 +1286,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
var layoutOffset: CGFloat = 0.0
|
||||
if item.hiddenOffset {
|
||||
layoutOffset = -itemHeight
|
||||
//layoutOffset = -itemHeight
|
||||
}
|
||||
|
||||
if let reorderControlNode = self.reorderControlNode {
|
||||
@ -1356,7 +1351,11 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
transition.updateFrame(node: self.badgeNode, frame: updatedBadgeFrame)
|
||||
|
||||
var mentionBadgeFrame = self.mentionBadgeNode.frame
|
||||
mentionBadgeFrame.origin.x = updatedBadgeFrame.minX - 6.0 - mentionBadgeFrame.width
|
||||
if updatedBadgeFrame.width.isZero {
|
||||
mentionBadgeFrame.origin.x = updatedBadgeFrame.minX - mentionBadgeFrame.width
|
||||
} else {
|
||||
mentionBadgeFrame.origin.x = updatedBadgeFrame.minX - 6.0 - mentionBadgeFrame.width
|
||||
}
|
||||
transition.updateFrame(node: self.mentionBadgeNode, frame: mentionBadgeFrame)
|
||||
|
||||
let pinnedIconSize = self.pinnedIconNode.bounds.size
|
||||
@ -1431,6 +1430,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
close = false
|
||||
case RevealOptionKey.hide.rawValue, RevealOptionKey.unhide.rawValue:
|
||||
item.interaction.toggleArchivedFolderHiddenByDefault()
|
||||
close = false
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -1458,4 +1458,10 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
self?.updateIsHighlighted(transition: .immediate)
|
||||
})
|
||||
}
|
||||
|
||||
override func animateFrameTransition(_ progress: CGFloat, _ currentValue: CGFloat) {
|
||||
super.animateFrameTransition(progress, currentValue)
|
||||
|
||||
self.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, currentValue - itemHeight, 0.0)
|
||||
}
|
||||
}
|
||||
|
@ -367,6 +367,8 @@ final class ChatListNode: ListView {
|
||||
let _ = self.currentRemovingPeerId.swap(peerId)
|
||||
}
|
||||
|
||||
private var hapticFeedback: HapticFeedback?
|
||||
|
||||
init(context: AccountContext, groupId: PeerGroupId?, controlsHistoryPreload: Bool, mode: ChatListNodeMode, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, disableAnimations: Bool) {
|
||||
self.context = context
|
||||
self.controlsHistoryPreload = controlsHistoryPreload
|
||||
@ -380,6 +382,7 @@ final class ChatListNode: ListView {
|
||||
super.init()
|
||||
|
||||
self.verticalScrollIndicatorColor = theme.list.scrollIndicatorColor
|
||||
self.verticalScrollIndicatorFollowsOverscroll = true
|
||||
|
||||
let nodeInteraction = ChatListNodeInteraction(activateSearch: { [weak self] in
|
||||
if let strongSelf = self, let activateSearch = strongSelf.activateSearch {
|
||||
@ -468,12 +471,17 @@ final class ChatListNode: ListView {
|
||||
})
|
||||
return updatedValue
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { updatedValue in
|
||||
|> deliverOnMainQueue).start(next: { value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if !updatedValue {
|
||||
|
||||
strongSelf.updateState { state in
|
||||
var state = state
|
||||
if !value {
|
||||
state.archiveShouldBeTemporaryRevealed = false
|
||||
}
|
||||
state.peerIdWithRevealedOptions = nil
|
||||
return state
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -488,6 +496,7 @@ final class ChatListNode: ListView {
|
||||
|
||||
let previousState = Atomic<ChatListNodeState>(value: self.currentState)
|
||||
let previousView = Atomic<ChatListNodeView?>(value: nil)
|
||||
let previousHideArchivedFolderByDefault = Atomic<Bool?>(value: nil)
|
||||
let currentRemovingPeerId = self.currentRemovingPeerId
|
||||
|
||||
let savedMessagesPeer: Signal<Peer?, NoError>
|
||||
@ -509,6 +518,8 @@ final class ChatListNode: ListView {
|
||||
|
||||
let chatListNodeViewTransition = combineLatest(hideArchivedFolderByDefault, savedMessagesPeer, chatListViewUpdate, self.statePromise.get()) |> mapToQueue { (hideArchivedFolderByDefault, savedMessagesPeer, update, state) -> Signal<ChatListNodeListViewTransition, NoError> in
|
||||
|
||||
let previousHideArchivedFolderByDefaultValue = previousHideArchivedFolderByDefault.swap(hideArchivedFolderByDefault)
|
||||
|
||||
let (rawEntries, isLoading) = chatListNodeEntriesForView(update.view, state: state, savedMessagesPeer: savedMessagesPeer, hideArchivedFolderByDefault: hideArchivedFolderByDefault, mode: mode)
|
||||
let entries = rawEntries.filter { entry in
|
||||
switch entry {
|
||||
@ -644,7 +655,7 @@ final class ChatListNode: ListView {
|
||||
if doesIncludeRemovingPeerId != didIncludeRemovingPeerId {
|
||||
disableAnimations = false
|
||||
}
|
||||
if previousState.archiveShouldBeTemporaryRevealed != state.archiveShouldBeTemporaryRevealed && doesIncludeArchive {
|
||||
if hideArchivedFolderByDefault && previousState.archiveShouldBeTemporaryRevealed != state.archiveShouldBeTemporaryRevealed && doesIncludeArchive {
|
||||
disableAnimations = false
|
||||
}
|
||||
if didIncludeHiddenByDefaultArchive != doesIncludeHiddenByDefaultArchive {
|
||||
@ -652,6 +663,10 @@ final class ChatListNode: ListView {
|
||||
}
|
||||
}
|
||||
|
||||
if let _ = previousHideArchivedFolderByDefaultValue, previousHideArchivedFolderByDefaultValue != hideArchivedFolderByDefault {
|
||||
disableAnimations = false
|
||||
}
|
||||
|
||||
var searchMode = false
|
||||
if case .peers = mode {
|
||||
searchMode = true
|
||||
@ -689,6 +704,7 @@ final class ChatListNode: ListView {
|
||||
|
||||
var rawUnreadCount: Int32 = 0
|
||||
var filteredUnreadCount: Int32 = 0
|
||||
var archiveVisible = false
|
||||
if let range = range.visibleRange {
|
||||
let entryCount = chatListView.filteredEntries.count
|
||||
for i in range.firstIndex ..< range.lastIndex {
|
||||
@ -705,6 +721,8 @@ final class ChatListNode: ListView {
|
||||
filteredUnreadCount += count
|
||||
}
|
||||
}
|
||||
case .GroupReferenceEntry:
|
||||
archiveVisible = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -714,6 +732,13 @@ final class ChatListNode: ListView {
|
||||
visibleUnreadCountsValue.raw = rawUnreadCount
|
||||
visibleUnreadCountsValue.filtered = filteredUnreadCount
|
||||
strongSelf.visibleUnreadCountsValue = visibleUnreadCountsValue
|
||||
if !archiveVisible && strongSelf.currentState.archiveShouldBeTemporaryRevealed {
|
||||
strongSelf.updateState { state in
|
||||
var state = state
|
||||
state.archiveShouldBeTemporaryRevealed = false
|
||||
return state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -925,7 +950,7 @@ final class ChatListNode: ListView {
|
||||
case .none, .unknown:
|
||||
revealHiddenItems = false
|
||||
case let .known(value):
|
||||
revealHiddenItems = value <= 76.0
|
||||
revealHiddenItems = value <= 54.0
|
||||
}
|
||||
if !revealHiddenItems && strongSelf.currentState.archiveShouldBeTemporaryRevealed {
|
||||
strongSelf.updateState { state in
|
||||
@ -974,16 +999,30 @@ final class ChatListNode: ListView {
|
||||
case let .known(value):
|
||||
atTop = value <= 0.0
|
||||
if startedScrollingAtUpperBound && strongSelf.isTracking {
|
||||
revealHiddenItems = value <= -32.0
|
||||
revealHiddenItems = value <= -76.0
|
||||
}
|
||||
}
|
||||
strongSelf.scrolledAtTopValue = atTop
|
||||
strongSelf.contentOffsetChanged?(offset)
|
||||
if revealHiddenItems && !strongSelf.currentState.archiveShouldBeTemporaryRevealed {
|
||||
strongSelf.updateState { state in
|
||||
var state = state
|
||||
state.archiveShouldBeTemporaryRevealed = true
|
||||
return state
|
||||
var isArchiveVisible = false
|
||||
strongSelf.forEachItemNode({ itemNode in
|
||||
if let itemNode = itemNode as? ChatListItemNode, let item = itemNode.item {
|
||||
if case .groupReference = item.content {
|
||||
isArchiveVisible = true
|
||||
}
|
||||
}
|
||||
})
|
||||
if isArchiveVisible {
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.impact(.medium)
|
||||
strongSelf.updateState { state in
|
||||
var state = state
|
||||
state.archiveShouldBeTemporaryRevealed = true
|
||||
return state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
case enableRaiseToSpeak(PresentationTheme, Bool)
|
||||
case keepChatNavigationStack(PresentationTheme, Bool)
|
||||
case skipReadHistory(PresentationTheme, Bool)
|
||||
case crashOnSlowQueries(PresentationTheme, Bool)
|
||||
case clearTips(PresentationTheme)
|
||||
case reimport(PresentationTheme)
|
||||
case resetData(PresentationTheme)
|
||||
@ -54,7 +55,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return DebugControllerSection.logs.rawValue
|
||||
case .logToFile, .logToConsole, .redactSensitiveData:
|
||||
return DebugControllerSection.logging.rawValue
|
||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory:
|
||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .clearTips, .reimport, .resetData, .animatedStickers:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
@ -85,12 +86,14 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return 8
|
||||
case .skipReadHistory:
|
||||
return 9
|
||||
case .clearTips:
|
||||
case .crashOnSlowQueries:
|
||||
return 10
|
||||
case .reimport:
|
||||
case .clearTips:
|
||||
return 11
|
||||
case .resetData:
|
||||
case .reimport:
|
||||
return 12
|
||||
case .resetData:
|
||||
return 13
|
||||
case .animatedStickers:
|
||||
return 14
|
||||
case .versionInfo:
|
||||
@ -275,6 +278,14 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return settings
|
||||
}).start()
|
||||
})
|
||||
case let .crashOnSlowQueries(theme, value):
|
||||
return ItemListSwitchItem(theme: theme, title: "Crash when slow", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
settings.crashOnLongQueries = value
|
||||
return settings
|
||||
}).start()
|
||||
})
|
||||
case let .clearTips(theme):
|
||||
return ItemListActionItem(theme: theme, title: "Clear Tips", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||
let _ = (arguments.sharedContext.accountManager.transaction { transaction -> Void in
|
||||
@ -346,6 +357,7 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS
|
||||
#if DEBUG
|
||||
entries.append(.skipReadHistory(presentationData.theme, experimentalSettings.skipReadHistory))
|
||||
#endif
|
||||
entries.append(.crashOnSlowQueries(presentationData.theme, experimentalSettings.crashOnLongQueries))
|
||||
entries.append(.clearTips(presentationData.theme))
|
||||
if hasLegacyAppData {
|
||||
entries.append(.reimport(presentationData.theme))
|
||||
|
@ -141,7 +141,8 @@ private let chatList = PresentationThemeChatList(
|
||||
searchBarKeyboardColor: .dark,
|
||||
verifiedIconFillColor: accentColor,
|
||||
verifiedIconForegroundColor: .white,
|
||||
secretIconColor: secretColor
|
||||
secretIconColor: secretColor,
|
||||
neutralAvatarColor: UIColor(rgb: 0xDBF5FF, alpha: 0.4)
|
||||
)
|
||||
|
||||
private let bubble = PresentationThemeChatBubble(
|
||||
|
@ -141,7 +141,8 @@ private let chatList = PresentationThemeChatList(
|
||||
searchBarKeyboardColor: .dark,
|
||||
verifiedIconFillColor: accentColor,
|
||||
verifiedIconForegroundColor: .white,
|
||||
secretIconColor: secretColor
|
||||
secretIconColor: secretColor,
|
||||
neutralAvatarColor: UIColor(rgb: 0x666666)
|
||||
)
|
||||
|
||||
private let bubble = PresentationThemeChatBubble(
|
||||
|
@ -141,7 +141,8 @@ private func makeDefaultPresentationTheme(accentColor: UIColor, serviceBackgroun
|
||||
searchBarKeyboardColor: .light,
|
||||
verifiedIconFillColor: accentColor,
|
||||
verifiedIconForegroundColor: .white,
|
||||
secretIconColor: secretColor
|
||||
secretIconColor: secretColor,
|
||||
neutralAvatarColor: UIColor(rgb: 0xb6b6ba)
|
||||
)
|
||||
|
||||
let chatListDay = PresentationThemeChatList(
|
||||
@ -172,7 +173,8 @@ private func makeDefaultPresentationTheme(accentColor: UIColor, serviceBackgroun
|
||||
searchBarKeyboardColor: .light,
|
||||
verifiedIconFillColor: accentColor,
|
||||
verifiedIconForegroundColor: .white,
|
||||
secretIconColor: secretColor
|
||||
secretIconColor: secretColor,
|
||||
neutralAvatarColor: UIColor(rgb: 0xb6b6ba)
|
||||
)
|
||||
|
||||
let bubble = PresentationThemeChatBubble(
|
||||
|
@ -5,24 +5,28 @@ import SwiftSignalKit
|
||||
public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
||||
public var keepChatNavigationStack: Bool
|
||||
public var skipReadHistory: Bool
|
||||
public var crashOnLongQueries: Bool
|
||||
|
||||
public static var defaultSettings: ExperimentalUISettings {
|
||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false)
|
||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false)
|
||||
}
|
||||
|
||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool) {
|
||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool) {
|
||||
self.keepChatNavigationStack = keepChatNavigationStack
|
||||
self.skipReadHistory = skipReadHistory
|
||||
self.crashOnLongQueries = crashOnLongQueries
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.keepChatNavigationStack = decoder.decodeInt32ForKey("keepChatNavigationStack", orElse: 0) != 0
|
||||
self.skipReadHistory = decoder.decodeInt32ForKey("skipReadHistory", orElse: 0) != 0
|
||||
self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.keepChatNavigationStack ? 1 : 0, forKey: "keepChatNavigationStack")
|
||||
encoder.encodeInt32(self.skipReadHistory ? 1 : 0, forKey: "skipReadHistory")
|
||||
encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries")
|
||||
}
|
||||
|
||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||
|
@ -269,9 +269,21 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega
|
||||
reveal = false
|
||||
}
|
||||
}
|
||||
self.updateRevealOffsetInternal(offset: reveal ? -revealSize.width : 0.0, transition: .animated(duration: 0.3, curve: .spring))
|
||||
if !reveal {
|
||||
self.revealOptionsInteractivelyClosed()
|
||||
|
||||
var selectedOption: ItemListRevealOption?
|
||||
if reveal && rightRevealNode.isDisplayingExtendedAction() {
|
||||
reveal = false
|
||||
selectedOption = self.revealOptions.right.last
|
||||
} else {
|
||||
self.updateRevealOffsetInternal(offset: reveal ? -revealSize.width : 0.0, transition: .animated(duration: 0.3, curve: .spring))
|
||||
}
|
||||
|
||||
if let selectedOption = selectedOption {
|
||||
self.revealOptionSelected(selectedOption, animated: true)
|
||||
} else {
|
||||
if !reveal {
|
||||
self.revealOptionsInteractivelyClosed()
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
@ -128,6 +128,7 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
|
||||
private let animationNode: ItemListRevealAnimationNode?
|
||||
private var animationNodeOffset: CGFloat = 0.0
|
||||
var alignment: ItemListRevealOptionAlignment?
|
||||
var isExpanded: Bool = false
|
||||
|
||||
init(title: String, icon: ItemListRevealOptionIcon, color: UIColor, textColor: UIColor) {
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
@ -178,11 +179,11 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
func updateLayout(isFirst: Bool, isLeft: Bool, baseSize: CGSize, alignment: ItemListRevealOptionAlignment, extendedWidth: CGFloat, sideInset: CGFloat, transition: ContainedViewLayoutTransition, revealFactor: CGFloat) {
|
||||
func updateLayout(isFirst: Bool, isLeft: Bool, baseSize: CGSize, alignment: ItemListRevealOptionAlignment, isExpanded: Bool, extendedWidth: CGFloat, sideInset: CGFloat, transition: ContainedViewLayoutTransition, additive: Bool, revealFactor: CGFloat) {
|
||||
self.highlightNode.frame = CGRect(origin: CGPoint(), size: baseSize)
|
||||
|
||||
var animateAdditive = false
|
||||
if transition.isAnimated, self.alignment != alignment {
|
||||
if additive && transition.isAnimated && self.isExpanded != isExpanded {
|
||||
animateAdditive = true
|
||||
}
|
||||
|
||||
@ -192,15 +193,23 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
|
||||
} else {
|
||||
backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: extendedWidth, height: baseSize.height))
|
||||
}
|
||||
let deltaX: CGFloat
|
||||
if animateAdditive {
|
||||
let previousFrame = self.backgroundNode.frame
|
||||
self.backgroundNode.frame = backgroundFrame
|
||||
transition.animatePositionAdditive(node: self.backgroundNode, offset: CGPoint(x: previousFrame.width - backgroundFrame.width, y: 0.0))
|
||||
if isLeft {
|
||||
deltaX = previousFrame.width - backgroundFrame.width
|
||||
} else {
|
||||
deltaX = -(previousFrame.width - backgroundFrame.width)
|
||||
}
|
||||
transition.animatePositionAdditive(node: self.backgroundNode, offset: CGPoint(x: deltaX, y: 0.0))
|
||||
} else {
|
||||
deltaX = 0.0
|
||||
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
|
||||
}
|
||||
|
||||
self.alignment = alignment
|
||||
self.isExpanded = isExpanded
|
||||
let titleSize = self.titleNode.calculatedSize
|
||||
var contentRect = CGRect(origin: CGPoint(), size: baseSize)
|
||||
switch alignment {
|
||||
@ -215,13 +224,13 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
|
||||
let titleIconSpacing: CGFloat = 11.0
|
||||
let iconFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - imageSize.width + sideInset) / 2.0), y: contentRect.midY - imageSize.height / 2.0 + iconOffset), size: imageSize)
|
||||
if animateAdditive {
|
||||
transition.animatePositionAdditive(node: animationNode, offset: CGPoint(x: animationNode.frame.minX - iconFrame.minX, y: 0.0))
|
||||
transition.animatePositionAdditive(node: animationNode, offset: CGPoint(x: deltaX, y: 0.0))
|
||||
}
|
||||
animationNode.frame = iconFrame
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - titleSize.width + sideInset) / 2.0), y: contentRect.midY + titleIconSpacing), size: titleSize)
|
||||
if animateAdditive {
|
||||
transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: self.titleNode.frame.minX - titleFrame.minX, y: 0.0))
|
||||
transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: deltaX, y: 0.0))
|
||||
}
|
||||
self.titleNode.frame = titleFrame
|
||||
|
||||
@ -235,13 +244,13 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
|
||||
let titleIconSpacing: CGFloat = 11.0
|
||||
let iconFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - imageSize.width + sideInset) / 2.0), y: contentRect.midY - imageSize.height / 2.0 + iconOffset), size: imageSize)
|
||||
if animateAdditive {
|
||||
transition.animatePositionAdditive(node: iconNode, offset: CGPoint(x: iconNode.frame.minX - iconFrame.minX, y: 0.0))
|
||||
transition.animatePositionAdditive(node: iconNode, offset: CGPoint(x: deltaX, y: 0.0))
|
||||
}
|
||||
iconNode.frame = iconFrame
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - titleSize.width + sideInset) / 2.0), y: contentRect.midY + titleIconSpacing), size: titleSize)
|
||||
if animateAdditive {
|
||||
transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: self.titleNode.frame.minX - titleFrame.minX, y: 0.0))
|
||||
transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: deltaX, y: 0.0))
|
||||
}
|
||||
self.titleNode.frame = titleFrame
|
||||
} else {
|
||||
@ -345,33 +354,30 @@ final class ItemListRevealOptionsNode: ASDisplayNode {
|
||||
let lastNodeWidth = size.width - basicNodeWidth * CGFloat(self.optionNodes.count - 1)
|
||||
let revealFactor = self.revealOffset / size.width
|
||||
let boundaryRevealFactor: CGFloat = 1.0 + basicNodeWidth / size.width * 0.7
|
||||
var leftOffset: CGFloat = 0.0
|
||||
var leftOffset: CGFloat
|
||||
if self.isLeft {
|
||||
leftOffset = size.width + max(0.0, abs(revealFactor) - 1.0) * size.width
|
||||
} else {
|
||||
leftOffset = 0.0
|
||||
}
|
||||
for i in 0 ..< self.optionNodes.count {
|
||||
var i = self.isLeft ? (self.optionNodes.count - 1) : 0
|
||||
while i >= 0 && i < self.optionNodes.count {
|
||||
let node = self.optionNodes[i]
|
||||
let nodeWidth = i == (self.optionNodes.count - 1) ? lastNodeWidth : basicNodeWidth
|
||||
var extendedWidth = nodeWidth
|
||||
let defaultAlignment: ItemListRevealOptionAlignment = isLeft ? .left : .right
|
||||
var alignment = defaultAlignment
|
||||
let defaultAlignment: ItemListRevealOptionAlignment = isLeft ? .right : .left
|
||||
var nodeTransition = transition
|
||||
extendedWidth = nodeWidth * max(1.0, abs(revealFactor))
|
||||
extendedWidth = floorToScreenPixels(nodeWidth * max(1.0, abs(revealFactor)))
|
||||
var isExpanded = false
|
||||
if (isLeft && i == 0) || (!isLeft && i == self.optionNodes.count - 1) {
|
||||
if isLeft && abs(revealFactor) > boundaryRevealFactor {
|
||||
if abs(revealFactor) > boundaryRevealFactor {
|
||||
extendedWidth = size.width * max(1.0, abs(revealFactor))
|
||||
isExpanded = true
|
||||
if isLeft {
|
||||
alignment = .right
|
||||
} else {
|
||||
alignment = .left
|
||||
}
|
||||
}
|
||||
}
|
||||
if let nodeAlignment = node.alignment, alignment != nodeAlignment {
|
||||
if let _ = node.alignment, node.isExpanded != isExpanded {
|
||||
nodeTransition = transition.isAnimated ? transition : .animated(duration: 0.2, curve: .spring)
|
||||
if alignment != defaultAlignment || !transition.isAnimated {
|
||||
if !transition.isAnimated {
|
||||
self.tapticAction()
|
||||
}
|
||||
}
|
||||
@ -382,13 +388,25 @@ final class ItemListRevealOptionsNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
var nodeLeftOffset = leftOffset
|
||||
if self.isLeft {
|
||||
nodeLeftOffset -= extendedWidth
|
||||
} else {
|
||||
nodeLeftOffset *= abs(revealFactor)
|
||||
}
|
||||
if isExpanded {
|
||||
nodeLeftOffset = 0.0
|
||||
}
|
||||
|
||||
transition.updateFrame(node: node, frame: CGRect(origin: CGPoint(x: floorToScreenPixels(nodeLeftOffset * abs(revealFactor)), y: 0.0), size: CGSize(width: extendedWidth, height: size.height)))
|
||||
node.updateLayout(isFirst: i == 0, isLeft: self.isLeft, baseSize: CGSize(width: nodeWidth, height: size.height), alignment: alignment, extendedWidth: extendedWidth, sideInset: sideInset, transition: nodeTransition, revealFactor: revealFactor)
|
||||
leftOffset += nodeWidth
|
||||
transition.updateFrame(node: node, frame: CGRect(origin: CGPoint(x: floorToScreenPixels(nodeLeftOffset), y: 0.0), size: CGSize(width: extendedWidth, height: size.height)))
|
||||
node.updateLayout(isFirst: (self.isLeft && i == 0) || (!self.isLeft && i == self.optionNodes.count - 1), isLeft: self.isLeft, baseSize: CGSize(width: nodeWidth, height: size.height), alignment: defaultAlignment, isExpanded: isExpanded, extendedWidth: extendedWidth, sideInset: sideInset, transition: nodeTransition, additive: !transition.isAnimated, revealFactor: revealFactor)
|
||||
|
||||
if self.isLeft {
|
||||
leftOffset -= extendedWidth
|
||||
i -= 1
|
||||
} else {
|
||||
leftOffset += nodeWidth
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,12 +427,6 @@ final class ItemListRevealOptionsNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
func isDisplayingExtendedAction() -> Bool {
|
||||
let defaultAlignment: ItemListRevealOptionAlignment = self.isLeft ? .left : .right
|
||||
for node in self.optionNodes {
|
||||
if let alignment = node.alignment, alignment != defaultAlignment {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return self.optionNodes.contains(where: { $0.isExpanded })
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class NavigationBarSearchContentNode: NavigationBarContentNode {
|
||||
}
|
||||
|
||||
func updateExpansionProgress(_ progress: CGFloat, animated: Bool = false) {
|
||||
let newProgress = max(0.0, min(1.0, progress))
|
||||
let newProgress = max(0.0, min(10.0, progress))
|
||||
if abs(newProgress - self.expansionProgress) > 0.0001 {
|
||||
self.expansionProgress = newProgress
|
||||
|
||||
@ -121,13 +121,16 @@ class NavigationBarSearchContentNode: NavigationBarContentNode {
|
||||
|
||||
let fieldHeight: CGFloat = 36.0
|
||||
let fraction = fieldHeight / self.nominalHeight
|
||||
let visibleProgress = max(0.0, self.expansionProgress - 1.0 + fraction) / fraction
|
||||
|
||||
let visibleProgress = max(0.0, min(1.0, self.expansionProgress) - 1.0 + fraction) / fraction
|
||||
|
||||
let overscrollProgress = max(0.0, max(0.0, self.expansionProgress - 1.0 + fraction) / fraction - visibleProgress)
|
||||
|
||||
let searchBarNodeLayout = self.placeholderNode.asyncLayout()
|
||||
let (searchBarHeight, searchBarApply) = searchBarNodeLayout(NSAttributedString(string: self.placeholder, font: searchBarFont, textColor: self.theme?.rootController.activeNavigationSearchBar.inputPlaceholderTextColor ?? UIColor(rgb: 0x8e8e93)), CGSize(width: baseWidth, height: fieldHeight), visibleProgress, self.theme?.rootController.activeNavigationSearchBar.inputPlaceholderTextColor ?? UIColor(rgb: 0x8e8e93), self.theme?.rootController.activeNavigationSearchBar.inputFillColor ?? .clear, self.theme?.rootController.navigationBar.backgroundColor ?? .clear, transition)
|
||||
searchBarApply()
|
||||
|
||||
let searchBarFrame = CGRect(origin: CGPoint(x: padding + leftInset, y: 8.0), size: CGSize(width: baseWidth, height: fieldHeight))
|
||||
let searchBarFrame = CGRect(origin: CGPoint(x: padding + leftInset, y: 8.0 + overscrollProgress * fieldHeight), size: CGSize(width: baseWidth, height: fieldHeight))
|
||||
transition.updateFrame(node: self.placeholderNode, frame: searchBarFrame)
|
||||
|
||||
self.placeholderHeight = searchBarHeight
|
||||
|
@ -375,8 +375,9 @@ public final class PresentationThemeChatList {
|
||||
public let verifiedIconFillColor: UIColor
|
||||
public let verifiedIconForegroundColor: UIColor
|
||||
public let secretIconColor: UIColor
|
||||
public let neutralAvatarColor: UIColor
|
||||
|
||||
init(backgroundColor: UIColor, itemSeparatorColor: UIColor, itemBackgroundColor: UIColor, pinnedItemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemSelectedBackgroundColor: UIColor, titleColor: UIColor, secretTitleColor: UIColor, dateTextColor: UIColor, authorNameColor: UIColor, messageTextColor: UIColor, messageDraftTextColor: UIColor, checkmarkColor: UIColor, pendingIndicatorColor: UIColor, muteIconColor: UIColor, unreadBadgeActiveBackgroundColor: UIColor, unreadBadgeActiveTextColor: UIColor, unreadBadgeInactiveBackgroundColor: UIColor, unreadBadgeInactiveTextColor: UIColor, pinnedBadgeColor: UIColor, pinnedSearchBarColor: UIColor, regularSearchBarColor: UIColor, sectionHeaderFillColor: UIColor, sectionHeaderTextColor: UIColor, searchBarKeyboardColor: PresentationThemeKeyboardColor, verifiedIconFillColor: UIColor, verifiedIconForegroundColor: UIColor, secretIconColor: UIColor) {
|
||||
init(backgroundColor: UIColor, itemSeparatorColor: UIColor, itemBackgroundColor: UIColor, pinnedItemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemSelectedBackgroundColor: UIColor, titleColor: UIColor, secretTitleColor: UIColor, dateTextColor: UIColor, authorNameColor: UIColor, messageTextColor: UIColor, messageDraftTextColor: UIColor, checkmarkColor: UIColor, pendingIndicatorColor: UIColor, muteIconColor: UIColor, unreadBadgeActiveBackgroundColor: UIColor, unreadBadgeActiveTextColor: UIColor, unreadBadgeInactiveBackgroundColor: UIColor, unreadBadgeInactiveTextColor: UIColor, pinnedBadgeColor: UIColor, pinnedSearchBarColor: UIColor, regularSearchBarColor: UIColor, sectionHeaderFillColor: UIColor, sectionHeaderTextColor: UIColor, searchBarKeyboardColor: PresentationThemeKeyboardColor, verifiedIconFillColor: UIColor, verifiedIconForegroundColor: UIColor, secretIconColor: UIColor, neutralAvatarColor: UIColor) {
|
||||
self.backgroundColor = backgroundColor
|
||||
self.itemSeparatorColor = itemSeparatorColor
|
||||
self.itemBackgroundColor = itemBackgroundColor
|
||||
@ -405,6 +406,7 @@ public final class PresentationThemeChatList {
|
||||
self.verifiedIconFillColor = verifiedIconFillColor
|
||||
self.verifiedIconForegroundColor = verifiedIconForegroundColor
|
||||
self.secretIconColor = secretIconColor
|
||||
self.neutralAvatarColor = neutralAvatarColor
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user