Various improvements

This commit is contained in:
Ali
2023-01-10 21:52:58 +04:00
parent 7b5a45f326
commit a7fd29fe10
25 changed files with 363 additions and 118 deletions

View File

@@ -92,6 +92,7 @@ public final class ChatListNodeInteraction {
let present: (ViewController) -> Void
let openForumThread: (EnginePeer.Id, Int64) -> Void
let openStorageManagement: () -> Void
let openPasswordSetup: () -> Void
public var searchTextHighightState: String?
var highlightedChatLocation: ChatListHighlightedLocation?
@@ -134,7 +135,8 @@ public final class ChatListNodeInteraction {
activateChatPreview: @escaping (ChatListItem, Int64?, ASDisplayNode, ContextGesture?, CGPoint?) -> Void,
present: @escaping (ViewController) -> Void,
openForumThread: @escaping (EnginePeer.Id, Int64) -> Void,
openStorageManagement: @escaping () -> Void
openStorageManagement: @escaping () -> Void,
openPasswordSetup: @escaping () -> Void
) {
self.activateSearch = activateSearch
self.peerSelected = peerSelected
@@ -165,6 +167,7 @@ public final class ChatListNodeInteraction {
self.animationRenderer = animationRenderer
self.openForumThread = openForumThread
self.openStorageManagement = openStorageManagement
self.openPasswordSetup = openPasswordSetup
}
}
@@ -570,9 +573,14 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
), directionHint: entry.directionHint)
case let .ArchiveIntro(presentationData):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
case let .StorageInfo(presentationData, sizeFraction):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListStorageInfoItem(theme: presentationData.theme, strings: presentationData.strings, sizeFraction: sizeFraction, action: { [weak nodeInteraction] in
nodeInteraction?.openStorageManagement()
case let .Notice(presentationData, notice):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListStorageInfoItem(theme: presentationData.theme, strings: presentationData.strings, notice: notice, action: { [weak nodeInteraction] in
switch notice {
case .clearStorage:
nodeInteraction?.openStorageManagement()
case .setupPassword:
nodeInteraction?.openPasswordSetup()
}
}), directionHint: entry.directionHint)
}
}
@@ -785,9 +793,14 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
), directionHint: entry.directionHint)
case let .ArchiveIntro(presentationData):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
case let .StorageInfo(presentationData, sizeFraction):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListStorageInfoItem(theme: presentationData.theme, strings: presentationData.strings, sizeFraction: sizeFraction, action: { [weak nodeInteraction] in
nodeInteraction?.openStorageManagement()
case let .Notice(presentationData, notice):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListStorageInfoItem(theme: presentationData.theme, strings: presentationData.strings, notice: notice, action: { [weak nodeInteraction] in
switch notice {
case .clearStorage:
nodeInteraction?.openStorageManagement()
case .setupPassword:
nodeInteraction?.openPasswordSetup()
}
}), directionHint: entry.directionHint)
case .HeaderEntry:
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListEmptyHeaderItem(), directionHint: entry.directionHint)
@@ -1277,6 +1290,20 @@ public final class ChatListNode: ListView {
}
let controller = self.context.sharedContext.makeStorageManagementController(context: self.context)
self.push?(controller)
}, openPasswordSetup: { [weak self] in
guard let self else {
return
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.6, execute: { [weak self] in
guard let self else {
return
}
let _ = dismissServerProvidedSuggestion(account: self.context.account, suggestion: .setupPassword).start()
})
let controller = self.context.sharedContext.makeSetupTwoFactorAuthController(context: self.context)
self.push?(controller)
})
nodeInteraction.isInlineMode = isInlineMode
@@ -1342,6 +1369,32 @@ public final class ChatListNode: ListView {
displayArchiveIntro = .single(false)
}
let suggestPasswordSetup: Signal<Bool, NoError>
if case .chatList(groupId: .root) = location, chatListFilter == nil {
suggestPasswordSetup = combineLatest(
getServerProvidedSuggestions(account: context.account),
context.engine.auth.twoStepVerificationConfiguration()
)
|> map { suggestions, configuration -> Bool in
var notSet = false
switch configuration {
case let .notSet(pendingEmail):
if pendingEmail == nil {
notSet = true
}
case .set:
break
}
if !notSet {
return false
}
return suggestions.contains(.setupPassword)
}
|> distinctUntilChanged
} else {
suggestPasswordSetup = .single(false)
}
let storageInfo: Signal<Double?, NoError>
if !"".isEmpty, case .chatList(groupId: .root) = location, chatListFilter == nil {
let totalSizeSignal = combineLatest(context.account.postbox.mediaBox.storageBox.totalSize(), context.account.postbox.mediaBox.cacheStorageBox.totalSize())
@@ -1431,13 +1484,13 @@ public final class ChatListNode: ListView {
let currentPeerId: EnginePeer.Id = context.account.peerId
let chatListNodeViewTransition = combineLatest(queue: viewProcessingQueue, hideArchivedFolderByDefault, displayArchiveIntro, storageInfo, savedMessagesPeer, chatListViewUpdate, self.statePromise.get())
|> mapToQueue { (hideArchivedFolderByDefault, displayArchiveIntro, storageInfo, savedMessagesPeer, updateAndFilter, state) -> Signal<ChatListNodeListViewTransition, NoError> in
let chatListNodeViewTransition = combineLatest(queue: viewProcessingQueue, hideArchivedFolderByDefault, displayArchiveIntro, storageInfo, suggestPasswordSetup, savedMessagesPeer, chatListViewUpdate, self.statePromise.get())
|> mapToQueue { (hideArchivedFolderByDefault, displayArchiveIntro, storageInfo, suggestPasswordSetup, savedMessagesPeer, updateAndFilter, state) -> Signal<ChatListNodeListViewTransition, NoError> in
let (update, filter) = updateAndFilter
let previousHideArchivedFolderByDefaultValue = previousHideArchivedFolderByDefault.swap(hideArchivedFolderByDefault)
let (rawEntries, isLoading) = chatListNodeEntriesForView(update.list, state: state, savedMessagesPeer: savedMessagesPeer, foundPeers: state.foundPeers, hideArchivedFolderByDefault: hideArchivedFolderByDefault, displayArchiveIntro: displayArchiveIntro, storageInfo: storageInfo, mode: mode, chatListLocation: location)
let (rawEntries, isLoading) = chatListNodeEntriesForView(update.list, state: state, savedMessagesPeer: savedMessagesPeer, foundPeers: state.foundPeers, hideArchivedFolderByDefault: hideArchivedFolderByDefault, displayArchiveIntro: displayArchiveIntro, storageInfo: storageInfo, suggestPasswordSetup: suggestPasswordSetup, mode: mode, chatListLocation: location)
let entries = rawEntries.filter { entry in
switch entry {
case let .PeerEntry(peerEntry):
@@ -2467,7 +2520,7 @@ public final class ChatListNode: ListView {
} else {
break loop
}
case .ArchiveIntro, .StorageInfo, .HeaderEntry, .AdditionalCategory:
case .ArchiveIntro, .Notice, .HeaderEntry, .AdditionalCategory:
break
}
}

View File

@@ -13,7 +13,7 @@ enum ChatListNodeEntryId: Hashable {
case ThreadId(Int64)
case GroupId(EngineChatList.Group)
case ArchiveIntro
case StorageInfo
case Notice
case additionalCategory(Int)
}
@@ -46,6 +46,11 @@ public enum ChatListNodeEntryPromoInfo: Equatable {
case psa(type: String, message: String?)
}
enum ChatListNotice: Equatable {
case clearStorage(sizeFraction: Double)
case setupPassword
}
enum ChatListNodeEntry: Comparable, Identifiable {
struct PeerEntryData: Equatable {
var index: EngineChatList.Item.Index
@@ -235,7 +240,7 @@ enum ChatListNodeEntry: Comparable, Identifiable {
case HoleEntry(EngineMessage.Index, theme: PresentationTheme)
case GroupReferenceEntry(index: EngineChatList.Item.Index, presentationData: ChatListPresentationData, groupId: EngineChatList.Group, peers: [EngineChatList.GroupItem.Item], message: EngineMessage?, editing: Bool, unreadCount: Int, revealed: Bool, hiddenByDefault: Bool)
case ArchiveIntro(presentationData: ChatListPresentationData)
case StorageInfo(presentationData: ChatListPresentationData, sizeFraction: Double)
case Notice(presentationData: ChatListPresentationData, notice: ChatListNotice)
case AdditionalCategory(index: Int, id: Int, title: String, image: UIImage?, appearance: ChatListNodeAdditionalCategory.Appearance, selected: Bool, presentationData: ChatListPresentationData)
var sortIndex: ChatListNodeEntrySortIndex {
@@ -250,7 +255,7 @@ enum ChatListNodeEntry: Comparable, Identifiable {
return .index(index)
case .ArchiveIntro:
return .index(.chatList(EngineChatList.Item.Index.ChatList.absoluteUpperBound.successor))
case .StorageInfo:
case .Notice:
return .index(.chatList(EngineChatList.Item.Index.ChatList.absoluteUpperBound.successor.successor))
case let .AdditionalCategory(index, _, _, _, _, _, _):
return .additionalCategory(index)
@@ -274,8 +279,8 @@ enum ChatListNodeEntry: Comparable, Identifiable {
return .GroupId(groupId)
case .ArchiveIntro:
return .ArchiveIntro
case .StorageInfo:
return .StorageInfo
case .Notice:
return .Notice
case let .AdditionalCategory(_, id, _, _, _, _, _):
return .additionalCategory(id)
}
@@ -348,8 +353,8 @@ enum ChatListNodeEntry: Comparable, Identifiable {
} else {
return false
}
case let .StorageInfo(lhsPresentationData, lhsInfo):
if case let .StorageInfo(rhsPresentationData, rhsInfo) = rhs {
case let .Notice(lhsPresentationData, lhsInfo):
if case let .Notice(rhsPresentationData, rhsInfo) = rhs {
if lhsPresentationData !== rhsPresentationData {
return false
}
@@ -399,7 +404,7 @@ private func offsetPinnedIndex(_ index: EngineChatList.Item.Index, offset: UInt1
}
}
func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState, savedMessagesPeer: EnginePeer?, foundPeers: [(EnginePeer, EnginePeer?)], hideArchivedFolderByDefault: Bool, displayArchiveIntro: Bool, storageInfo: Double?, mode: ChatListNodeMode, chatListLocation: ChatListControllerLocation) -> (entries: [ChatListNodeEntry], loading: Bool) {
func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState, savedMessagesPeer: EnginePeer?, foundPeers: [(EnginePeer, EnginePeer?)], hideArchivedFolderByDefault: Bool, displayArchiveIntro: Bool, storageInfo: Double?, suggestPasswordSetup: Bool, mode: ChatListNodeMode, chatListLocation: ChatListControllerLocation) -> (entries: [ChatListNodeEntry], loading: Bool) {
var result: [ChatListNodeEntry] = []
var pinnedIndexOffset: UInt16 = 0
@@ -661,8 +666,10 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState
if displayArchiveIntro {
result.append(.ArchiveIntro(presentationData: state.presentationData))
}
if let storageInfo {
result.append(.StorageInfo(presentationData: state.presentationData, sizeFraction: storageInfo))
if suggestPasswordSetup {
result.append(.Notice(presentationData: state.presentationData, notice: .setupPassword))
} else if let storageInfo {
result.append(.Notice(presentationData: state.presentationData, notice: .clearStorage(sizeFraction: storageInfo)))
}
result.append(.HeaderEntry)

View File

@@ -11,15 +11,15 @@ import AppBundle
class ChatListStorageInfoItem: ListViewItem {
let theme: PresentationTheme
let strings: PresentationStrings
let sizeFraction: Double
let notice: ChatListNotice
let action: () -> Void
let selectable: Bool = true
init(theme: PresentationTheme, strings: PresentationStrings, sizeFraction: Double, action: @escaping () -> Void) {
init(theme: PresentationTheme, strings: PresentationStrings, notice: ChatListNotice, action: @escaping () -> Void) {
self.theme = theme
self.strings = strings
self.sizeFraction = sizeFraction
self.notice = notice
self.action = action
}
@@ -117,23 +117,37 @@ class ChatListStorageInfoItemNode: ListViewItemNode {
let _ = baseWidth
let sideInset: CGFloat = params.leftInset + 16.0
let height: CGFloat = 54.0
let rightInset: CGFloat = sideInset + 24.0
let verticalInset: CGFloat = 8.0
let spacing: CGFloat = 0.0
let themeUpdated = item.theme !== previousItem?.theme
let sizeString = dataSizeString(Int64(item.sizeFraction), formatting: DataSizeStringFormatting(strings: item.strings, decimalSeparator: "."))
let rawTitleString = item.strings.ChatList_StorageHintTitle(sizeString)
let titleString = NSMutableAttributedString(attributedString: NSAttributedString(string: rawTitleString.string, font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor))
if let range = rawTitleString.ranges.first {
titleString.addAttribute(.foregroundColor, value: item.theme.rootController.navigationBar.accentTextColor, range: range.range)
let titleString: NSAttributedString
let textString: NSAttributedString
switch item.notice {
case let .clearStorage(sizeFraction):
let sizeString = dataSizeString(Int64(sizeFraction), formatting: DataSizeStringFormatting(strings: item.strings, decimalSeparator: "."))
let rawTitleString = item.strings.ChatList_StorageHintTitle(sizeString)
let titleStringValue = NSMutableAttributedString(attributedString: NSAttributedString(string: rawTitleString.string, font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor))
if let range = rawTitleString.ranges.first {
titleStringValue.addAttribute(.foregroundColor, value: item.theme.rootController.navigationBar.accentTextColor, range: range.range)
}
titleString = titleStringValue
textString = NSAttributedString(string: item.strings.ChatList_StorageHintText, font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
case .setupPassword:
//TODO:localize
titleString = NSAttributedString(string: "Protect Your Account", font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor)
textString = NSAttributedString(string: "Set a password that will be required each time you log in with this phone number.", font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
}
let titleLayout = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - sideInset - rightInset, height: 100.0)))
let textLayout = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.strings.ChatList_StorageHintText, font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor), maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - sideInset - rightInset, height: 100.0)))
let textLayout = makeTextLayout(TextNodeLayoutArguments(attributedString: textString, maximumNumberOfLines: 5, truncationType: .end, constrainedSize: CGSize(width: params.width - sideInset - rightInset, height: 100.0)))
let layout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: height), insets: UIEdgeInsets())
let layout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: verticalInset * 2.0 + titleLayout.0.size.height + textLayout.0.size.height), insets: UIEdgeInsets())
return (layout, { [weak self] in
if let strongSelf = self {
@@ -148,10 +162,10 @@ class ChatListStorageInfoItemNode: ListViewItemNode {
strongSelf.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - UIScreenPixel), size: CGSize(width: layout.size.width, height: UIScreenPixel))
let _ = titleLayout.1()
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: sideInset, y: 9.0), size: titleLayout.0.size)
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: sideInset, y: verticalInset), size: titleLayout.0.size)
let _ = textLayout.1()
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: sideInset, y: strongSelf.titleNode.frame.maxY - 0.0), size: textLayout.0.size)
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: sideInset, y: strongSelf.titleNode.frame.maxY + spacing), size: textLayout.0.size)
if let image = strongSelf.arrowNode.image {
strongSelf.arrowNode.frame = CGRect(origin: CGPoint(x: layout.size.width - sideInset - image.size.width + 8.0, y: floor((layout.size.height - image.size.height) / 2.0)), size: image.size)