Update settings screen

This commit is contained in:
Ilya Laktyushin
2020-07-07 02:48:35 +03:00
parent 76a340cff8
commit 37895d675b
61 changed files with 6484 additions and 4636 deletions

View File

@@ -258,19 +258,33 @@ private enum SettingsSearchRecentEntryStableId: Hashable {
}
private enum SettingsSearchRecentEntry: Comparable, Identifiable {
case recent(Int, SettingsSearchableItem)
case recent(Int, SettingsSearchableItem, ChatListSearchItemHeader)
case faq(Int, SettingsSearchableItem, ChatListSearchItemHeader)
var stableId: SettingsSearchRecentEntryStableId {
switch self {
case let .recent(_, item):
case let .recent(_, item, _), let .faq(_, item, _):
return .recent(item.id)
}
}
var header: ChatListSearchItemHeader {
switch self {
case let .recent(_, _, header), let .faq(_, _, header):
return header
}
}
static func ==(lhs: SettingsSearchRecentEntry, rhs: SettingsSearchRecentEntry) -> Bool {
switch lhs {
case let .recent(lhsIndex, lhsItem):
if case let .recent(rhsIndex, rhsItem) = rhs, lhsIndex == rhsIndex, lhsItem.id == rhsItem.id {
case let .recent(lhsIndex, lhsItem, lhsHeader):
if case let .recent(rhsIndex, rhsItem, rhsHeader) = rhs, lhsIndex == rhsIndex, lhsItem.id == rhsItem.id, lhsHeader.id == rhsHeader.id {
return true
} else {
return false
}
case let .faq(lhsIndex, lhsItem, lhsHeader):
if case let .faq(rhsIndex, rhsItem, rhsHeader) = rhs, lhsIndex == rhsIndex, lhsItem.id == rhsItem.id, lhsHeader.id == rhsHeader.id {
return true
} else {
return false
@@ -280,17 +294,26 @@ private enum SettingsSearchRecentEntry: Comparable, Identifiable {
static func <(lhs: SettingsSearchRecentEntry, rhs: SettingsSearchRecentEntry) -> Bool {
switch lhs {
case let .recent(lhsIndex, _):
case let .recent(lhsIndex, _, _):
switch rhs {
case let .recent(rhsIndex, _):
case let .recent(rhsIndex, _, _):
return lhsIndex <= rhsIndex
case .faq:
return false
}
case let .faq(lhsIndex, _, _):
switch rhs {
case .recent:
return true
case let .faq(rhsIndex, _, _):
return lhsIndex <= rhsIndex
}
}
}
func item(account: Account, theme: PresentationTheme, strings: PresentationStrings, interaction: SettingsSearchInteraction, header: ListViewItemHeader) -> ListViewItem {
func item(account: Account, theme: PresentationTheme, strings: PresentationStrings, interaction: SettingsSearchInteraction) -> ListViewItem {
switch self {
case let .recent(_, item):
case let .recent(_, item, header), let .faq(_, item, header):
return SettingsSearchRecentItem(account: account, theme: theme, strings: strings, title: item.title, breadcrumbs: item.breadcrumbs, action: {
interaction.openItem(item)
}, deleted: {
@@ -307,18 +330,18 @@ private struct SettingsSearchContainerRecentTransition {
let isEmpty: Bool
}
private func preparedSettingsSearchContainerRecentTransition(from fromEntries: [SettingsSearchRecentEntry], to toEntries: [SettingsSearchRecentEntry], account: Account, theme: PresentationTheme, strings: PresentationStrings, interaction: SettingsSearchInteraction, header: ListViewItemHeader) -> SettingsSearchContainerRecentTransition {
private func preparedSettingsSearchContainerRecentTransition(from fromEntries: [SettingsSearchRecentEntry], to toEntries: [SettingsSearchRecentEntry], account: Account, theme: PresentationTheme, strings: PresentationStrings, interaction: SettingsSearchInteraction) -> SettingsSearchContainerRecentTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, interaction: interaction, header: header), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, interaction: interaction, header: header), directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, interaction: interaction), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, interaction: interaction), directionHint: nil) }
return SettingsSearchContainerRecentTransition(deletions: deletions, insertions: insertions, updates: updates, isEmpty: toEntries.isEmpty)
}
private final class SettingsSearchContainerNode: SearchDisplayControllerContentNode {
public final class SettingsSearchContainerNode: SearchDisplayControllerContentNode {
private let listNode: ListView
private let recentListNode: ListView
@@ -335,7 +358,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
private var presentationDataDisposable: Disposable?
private let presentationDataPromise: Promise<PresentationData>
init(context: AccountContext, openResult: @escaping (SettingsSearchableItem) -> Void, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, hasWallet: Signal<Bool, NoError>, activeSessionsContext: Signal<ActiveSessionsContext?, NoError>, webSessionsContext: Signal<WebSessionsContext?, NoError>) {
public init(context: AccountContext, openResult: @escaping (SettingsSearchableItem) -> Void, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, hasWallet: Signal<Bool, NoError>, activeSessionsContext: Signal<ActiveSessionsContext?, NoError>, webSessionsContext: Signal<WebSessionsContext?, NoError>) {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.presentationDataPromise = Promise(self.presentationData)
@@ -354,14 +377,20 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
self.addSubnode(self.recentListNode)
self.addSubnode(self.listNode)
let interaction = SettingsSearchInteraction(openItem: openResult, deleteRecentItem: { id in
let interaction = SettingsSearchInteraction(openItem: { result in
addRecentSettingsSearchItem(postbox: context.account.postbox, item: result.id)
openResult(result)
}, deleteRecentItem: { id in
removeRecentSettingsSearchItem(postbox: context.account.postbox, item: id)
})
let searchableItems = Promise<[SettingsSearchableItem]>()
searchableItems.set(settingsSearchableItems(context: context, notificationExceptionsList: exceptionsList, archivedStickerPacks: archivedStickerPacks, privacySettings: privacySettings, hasWallet: hasWallet, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext))
let queryAndFoundItems = combineLatest(searchableItems.get(), faqSearchableItems(context: context))
let faqItems = Promise<[SettingsSearchableItem]>()
faqItems.set(faqSearchableItems(context: context, suggestAccountDeletion: false))
let queryAndFoundItems = combineLatest(searchableItems.get(), faqSearchableItems(context: context, suggestAccountDeletion: true))
|> mapToSignal { searchableItems, faqSearchableItems -> Signal<(String, [SettingsSearchableItem])?, NoError> in
return self.searchQuery.get()
|> mapToSignal { query -> Signal<(String, [SettingsSearchableItem])?, NoError> in
@@ -429,20 +458,26 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
}
let previousRecentItems = Atomic<[SettingsSearchRecentEntry]?>(value: nil)
self.recentDisposable = (combineLatest(recentSearchItems, self.presentationDataPromise.get())
|> deliverOnMainQueue).start(next: { [weak self] recentSearchItems, presentationData in
self.recentDisposable = (combineLatest(recentSearchItems, faqItems.get(), self.presentationDataPromise.get())
|> deliverOnMainQueue).start(next: { [weak self] recentSearchItems, faqItems, presentationData in
if let strongSelf = self {
var entries: [SettingsSearchRecentEntry] = []
for i in 0 ..< recentSearchItems.count {
entries.append(.recent(i, recentSearchItems[i]))
}
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: {
let recentHeader = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: {
clearRecentSettingsSearchItems(postbox: context.account.postbox)
})
let faqHeader = ChatListSearchItemHeader(type: .faq, theme: presentationData.theme, strings: presentationData.strings)
var entries: [SettingsSearchRecentEntry] = []
for i in 0 ..< recentSearchItems.count {
entries.append(.recent(i, recentSearchItems[i], recentHeader))
}
for i in 0 ..< faqItems.count {
entries.append(.faq(i, faqItems[i], faqHeader))
}
let previousEntries = previousRecentItems.swap(entries)
let transition = preparedSettingsSearchContainerRecentTransition(from: previousEntries ?? [], to: entries, account: context.account, theme: presentationData.theme, strings: presentationData.strings, interaction: interaction, header: header)
let transition = preparedSettingsSearchContainerRecentTransition(from: previousEntries ?? [], to: entries, account: context.account, theme: presentationData.theme, strings: presentationData.strings, interaction: interaction)
strongSelf.enqueueRecentTransition(transition, firstTime: previousEntries == nil)
}
})
@@ -510,7 +545,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
self.recentListNode.verticalScrollIndicatorColor = theme.list.scrollIndicatorColor
}
override func searchTextUpdated(text: String) {
public override func searchTextUpdated(text: String) {
if text.isEmpty {
self.searchQuery.set(.single(nil))
} else {
@@ -569,7 +604,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
}
}
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
public override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition)
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
@@ -593,7 +628,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
}
}
override func scrollToTop() {
public override func scrollToTop() {
let listNodeToScroll: ListView
if !self.listNode.isHidden {
listNodeToScroll = self.listNode
@@ -657,8 +692,6 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode {
self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: SettingsSearchContainerNode(context: self.context, openResult: { [weak self] result in
if let strongSelf = self {
addRecentSettingsSearchItem(postbox: strongSelf.context.account.postbox, item: result.id)
result.present(strongSelf.context, strongSelf.getNavigationController?(), { [weak self] mode, controller in
if let strongSelf = self {
switch mode {