Various improvements

This commit is contained in:
Ilya Laktyushin 2022-05-23 04:57:54 +04:00
parent 00d343a892
commit 585838b455
7 changed files with 131 additions and 39 deletions

View File

@ -1245,8 +1245,24 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
strongSelf.setToolbar(toolbar, transition: transition)
}))
self.tabContainerNode.tabSelected = { [weak self] id in
self?.selectTab(id: id)
self.tabContainerNode.tabSelected = { [weak self] id, disabled in
guard let strongSelf = self else {
return
}
if disabled {
let context = strongSelf.context
var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumLimitScreen(context: context, subject: .folders, count: strongSelf.tabContainerNode.filtersCount, action: {
let controller = PremiumIntroScreen(context: context, source: .folders)
replaceImpl?(controller)
})
replaceImpl = { [weak controller] c in
controller?.replace(with: c)
}
strongSelf.push(controller)
} else {
strongSelf.selectTab(id: id)
}
}
self.chatListDisplayNode.inlineTabContainerNode.tabSelected = { [weak self] id in
self?.selectTab(id: id)
@ -1342,7 +1358,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if let accountPeer = accountPeer, accountPeer.isPremium {
if data.includePeers.peers.count >= premiumLimit {
//printPremiumError
return
}
} else {

View File

@ -15,15 +15,15 @@ import PremiumUI
private final class ChatListFilterPresetListControllerArguments {
let context: AccountContext
let addSuggestedPresed: (String, ChatListFilterData) -> Void
let addSuggestedPressed: (String, ChatListFilterData) -> Void
let openPreset: (ChatListFilter) -> Void
let addNew: () -> Void
let setItemWithRevealedOptions: (Int32?, Int32?) -> Void
let removePreset: (Int32) -> Void
init(context: AccountContext, addSuggestedPresed: @escaping (String, ChatListFilterData) -> Void, openPreset: @escaping (ChatListFilter) -> Void, addNew: @escaping () -> Void, setItemWithRevealedOptions: @escaping (Int32?, Int32?) -> Void, removePreset: @escaping (Int32) -> Void) {
init(context: AccountContext, addSuggestedPressed: @escaping (String, ChatListFilterData) -> Void, openPreset: @escaping (ChatListFilter) -> Void, addNew: @escaping () -> Void, setItemWithRevealedOptions: @escaping (Int32?, Int32?) -> Void, removePreset: @escaping (Int32) -> Void) {
self.context = context
self.addSuggestedPresed = addSuggestedPresed
self.addSuggestedPressed = addSuggestedPressed
self.openPreset = openPreset
self.addNew = addNew
self.setItemWithRevealedOptions = setItemWithRevealedOptions
@ -144,7 +144,7 @@ private enum ChatListFilterPresetListEntry: ItemListNodeEntry {
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, multiline: true, sectionId: self.section)
case let .suggestedPreset(_, title, label, preset):
return ChatListFilterPresetListSuggestedItem(presentationData: presentationData, title: title, label: label, sectionId: self.section, style: .blocks, installAction: {
arguments.addSuggestedPresed(title, preset)
arguments.addSuggestedPressed(title, preset)
}, tag: nil)
case let .suggestedAddCustom(text):
return ItemListPeerActionItem(presentationData: presentationData, icon: nil, title: text, sectionId: self.section, height: .generic, editing: false, action: {
@ -207,6 +207,13 @@ private func chatListFilterPresetListControllerEntries(presentationData: Present
return true
}
let actualFilters = filters.filter { filter in
if case .allChats = filter.0 {
return false
}
return true
}
if !filters.isEmpty || suggestedFilters.isEmpty {
entries.append(.listHeader(presentationData.strings.ChatListFolderSettings_FoldersSection))
@ -218,13 +225,13 @@ private func chatListFilterPresetListControllerEntries(presentationData: Present
entries.append(.preset(index: PresetIndex(value: entries.count), title: title, label: chatCount == 0 ? "" : "\(chatCount)", preset: filter, canBeReordered: filters.count > 1, canBeDeleted: true, isEditing: state.isEditing, isAllChats: false))
}
}
if !isPremium || filters.count < limits.maxFolderChatsCount {
if actualFilters.count < limits.maxFoldersCount {
entries.append(.addItem(text: presentationData.strings.ChatListFolderSettings_NewFolder, isEditing: state.isEditing))
}
entries.append(.listFooter(presentationData.strings.ChatListFolderSettings_EditFoldersInfo))
}
if !filteredSuggestedFilters.isEmpty && filters.count < 10 {
if !filteredSuggestedFilters.isEmpty && actualFilters.count < limits.maxFoldersCount {
entries.append(.suggestedListHeader(presentationData.strings.ChatListFolderSettings_RecommendedFoldersSection))
for filter in filteredSuggestedFilters {
entries.append(.suggestedPreset(index: PresetIndex(value: entries.count), title: filter.title, label: filter.description, preset: filter.data))
@ -266,14 +273,52 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
filtersWithCounts.set(filtersWithCountsSignal)
let arguments = ChatListFilterPresetListControllerArguments(context: context,
addSuggestedPresed: { title, data in
let _ = (context.engine.peers.updateChatListFiltersInteractively { filters in
var filters = filters
let id = context.engine.peers.generateNewChatListFilterId(filters: filters)
filters.insert(.filter(id: id, title: title, emoticon: nil, data: data), at: 0)
return filters
}
|> deliverOnMainQueue).start(next: { _ in
addSuggestedPressed: { title, data in
let _ = combineLatest(
queue: Queue.mainQueue(),
context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId),
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false),
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
),
filtersWithCounts.get() |> take(1)
).start(next: { result, filters in
let (accountPeer, limits, premiumLimits) = result
let filters = filters.filter { filter in
if case .allChats = filter.0 {
return false
}
return true
}
let limit = limits.maxFoldersCount
let premiumLimit = premiumLimits.maxFoldersCount
if let accountPeer = accountPeer, accountPeer.isPremium {
if filters.count >= premiumLimit {
return
}
} else {
if filters.count >= limit {
var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumLimitScreen(context: context, subject: .folders, count: Int32(filters.count), action: {
let controller = PremiumIntroScreen(context: context, source: .folders)
replaceImpl?(controller)
})
replaceImpl = { [weak controller] c in
controller?.replace(with: c)
}
pushControllerImpl?(controller)
return
}
}
let _ = (context.engine.peers.updateChatListFiltersInteractively { filters in
var filters = filters
let id = context.engine.peers.generateNewChatListFilterId(filters: filters)
filters.insert(.filter(id: id, title: title, emoticon: nil, data: data), at: 0)
return filters
}
|> deliverOnMainQueue).start(next: { _ in
})
})
}, openPreset: { preset in
pushControllerImpl?(chatListFilterPresetController(context: context, currentPreset: preset, updated: { _ in }))
@ -288,11 +333,17 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
filtersWithCounts.get() |> take(1)
).start(next: { result, filters in
let (accountPeer, limits, premiumLimits) = result
let filters = filters.filter { filter in
if case .allChats = filter.0 {
return false
}
return true
}
let limit = limits.maxFoldersCount
let premiumLimit = premiumLimits.maxFoldersCount
if let accountPeer = accountPeer, accountPeer.isPremium {
if filters.count >= premiumLimit {
//printPremiumError
return
}
} else {
@ -377,7 +428,7 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
)
|> map { presentationData, state, filtersWithCountsValue, preferences, updatedFilterOrderValue, suggestedFilters, peer, limits -> (ItemListControllerState, (ItemListNodeState, Any)) in
let isPremium = peer?.isPremium ?? false
let effectiveLimits = isPremium ? limits.1 : limits.0
let effectiveLimits = limits.1
let filterSettings = preferences.values[ApplicationSpecificPreferencesKeys.chatListFilterSettings]?.get(ChatListFilterSettings.self) ?? ChatListFilterSettings.default
let leftNavigationButton: ItemListNavigationButton?

View File

@ -56,7 +56,7 @@ private final class ItemNodeDeleteButtonNode: HighlightableButtonNode {
}
private final class ItemNode: ASDisplayNode {
private let pressed: () -> Void
private let pressed: (Bool) -> Void
private let requestedDeletion: () -> Void
private let extractedContainerNode: ContextExtractedContentContainingNode
@ -84,10 +84,11 @@ private final class ItemNode: ASDisplayNode {
private var isReordering: Bool = false
private var isEditing: Bool = false
private var isDisabled: Bool = false
private var theme: PresentationTheme?
init(pressed: @escaping () -> Void, requestedDeletion: @escaping () -> Void, contextGesture: @escaping (ContextExtractedContentContainingNode, ContextGesture) -> Void) {
init(pressed: @escaping (Bool) -> Void, requestedDeletion: @escaping () -> Void, contextGesture: @escaping (ContextExtractedContentContainingNode, ContextGesture) -> Void) {
self.pressed = pressed
self.requestedDeletion = requestedDeletion
@ -189,11 +190,12 @@ private final class ItemNode: ASDisplayNode {
}
@objc private func buttonPressed() {
self.pressed()
self.pressed(self.isDisabled)
}
func updateText(strings: PresentationStrings, title: String, shortTitle: String, unreadCount: Int, unreadHasUnmuted: Bool, isNoFilter: Bool, selectionFraction: CGFloat, isEditing: Bool, isAllChats: Bool, isReordering: Bool, canReorderAllChats: Bool, presentationData: PresentationData, transition: ContainedViewLayoutTransition) {
func updateText(strings: PresentationStrings, title: String, shortTitle: String, unreadCount: Int, unreadHasUnmuted: Bool, isNoFilter: Bool, selectionFraction: CGFloat, isEditing: Bool, isReordering: Bool, canReorderAllChats: Bool, isDisabled: Bool, presentationData: PresentationData, transition: ContainedViewLayoutTransition) {
self.isEditing = isEditing
self.isDisabled = isDisabled
if self.theme !== presentationData.theme {
self.theme = presentationData.theme
@ -215,9 +217,9 @@ private final class ItemNode: ASDisplayNode {
self.selectionFraction = selectionFraction
self.unreadCount = unreadCount
transition.updateAlpha(node: self.containerNode, alpha: isEditing || (isReordering && isAllChats && !canReorderAllChats) ? 0.5 : 1.0)
transition.updateAlpha(node: self.containerNode, alpha: (isReordering && isNoFilter && !canReorderAllChats) ? 0.5 : 1.0)
if isReordering && !isAllChats {
if isReordering && !isNoFilter {
if self.deleteButtonNode == nil {
let deleteButtonNode = ItemNodeDeleteButtonNode(pressed: { [weak self] in
self?.requestedDeletion()
@ -237,10 +239,10 @@ private final class ItemNode: ASDisplayNode {
})
}
transition.updateAlpha(node: self.badgeContainerNode, alpha: (isEditing || isReordering || unreadCount == 0) ? 0.0 : 1.0)
transition.updateAlpha(node: self.badgeContainerNode, alpha: (isDisabled || isReordering || unreadCount == 0) ? 0.0 : 1.0)
let selectionAlpha: CGFloat = selectionFraction * selectionFraction
let deselectionAlpha: CGFloat = 1.0// - selectionFraction
let deselectionAlpha: CGFloat = isDisabled ? 0.5 : 1.0// - selectionFraction
transition.updateAlpha(node: self.titleNode, alpha: deselectionAlpha)
transition.updateAlpha(node: self.titleActiveNode, alpha: selectionAlpha)
@ -265,7 +267,7 @@ private final class ItemNode: ASDisplayNode {
if self.isReordering != isReordering {
self.isReordering = isReordering
if self.isReordering && (!isAllChats || canReorderAllChats) {
if self.isReordering && (!isNoFilter || canReorderAllChats) {
self.startShaking()
} else {
self.layer.removeAnimation(forKey: "shaking_position")
@ -462,7 +464,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
private let selectedLineNode: ASImageNode
private var itemNodes: [ChatListFilterTabEntryId: ItemNode] = [:]
var tabSelected: ((ChatListFilterTabEntryId) -> Void)?
var tabSelected: ((ChatListFilterTabEntryId, Bool) -> Void)?
var tabRequestedDeletion: ((ChatListFilterTabEntryId) -> Void)?
var addFilter: (() -> Void)?
var contextGesture: ((Int32?, ContextExtractedContentContainingNode, ContextGesture) -> Void)?
@ -489,6 +491,21 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
}
}
var filtersCount: Int32 {
if let (_, _, filters, _, _, _, _, _, _) = self.currentParams {
let filters = filters.filter { filter in
if case .all = filter {
return false
} else {
return true
}
}
return Int32(filters.count)
} else {
return 0
}
}
override init() {
self.scrollNode = ASScrollNode()
@ -706,6 +723,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
}
}
let folderLimit: Int = 4
var folderIndex = 0
for i in 0 ..< reorderedFilters.count {
let filter = reorderedFilters[i]
@ -717,8 +736,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
} else {
itemNodeTransition = .immediate
wasAdded = true
itemNode = ItemNode(pressed: { [weak self] in
self?.tabSelected?(filter.id)
itemNode = ItemNode(pressed: { [weak self] disabled in
self?.tabSelected?(filter.id, disabled)
}, requestedDeletion: { [weak self] in
self?.tabRequestedDeletion?(filter.id)
}, contextGesture: { [weak self] sourceNode, gesture in
@ -739,7 +758,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
}
let unreadCount: Int
let unreadHasUnmuted: Bool
var isNoFilter: Bool = false
var isNoFilter = false
var isDisabled = false
switch filter {
case let .all(count):
unreadCount = count
@ -748,6 +768,9 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
case let .filter(_, _, unread):
unreadCount = unread.value
unreadHasUnmuted = unread.hasUnmuted
isDisabled = !canReorderAllChats && folderIndex >= folderLimit
folderIndex += 1
}
if !wasAdded && (itemNode.unreadCount != 0) != (unreadCount != 0) {
badgeAnimations[filter.id] = (unreadCount != 0) ? .in : .out
@ -764,7 +787,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
selectionFraction = 0.0
}
itemNode.updateText(strings: presentationData.strings, title: filter.title(strings: presentationData.strings), shortTitle: filter.shortTitle(strings: presentationData.strings), unreadCount: unreadCount, unreadHasUnmuted: unreadHasUnmuted, isNoFilter: isNoFilter, selectionFraction: selectionFraction, isEditing: isEditing, isAllChats: isNoFilter, isReordering: isReordering, canReorderAllChats: canReorderAllChats, presentationData: presentationData, transition: itemNodeTransition)
itemNode.updateText(strings: presentationData.strings, title: filter.title(strings: presentationData.strings), shortTitle: filter.shortTitle(strings: presentationData.strings), unreadCount: unreadCount, unreadHasUnmuted: unreadHasUnmuted, isNoFilter: isNoFilter, selectionFraction: selectionFraction, isEditing: isEditing, isReordering: isReordering, canReorderAllChats: canReorderAllChats, isDisabled: isDisabled, presentationData: presentationData, transition: itemNodeTransition)
}
var removeKeys: [ChatListFilterTabEntryId] = []
for (id, _) in self.itemNodes {

View File

@ -910,7 +910,8 @@ open class NavigationController: UINavigationController, ContainableController,
visibleRootModalDismissProgress = effectiveRootModalDismissProgress
additionalModalFrameProgress = 1.0 - topModalDismissProgress
} else {
effectiveRootModalDismissProgress = ((topModalIsFlat && !topFlatModalHasProgress) || isLandscape) ? 1.0 : topModalDismissProgress
// effectiveRootModalDismissProgress = ((topModalIsFlat && !topFlatModalHasProgress) || isLandscape) ? 1.0 : topModalDismissProgress
effectiveRootModalDismissProgress = topModalDismissProgress
visibleRootModalDismissProgress = effectiveRootModalDismissProgress
additionalModalFrameProgress = 0.0
}

View File

@ -495,6 +495,7 @@ private final class ScrollComponent<ChildEnvironment: Equatable>: Component {
}
self.delegate = self
self.showsVerticalScrollIndicator = false
self.showsHorizontalScrollIndicator = false
self.canCancelContentTouches = true
self.addSubview(self.contentView)
@ -1506,7 +1507,9 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
contentOffsetUpdated: { [weak state] topContentOffset, bottomContentOffset in
state?.topContentOffset = topContentOffset
state?.bottomContentOffset = bottomContentOffset
state?.updated(transition: .immediate)
Queue.mainQueue().justDispatch {
state?.updated(transition: .immediate)
}
},
contentOffsetWillCommit: { targetContentOffset in
if targetContentOffset.pointee.y < 100.0 {

View File

@ -230,7 +230,7 @@ private class PremiumLimitAnimationComponent: Component {
self.badgeMaskArrowView.frame = CGRect(origin: CGPoint(x: (badgeSize.width - 44.0) / 2.0, y: badgeSize.height - 12.0), size: CGSize(width: 44.0, height: 12.0))
self.badgeView.bounds = CGRect(origin: .zero, size: badgeSize)
self.badgeView.center = CGPoint(x: availableSize.width * component.badgePosition, y: 82.0)
self.badgeView.center = CGPoint(x: 3.0 + (availableSize.width - 6.0) * component.badgePosition, y: 82.0)
self.badgeForeground.bounds = CGRect(origin: CGPoint(), size: CGSize(width: badgeSize.width * 3.0, height: badgeSize.height))
if self.badgeForeground.animation(forKey: "movement") == nil {
self.badgeForeground.position = CGPoint(x: badgeSize.width * 3.0 / 2.0 - self.badgeForeground.frame.width * 0.35, y: badgeSize.height / 2.0)

View File

@ -3506,7 +3506,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
controller.navigationPresentation = .flatModal
strongSelf.currentWebAppController = controller
strongSelf.present(controller, in: .window(.root))
strongSelf.push(controller)
}, error: { [weak self] error in
if let strongSelf = self {
strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
@ -3532,7 +3532,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
controller.navigationPresentation = .flatModal
strongSelf.currentWebAppController = controller
strongSelf.present(controller, in: .window(.root))
strongSelf.push(controller)
}, error: { [weak self] error in
if let strongSelf = self {
strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
@ -11181,7 +11181,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let present = {
attachmentController.navigationPresentation = .flatModal
strongSelf.push(attachmentController)
// strongSelf.present(attachmentController, in: .window(.root))
strongSelf.attachmentController = attachmentController
}