This commit is contained in:
Ilya Laktyushin 2019-03-20 14:02:37 +04:00
parent 4f3f07b902
commit cfc495ff88
12 changed files with 1511 additions and 1447 deletions

View File

@ -31,7 +31,7 @@ private let newlineScalar = "\n" as UnicodeScalar
private let hashScalar = "#" as UnicodeScalar
private let atScalar = "@" as UnicodeScalar
private let slashScalar = "/" as UnicodeScalar
private let dotsScalar = ":" as UnicodeScalar
private let colonScalar = ":" as UnicodeScalar
private let alphanumerics = CharacterSet.alphanumerics
private func scalarCanPrependQueryControl(_ c: UnicodeScalar?) -> Bool {
@ -101,7 +101,8 @@ func textInputStateContextQueryRangeAndType(_ inputState: ChatTextInputState) ->
var possibleQueryRange: NSRange?
if (inputString as String).isSingleEmoji {
let string = (inputString as String)
if string.count < 3, string.trimmingTrailingSpaces().isSingleEmoji {
return [(NSRange(location: 0, length: inputLength), [.emoji], nil)]
}
@ -140,7 +141,7 @@ func textInputStateContextQueryRangeAndType(_ inputState: ChatTextInputState) ->
possibleQueryRange = NSRange(location: index, length: maxIndex - index)
}
break
} else if c == dotsScalar {
} else if c == colonScalar {
if scalarCanPrependQueryControl(previousC) {
possibleTypes = possibleTypes.intersection([.emojiSearch])
definedType = true
@ -231,11 +232,6 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
switch chatPresentationInterfaceState.inputMode {
case .media:
// if contextPlaceholder == nil && chatPresentationInterfaceState.interfaceState.editMessage == nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0, case .media(.gif, _) = chatPresentationInterfaceState.inputMode {
// let baseFontSize: CGFloat = max(17.0, chatPresentationInterfaceState.fontSize.baseDisplaySize)
//
// contextPlaceholder = NSAttributedString(string: "@gif", font: Font.regular(baseFontSize), textColor: chatPresentationInterfaceState.theme.chat.inputPanel.inputPlaceholderColor)
// }
accessoryItems.append(.keyboard)
return ChatTextInputPanelState(accessoryItems: accessoryItems, contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
case .inputButtons:
@ -286,7 +282,3 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
}
}
}
func urlPreviewForPresentationInterfaceState() {
}

View File

@ -21,6 +21,14 @@ extension UnicodeScalar {
}
extension String {
func trimmingTrailingSpaces() -> String {
var t = self
while t.hasSuffix(" ") {
t = "" + t.dropLast()
}
return t
}
var glyphCount: Int {
let richText = NSAttributedString(string: self)
let line = CTLineCreateWithAttributedString(richText)

View File

@ -78,20 +78,30 @@ struct InstantPageGalleryEntry: Equatable {
if let image = self.media.media as? TelegramMediaImage {
return InstantImageGalleryItem(context: context, presentationData: presentationData, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions)
} else if let file = self.media.media as? TelegramMediaFile, file.isVideo {
var indexData: GalleryItemIndexData?
if let location = self.location {
indexData = GalleryItemIndexData(position: location.position, totalCount: location.totalCount)
}
let nativeId: NativeVideoContentId
if let message = message, case let .Loaded(content) = webPage.content, content.file?.fileId == file.fileId {
nativeId = .message(message.id, message.stableId, file.fileId)
} else if let file = self.media.media as? TelegramMediaFile {
if file.isVideo {
var indexData: GalleryItemIndexData?
if let location = self.location {
indexData = GalleryItemIndexData(position: location.position, totalCount: location.totalCount)
}
let nativeId: NativeVideoContentId
if let message = message, case let .Loaded(content) = webPage.content, content.file?.fileId == file.fileId {
nativeId = .message(message.id, message.stableId, file.fileId)
} else {
nativeId = .instantPage(self.pageId, file.fileId)
}
return UniversalVideoGalleryItem(context: context, presentationData: presentationData, content: NativeVideoContent(id: nativeId, fileReference: .webPage(webPage: WebpageReference(webPage), media: file), streamVideo: isMediaStreamable(media: file) ? .conservative : .none), originData: nil, indexData: indexData, contentInfo: .webPage(webPage, file), caption: caption, credit: credit, fromPlayingVideo: fromPlayingVideo, landscape: landscape, performAction: { _ in }, openActionOptions: { _ in })
} else {
nativeId = .instantPage(self.pageId, file.fileId)
var representations: [TelegramMediaImageRepresentation] = []
representations.append(contentsOf: file.previewRepresentations)
if let dimensions = file.dimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource))
}
let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: file.immediateThumbnailData, reference: nil, partialReference: nil)
return InstantImageGalleryItem(context: context, presentationData: presentationData, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions)
}
return UniversalVideoGalleryItem(context: context, presentationData: presentationData, content: NativeVideoContent(id: nativeId, fileReference: .webPage(webPage: WebpageReference(webPage), media: file), streamVideo: isMediaStreamable(media: file) ? .conservative : .none), originData: nil, indexData: indexData, contentInfo: .webPage(webPage, file), caption: caption, credit: credit, fromPlayingVideo: fromPlayingVideo, landscape: landscape, performAction: { _ in }, openActionOptions: { _ in })
} else if let embedWebpage = self.media.media as? TelegramMediaWebpage, case let .Loaded(webpageContent) = embedWebpage.content {
if let content = WebEmbedVideoContent(webPage: embedWebpage, webpageContent: webpageContent) {
return UniversalVideoGalleryItem(context: context, presentationData: presentationData, content: content, originData: nil, indexData: nil, contentInfo: .webPage(webPage, embedWebpage), caption: NSAttributedString(string: ""), fromPlayingVideo: fromPlayingVideo, landscape: landscape, performAction: { _ in }, openActionOptions: { _ in })

File diff suppressed because it is too large Load Diff

View File

@ -243,7 +243,7 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
private let backgroundNode: ASDisplayNode
private let separatorNode: ASDisplayNode
private let textBackgroundNode: ASImageNode
private let textBackgroundNode: ASDisplayNode
private var activityIndicator: ActivityIndicator?
private let iconNode: ASImageNode
private let textField: SearchBarTextField
@ -333,10 +333,10 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
self.textBackgroundNode = ASImageNode()
self.textBackgroundNode = ASDisplayNode()
self.textBackgroundNode.isLayerBacked = false
self.textBackgroundNode.displaysAsynchronously = false
self.textBackgroundNode.displayWithoutProcessing = true
self.textBackgroundNode.cornerRadius = self.fieldStyle.cornerDiameter / 2.0
self.iconNode = ASImageNode()
self.iconNode.isLayerBacked = true
@ -391,7 +391,7 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
if self.fieldStyle != .modern {
self.separatorNode.backgroundColor = theme.separator
}
self.textBackgroundNode.image = generateBackground(foregroundColor: theme.inputFill, diameter: self.fieldStyle.cornerDiameter)
self.textBackgroundNode.backgroundColor = theme.inputFill
self.textField.textColor = theme.primaryText
self.clearButton.setImage(generateClearIcon(color: theme.inputClear), for: [])
self.iconNode.image = generateLoupeIcon(color: theme.inputIcon)
@ -472,6 +472,9 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
self.separatorNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration)
self.separatorNode.layer.animateFrame(from: initialSeparatorFrame, to: self.separatorNode.frame, duration: duration, timingFunction: timingFunction)
if let fromTextBackgroundColor = node.backgroundNode.backgroundColor, let toTextBackgroundColor = self.textBackgroundNode.backgroundColor {
self.textBackgroundNode.layer.animate(from: fromTextBackgroundColor.cgColor, to: toTextBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: timingFunction, duration: duration * 0.5)
}
self.textBackgroundNode.layer.animateFrame(from: initialTextBackgroundFrame, to: self.textBackgroundNode.frame, duration: duration, timingFunction: timingFunction)
let textFieldFrame = self.textField.frame

View File

@ -77,7 +77,7 @@ class SearchBarPlaceholderNode: ASDisplayNode {
return
}
if let _ = point {
strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9).cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.3)
strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9).cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.2)
strongSelf.backgroundNode.backgroundColor = strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9)
} else {
strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.4)

View File

@ -33,7 +33,7 @@ private struct SettingsItemArguments {
let openProxy: () -> Void
let openSavedMessages: () -> Void
let openRecentCalls: () -> Void
let openPrivacyAndSecurity: () -> Void
let openPrivacyAndSecurity: (AccountPrivacySettings?) -> Void
let openDataAndStorage: () -> Void
let openStickerPacks: ([ArchivedStickerPackItem]?) -> Void
let openNotificationsAndSounds: (NotificationExceptionsList?) -> Void
@ -77,7 +77,7 @@ private enum SettingsEntry: ItemListNodeEntry {
case stickers(PresentationTheme, UIImage?, String, String, [ArchivedStickerPackItem]?)
case notificationsAndSounds(PresentationTheme, UIImage?, String, NotificationExceptionsList?, Bool)
case privacyAndSecurity(PresentationTheme, UIImage?, String)
case privacyAndSecurity(PresentationTheme, UIImage?, String, AccountPrivacySettings?)
case dataAndStorage(PresentationTheme, UIImage?, String)
case themes(PresentationTheme, UIImage?, String)
case language(PresentationTheme, UIImage?, String, String)
@ -241,8 +241,8 @@ private enum SettingsEntry: ItemListNodeEntry {
} else {
return false
}
case let .privacyAndSecurity(lhsTheme, lhsImage, lhsText):
if case let .privacyAndSecurity(rhsTheme, rhsImage, rhsText) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText {
case let .privacyAndSecurity(lhsTheme, lhsImage, lhsText, _):
if case let .privacyAndSecurity(rhsTheme, rhsImage, rhsText, _) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText {
return true
} else {
return false
@ -363,9 +363,9 @@ private enum SettingsEntry: ItemListNodeEntry {
return ItemListDisclosureItem(theme: theme, icon: image, title: text, label: warning ? "!" : "", labelStyle: warning ? .badge(theme.list.itemDestructiveColor) : .text, sectionId: ItemListSectionId(self.section), style: .blocks, action: {
arguments.openNotificationsAndSounds(exceptionsList)
})
case let .privacyAndSecurity(theme, image, text):
case let .privacyAndSecurity(theme, image, text, privacySettings):
return ItemListDisclosureItem(theme: theme, icon: image, title: text, label: "", sectionId: ItemListSectionId(self.section), style: .blocks, action: {
arguments.openPrivacyAndSecurity()
arguments.openPrivacyAndSecurity(privacySettings)
})
case let .dataAndStorage(theme, image, text):
return ItemListDisclosureItem(theme: theme, icon: image, title: text, label: "", sectionId: ItemListSectionId(self.section), style: .blocks, action: {
@ -405,7 +405,7 @@ private struct SettingsState: Equatable {
var isSearching: Bool
}
private func settingsEntries(account: Account, presentationData: PresentationData, state: SettingsState, view: PeerView, proxySettings: ProxySettings, notifyExceptions: NotificationExceptionsList?, notificationsAuthorizationStatus: AccessType, notificationsWarningSuppressed: Bool, unreadTrendingStickerPacks: Int, archivedPacks: [ArchivedStickerPackItem]?, hasPassport: Bool, hasWatchApp: Bool, accountsAndPeers: [(Account, Peer, Int32)], inAppNotificationSettings: InAppNotificationSettings) -> [SettingsEntry] {
private func settingsEntries(account: Account, presentationData: PresentationData, state: SettingsState, view: PeerView, proxySettings: ProxySettings, notifyExceptions: NotificationExceptionsList?, notificationsAuthorizationStatus: AccessType, notificationsWarningSuppressed: Bool, unreadTrendingStickerPacks: Int, archivedPacks: [ArchivedStickerPackItem]?, privacySettings: AccountPrivacySettings?, hasPassport: Bool, hasWatchApp: Bool, accountsAndPeers: [(Account, Peer, Int32)], inAppNotificationSettings: InAppNotificationSettings) -> [SettingsEntry] {
var entries: [SettingsEntry] = []
if let peer = peerViewMainPeer(view) as? TelegramUser {
@ -450,7 +450,7 @@ private func settingsEntries(account: Account, presentationData: PresentationDat
let notificationsWarning = shouldDisplayNotificationsPermissionWarning(status: notificationsAuthorizationStatus, suppressed: notificationsWarningSuppressed)
entries.append(.notificationsAndSounds(presentationData.theme, PresentationResourcesSettings.notifications, presentationData.strings.Settings_NotificationsAndSounds, notifyExceptions, notificationsWarning))
entries.append(.privacyAndSecurity(presentationData.theme, PresentationResourcesSettings.security, presentationData.strings.Settings_PrivacySettings))
entries.append(.privacyAndSecurity(presentationData.theme, PresentationResourcesSettings.security, presentationData.strings.Settings_PrivacySettings, privacySettings))
entries.append(.dataAndStorage(presentationData.theme, PresentationResourcesSettings.dataAndStorage, presentationData.strings.Settings_ChatSettings))
entries.append(.themes(presentationData.theme, PresentationResourcesSettings.appearance, presentationData.strings.Settings_Appearance))
let languageName = presentationData.strings.primaryComponent.localizedName
@ -592,7 +592,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
let accountsAndPeers = Promise<((Account, Peer)?, [(Account, Peer, Int32)])>()
accountsAndPeers.set(activeAccountsAndPeers(context: context))
let privacySettings = Promise<[PeerId: AccountPrivacySettings]>([:])
let privacySettings = Promise<AccountPrivacySettings?>(nil)
let openFaq: (Promise<ResolvedUrl>) -> Void = { resolvedUrl in
let _ = (contextValue.get()
@ -677,23 +677,13 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|> take(1)).start(next: { context in
pushControllerImpl?(CallListController(context: context, mode: .navigation))
})
}, openPrivacyAndSecurity: {
}, openPrivacyAndSecurity: { privacySettingsValue in
let _ = (contextValue.get()
|> deliverOnMainQueue
|> take(1)).start(next: { context in
let _ = (privacySettings.get()
|> take(1)
|> deliverOnMainQueue).start(next: { settings in
pushControllerImpl?(privacyAndSecurityController(context: context, initialSettings: settings[context.account.peerId], updatedSettings: { settings in
let _ = ((privacySettings.get()
|> take(1)
|> deliverOnMainQueue).start(next: { currentPrivacySettings in
var updatedPrivacySettings = currentPrivacySettings
updatedPrivacySettings[context.account.peerId] = settings
privacySettings.set(.single(updatedPrivacySettings))
}))
}))
})
pushControllerImpl?(privacyAndSecurityController(context: context, initialSettings: privacySettingsValue, updatedSettings: { settings in
privacySettings.set(.single(settings))
}))
})
}, openDataAndStorage: {
let _ = (contextValue.get()
@ -1025,6 +1015,17 @@ public func settingsController(context: AccountContext, accountManager: AccountM
)
}
privacySettings.set(
.single(nil)
|> then(
contextValue.get()
|> mapToSignal { context -> Signal<AccountPrivacySettings?, NoError> in
requestAccountPrivacySettings(account: context.account)
|> map(Optional.init)
}
)
)
let hasWatchApp = Promise<Bool>(false)
hasWatchApp.set(
contextValue.get()
@ -1049,7 +1050,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
return context.account.viewTracker.featuredStickerPacks()
}
let signal = combineLatest(queue: Queue.mainQueue(), contextValue.get(), updatedPresentationData, statePromise.get(), peerView, combineLatest(queue: Queue.mainQueue(), preferences, notifyExceptions.get(), notificationsAuthorizationStatus.get(), notificationsWarningSuppressed.get()), combineLatest(featuredStickerPacks, archivedPacks.get()), combineLatest(hasPassport.get(), hasWatchApp.get()), accountsAndPeers.get())
let signal = combineLatest(queue: Queue.mainQueue(), contextValue.get(), updatedPresentationData, statePromise.get(), peerView, combineLatest(queue: Queue.mainQueue(), preferences, notifyExceptions.get(), notificationsAuthorizationStatus.get(), notificationsWarningSuppressed.get(), privacySettings.get()), combineLatest(featuredStickerPacks, archivedPacks.get()), combineLatest(hasPassport.get(), hasWatchApp.get()), accountsAndPeers.get())
|> map { context, presentationData, state, view, preferencesAndExceptions, featuredAndArchived, hasPassportAndWatch, accountsAndPeers -> (ItemListControllerState, (ItemListNodeState<SettingsEntry>, SettingsEntry.ItemGenerationArguments)) in
let proxySettings: ProxySettings = preferencesAndExceptions.0.entries[SharedDataKeys.proxySettings] as? ProxySettings ?? ProxySettings.defaultSettings
let inAppNotificationSettings: InAppNotificationSettings = preferencesAndExceptions.0.entries[ApplicationSpecificSharedDataKeys.inAppNotificationSettings] as? InAppNotificationSettings ?? InAppNotificationSettings.defaultSettings
@ -1084,10 +1085,10 @@ public func settingsController(context: AccountContext, accountManager: AccountM
presentControllerImpl?(v, a)
}, pushController: { v in
pushControllerImpl?(v)
}, getNavigationController: getNavigationControllerImpl, exceptionsList: notifyExceptions.get())
}, getNavigationController: getNavigationControllerImpl, exceptionsList: notifyExceptions.get(), archivedStickerPacks: archivedPacks.get())
let (hasPassport, hasWatchApp) = hasPassportAndWatch
let listState = ItemListNodeState(entries: settingsEntries(account: context.account, presentationData: presentationData, state: state, view: view, proxySettings: proxySettings, notifyExceptions: preferencesAndExceptions.1, notificationsAuthorizationStatus: preferencesAndExceptions.2, notificationsWarningSuppressed: preferencesAndExceptions.3, unreadTrendingStickerPacks: unreadTrendingStickerPacks, archivedPacks: featuredAndArchived.1, hasPassport: hasPassport, hasWatchApp: hasWatchApp, accountsAndPeers: accountsAndPeers.1, inAppNotificationSettings: inAppNotificationSettings), style: .blocks, searchItem: searchItem, initialScrollToItem: ListViewScrollToItem(index: 0, position: .top(-navigationBarSearchContentHeight), animated: false, curve: .Default(duration: 0.0), directionHint: .Up))
let listState = ItemListNodeState(entries: settingsEntries(account: context.account, presentationData: presentationData, state: state, view: view, proxySettings: proxySettings, notifyExceptions: preferencesAndExceptions.1, notificationsAuthorizationStatus: preferencesAndExceptions.2, notificationsWarningSuppressed: preferencesAndExceptions.3, unreadTrendingStickerPacks: unreadTrendingStickerPacks, archivedPacks: featuredAndArchived.1, privacySettings: preferencesAndExceptions.4, hasPassport: hasPassport, hasWatchApp: hasWatchApp, accountsAndPeers: accountsAndPeers.1, inAppNotificationSettings: inAppNotificationSettings), style: .blocks, searchItem: searchItem, initialScrollToItem: ListViewScrollToItem(index: 0, position: .top(-navigationBarSearchContentHeight), animated: false, curve: .Default(duration: 0.0), directionHint: .Up))
return (controllerState, (listState, arguments))
}

View File

@ -61,12 +61,13 @@ final class SettingsSearchItem: ItemListControllerSearch {
let pushController: (ViewController) -> Void
let getNavigationController: (() -> NavigationController?)?
let exceptionsList: Signal<NotificationExceptionsList?, NoError>
let archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>
private var updateActivity: ((Bool) -> Void)?
private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false)
private let activityDisposable = MetaDisposable()
init(context: AccountContext, theme: PresentationTheme, placeholder: String, activated: Bool, updateActivated: @escaping (Bool) -> Void, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal<NotificationExceptionsList?, NoError>) {
init(context: AccountContext, theme: PresentationTheme, placeholder: String, activated: Bool, updateActivated: @escaping (Bool) -> Void, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>) {
self.context = context
self.theme = theme
self.placeholder = placeholder
@ -76,6 +77,7 @@ final class SettingsSearchItem: ItemListControllerSearch {
self.pushController = pushController
self.getNavigationController = getNavigationController
self.exceptionsList = exceptionsList
self.archivedStickerPacks = archivedStickerPacks
self.activityDisposable.set((activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in
if value {
return .single(value) |> delay(0.2, queue: Queue.mainQueue())
@ -139,7 +141,7 @@ final class SettingsSearchItem: ItemListControllerSearch {
pushController(c)
}, presentController: { c, a in
presentController(c, a)
}, getNavigationController: self.getNavigationController, exceptionsList: self.exceptionsList)
}, getNavigationController: self.getNavigationController, exceptionsList: self.exceptionsList, archivedStickerPacks: self.archivedStickerPacks)
}
}
}
@ -315,7 +317,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>) {
init(context: AccountContext, openResult: @escaping (SettingsSearchableItem) -> Void, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>) {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.presentationDataPromise = Promise(self.presentationData)
@ -343,7 +345,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
})
let searchableItems = Promise<[SettingsSearchableItem]>()
searchableItems.set(settingsSearchableItems(context: context, notificationExceptionsList: exceptionsList))
searchableItems.set(settingsSearchableItems(context: context, notificationExceptionsList: exceptionsList, archivedStickerPacks: archivedStickerPacks))
let queryAndFoundItems = combineLatest(searchableItems.get(), faqSearchableItems(context: context))
|> mapToSignal { searchableItems, faqSearchableItems -> Signal<(String, [SettingsSearchableItem])?, NoError> in
@ -367,7 +369,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
self.recentListNode.isHidden = false
let recentSearchItems = combineLatest(searchableItems.get(), settingsSearchRecentItems(postbox: context.account.postbox))
let recentSearchItems = combineLatest(searchableItems.get(), settingsSearchRecentItems(postbox: context.account.postbox) |> take(1))
|> map { searchableItems, recentItems -> [SettingsSearchableItem] in
let searchableItemsMap = searchableItems.reduce([SettingsSearchableItemId : SettingsSearchableItem]()) { (map, item) -> [SettingsSearchableItemId: SettingsSearchableItem] in
var map = map
@ -605,10 +607,11 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode {
let presentController: (ViewController, Any?) -> Void
let getNavigationController: (() -> NavigationController?)?
let exceptionsList: Signal<NotificationExceptionsList?, NoError>
let archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>
var cancel: () -> Void
init(context: AccountContext, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal<NotificationExceptionsList?, NoError>) {
init(context: AccountContext, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>) {
self.context = context
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.cancel = cancel
@ -616,6 +619,7 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode {
self.presentController = presentController
self.getNavigationController = getNavigationController
self.exceptionsList = exceptionsList
self.archivedStickerPacks = archivedStickerPacks
super.init()
}
@ -649,7 +653,7 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode {
}
})
}
}, exceptionsList: self.exceptionsList), cancel: { [weak self] in
}, exceptionsList: self.exceptionsList, archivedStickerPacks: self.archivedStickerPacks), cancel: { [weak self] in
self?.cancel()
})

View File

@ -0,0 +1,42 @@
import Foundation
import Display
final class SettingsSearchItemHeader: ListViewItemHeader {
let id: Int64
let icon: UIImage
let stickDirection: ListViewItemHeaderStickDirection = .top
let height: CGFloat = 29.0
init(id: Int64, icon: UIImage) {
self.id = id
self.icon = icon
}
func node() -> ListViewItemHeaderNode {
return SettingsSearchItemHeaderNode(icon : self.icon)
}
}
final class SettingsSearchItemHeaderNode: ListViewItemHeaderNode {
private let iconNode: ASImageNode
init(icon: UIImage) {
self.iconNode = ASImageNode()
super.init()
self.iconNode.image = icon
self.addSubnode(self.iconNode)
}
override func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
self.iconNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 10.0, height: 10.0))
}
override func animateRemoved(duration: Double) {
self.alpha = 0.0
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false)
}
}

View File

@ -23,8 +23,6 @@ enum SettingsSearchableItemIcon {
case faq
}
enum SettingsSearchableItemId: Hashable {
case profile(Int32)
case proxy(Int32)
@ -152,7 +150,7 @@ struct SettingsSearchableItem {
}
private func synonyms(_ string: String?) -> [String] {
if let string = string {
if let string = string, !string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
return string.components(separatedBy: "|")
} else {
return []
@ -227,33 +225,34 @@ private func callSearchableItems(context: AccountContext) -> [SettingsSearchable
]
}
private func stickerSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
private func stickerSearchableItems(context: AccountContext, hasArchivedStickerPacks: Bool) -> [SettingsSearchableItem] {
let icon: SettingsSearchableItemIcon = .stickers
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
let presentStickerSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController) -> Void, InstalledStickerPacksEntryTag?) -> Void = { context, present, itemTag in
present(.push, installedStickerPacksController(context: context, mode: .general, archivedPacks: nil, updatedPacks: { _ in
}, focusOnItemTag: itemTag))
present(.push, installedStickerPacksController(context: context, mode: .general, archivedPacks: nil, updatedPacks: { _ in }, focusOnItemTag: itemTag))
}
return [
SettingsSearchableItem(id: .stickers(0), title: strings.ChatSettings_Stickers, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_Title), icon: icon, breadcrumbs: [], present: { context, _, present in
presentStickerSettings(context, present, nil)
}),
SettingsSearchableItem(id: .stickers(1), title: strings.Stickers_SuggestStickers, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_SuggestStickers), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
presentStickerSettings(context, present, .suggestOptions)
}),
SettingsSearchableItem(id: .stickers(2), title: strings.StickerPacksSettings_FeaturedPacks, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_FeaturedPacks), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
present(.push, featuredStickerPacksController(context: context))
}),
SettingsSearchableItem(id: .stickers(3), title: strings.StickerPacksSettings_ArchivedPacks, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_ArchivedPacks), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
present(.push, archivedStickerPacksController(context: context, mode: .stickers, archived: nil, updatedPacks: { _ in
}))
}),
SettingsSearchableItem(id: .stickers(4), title: strings.MaskStickerSettings_Title, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_Masks), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
present(.push, installedStickerPacksController(context: context, mode: .masks, archivedPacks: nil, updatedPacks: { _ in}))
})
]
var items: [SettingsSearchableItem] = []
items.append(SettingsSearchableItem(id: .stickers(0), title: strings.ChatSettings_Stickers, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_Title), icon: icon, breadcrumbs: [], present: { context, _, present in
presentStickerSettings(context, present, nil)
}))
items.append(SettingsSearchableItem(id: .stickers(1), title: strings.Stickers_SuggestStickers, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_SuggestStickers), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
presentStickerSettings(context, present, .suggestOptions)
}))
items.append(SettingsSearchableItem(id: .stickers(2), title: strings.StickerPacksSettings_FeaturedPacks, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_FeaturedPacks), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
present(.push, featuredStickerPacksController(context: context))
}))
if hasArchivedStickerPacks {
items.append(SettingsSearchableItem(id: .stickers(3), title: strings.StickerPacksSettings_ArchivedPacks, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_ArchivedPacks), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
present(.push, archivedStickerPacksController(context: context, mode: .stickers, archived: nil, updatedPacks: { _ in }))
}))
}
items.append(SettingsSearchableItem(id: .stickers(4), title: strings.MaskStickerSettings_Title, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_Masks), icon: icon, breadcrumbs: [strings.ChatSettings_Stickers], present: { context, _, present in
present(.push, installedStickerPacksController(context: context, mode: .masks, archivedPacks: nil, updatedPacks: { _ in }))
}))
return items
}
private func notificationSearchableItems(context: AccountContext, settings: GlobalNotificationSettingsSet, exceptionsList: NotificationExceptionsList?) -> [SettingsSearchableItem] {
@ -319,13 +318,13 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
SettingsSearchableItem(id: .notifications(0), title: strings.Settings_NotificationsAndSounds, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_Title), icon: icon, breadcrumbs: [], present: { context, _, present in
presentNotificationSettings(context, present, nil)
}),
SettingsSearchableItem(id: .notifications(1), title: strings.Notifications_MessageNotificationsAlert, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsAlert), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(1), title: strings.Notifications_MessageNotificationsAlert, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsAlert), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .messageAlerts)
}),
SettingsSearchableItem(id: .notifications(2), title: strings.Notifications_MessageNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(2), title: strings.Notifications_MessageNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .messagePreviews)
}),
SettingsSearchableItem(id: .notifications(3), title: strings.Notifications_MessageNotificationsSound, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(3), title: strings.Notifications_MessageNotificationsSound, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications], present: { context, _, present in
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.privateChats.sound), defaultSound: nil, completion: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
@ -336,16 +335,16 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
})
present(.modal, controller)
}),
SettingsSearchableItem(id: .notifications(4), title: strings.Notifications_MessageNotificationsExceptions, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsExceptions), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(4), title: strings.Notifications_MessageNotificationsExceptions, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsExceptions), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications], present: { context, _, present in
present(.push, NotificationExceptionsController(context: context, mode: exceptions().0, updatedMode: { _ in}))
}),
SettingsSearchableItem(id: .notifications(5), title: strings.Notifications_GroupNotificationsAlert, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsAlert), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(5), title: strings.Notifications_GroupNotificationsAlert, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsAlert), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .groupAlerts)
}),
SettingsSearchableItem(id: .notifications(6), title: strings.Notifications_GroupNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(6), title: strings.Notifications_GroupNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .groupPreviews)
}),
SettingsSearchableItem(id: .notifications(7), title: strings.Notifications_GroupNotificationsSound, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(7), title: strings.Notifications_GroupNotificationsSound, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications], present: { context, _, present in
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.groupChats.sound), defaultSound: nil, completion: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
var settings = settings
@ -355,16 +354,16 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
})
present(.modal, controller)
}),
SettingsSearchableItem(id: .notifications(8), title: strings.Notifications_GroupNotificationsExceptions, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(8), title: strings.Notifications_GroupNotificationsExceptions, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupNotifications], present: { context, _, present in
present(.push, NotificationExceptionsController(context: context, mode: exceptions().1, updatedMode: { _ in}))
}),
SettingsSearchableItem(id: .notifications(9), title: strings.Notifications_ChannelNotificationsAlert, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsAlert), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(9), title: strings.Notifications_ChannelNotificationsAlert, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsAlert), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .channelAlerts)
}),
SettingsSearchableItem(id: .notifications(10), title: strings.Notifications_ChannelNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(10), title: strings.Notifications_ChannelNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .channelPreviews)
}),
SettingsSearchableItem(id: .notifications(11), title: strings.Notifications_ChannelNotificationsSound, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(11), title: strings.Notifications_ChannelNotificationsSound, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications], present: { context, _, present in
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.channels.sound), defaultSound: nil, completion: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
var settings = settings
@ -374,31 +373,31 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
})
present(.modal, controller)
}),
SettingsSearchableItem(id: .notifications(12), title: strings.Notifications_MessageNotificationsExceptions, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(12), title: strings.Notifications_MessageNotificationsExceptions, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_ChannelNotifications], present: { context, _, present in
present(.push, NotificationExceptionsController(context: context, mode: exceptions().2, updatedMode: { _ in}))
}),
SettingsSearchableItem(id: .notifications(13), title: strings.Notifications_InAppNotificationsSounds, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(13), title: strings.Notifications_InAppNotificationsSounds, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsSound), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .inAppSounds)
}),
SettingsSearchableItem(id: .notifications(14), title: strings.Notifications_InAppNotificationsVibrate, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(14), title: strings.Notifications_InAppNotificationsVibrate, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .inAppVibrate)
}),
SettingsSearchableItem(id: .notifications(15), title: strings.Notifications_InAppNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(15), title: strings.Notifications_InAppNotificationsPreview, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications], present: { context, _, present in
presentNotificationSettings(context, present, .inAppPreviews)
}),
SettingsSearchableItem(id: .notifications(16), title: strings.Notifications_DisplayNamesOnLockScreen, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_DisplayNamesOnLockScreen), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds], present: { context, _, present in
presentNotificationSettings(context, present, .displayNamesOnLockscreen)
}),
SettingsSearchableItem(id: .notifications(17), title: strings.Notifications_Badge_IncludeMutedChats, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChats), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(17), title: strings.Notifications_Badge_IncludeMutedChats, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChats), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge], present: { context, _, present in
presentNotificationSettings(context, present, .unreadCountStyle)
}),
SettingsSearchableItem(id: .notifications(18), title: strings.Notifications_Badge_IncludePublicGroups, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedPublicGroups), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(18), title: strings.Notifications_Badge_IncludePublicGroups, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedPublicGroups), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge], present: { context, _, present in
presentNotificationSettings(context, present, .includePublicGroups)
}),
SettingsSearchableItem(id: .notifications(19), title: strings.Notifications_Badge_IncludeChannels, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(19), title: strings.Notifications_Badge_IncludeChannels, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge], present: { context, _, present in
presentNotificationSettings(context, present, .includeChannels)
}),
SettingsSearchableItem(id: .notifications(20), title: strings.Notifications_Badge_CountUnreadMessages, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .notifications(20), title: strings.Notifications_Badge_CountUnreadMessages, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge], present: { context, _, present in
presentNotificationSettings(context, present, .unreadCountCategory)
}),
SettingsSearchableItem(id: .notifications(21), title: strings.NotificationSettings_ContactJoined, alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ContactJoined), icon: icon, breadcrumbs: [strings.Settings_NotificationsAndSounds], present: { context, _, present in
@ -521,7 +520,7 @@ private func privacySearchableItems(context: AccountContext) -> [SettingsSearcha
SettingsSearchableItem(id: .privacy(9), title: strings.PrivacySettings_AuthSessions, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
present(.push, recentSessionsController(context: context))
}),
SettingsSearchableItem(id: .privacy(10), title: strings.PrivacySettings_DeleteAccountTitle.capitalized, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
SettingsSearchableItem(id: .privacy(10), title: strings.PrivacySettings_DeleteAccountTitle, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
presentPrivacySettings(context, present, .accountTimeout)
}),
SettingsSearchableItem(id: .privacy(11), title: strings.PrivacySettings_DataSettings, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_Title), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
@ -573,10 +572,10 @@ private func dataSearchableItems(context: AccountContext) -> [SettingsSearchable
SettingsSearchableItem(id: .data(4), title: strings.NetworkUsageSettings_Title, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_NetworkUsage), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
present(.push, networkUsageStatsController(context: context))
}),
SettingsSearchableItem(id: .data(5), title: strings.ChatSettings_AutoDownloadUsingCellular, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .data(5), title: strings.ChatSettings_AutoDownloadUsingCellular, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle], present: { context, _, present in
present(.push, autodownloadMediaConnectionTypeController(context: context, connectionType: .cellular))
}),
SettingsSearchableItem(id: .data(6), title: strings.ChatSettings_AutoDownloadUsingWiFi, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .data(6), title: strings.ChatSettings_AutoDownloadUsingWiFi, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle], present: { context, _, present in
present(.push, autodownloadMediaConnectionTypeController(context: context, connectionType: .wifi))
}),
SettingsSearchableItem(id: .data(7), title: strings.ChatSettings_AutoDownloadReset, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadReset), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
@ -646,7 +645,7 @@ private func appearanceSearchableItems(context: AccountContext) -> [SettingsSear
SettingsSearchableItem(id: .appearance(0), title: strings.Settings_Appearance, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_Title), icon: icon, breadcrumbs: [], present: { context, _, present in
presentAppearanceSettings(context, present, nil)
}),
SettingsSearchableItem(id: .appearance(1), title: strings.Appearance_TextSize.capitalized, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_TextSize), icon: icon, breadcrumbs: [strings.Settings_Appearance], present: { context, _, present in
SettingsSearchableItem(id: .appearance(1), title: strings.Appearance_TextSize, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_TextSize), icon: icon, breadcrumbs: [strings.Settings_Appearance], present: { context, _, present in
presentAppearanceSettings(context, present, .fontSize)
}),
SettingsSearchableItem(id: .appearance(2), title: strings.Settings_ChatBackground, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ChatBackground), icon: icon, breadcrumbs: [strings.Settings_Appearance], present: { context, _, present in
@ -663,16 +662,16 @@ private func appearanceSearchableItems(context: AccountContext) -> [SettingsSear
SettingsSearchableItem(id: .appearance(5), title: strings.Appearance_AutoNightTheme, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_AutoNightTheme), icon: icon, breadcrumbs: [strings.Settings_Appearance], present: { context, _, present in
present(.push, themeAutoNightSettingsController(context: context))
}),
SettingsSearchableItem(id: .appearance(6), title: strings.Appearance_ColorTheme.capitalized, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ColorTheme), icon: icon, breadcrumbs: [strings.Settings_Appearance], present: { context, _, present in
SettingsSearchableItem(id: .appearance(6), title: strings.Appearance_ColorTheme, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ColorTheme), icon: icon, breadcrumbs: [strings.Settings_Appearance], present: { context, _, present in
presentAppearanceSettings(context, present, .accentColor)
}),
SettingsSearchableItem(id: .appearance(7), title: strings.Appearance_ReduceMotion, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_Animations), icon: icon, breadcrumbs: [strings.Settings_Appearance, strings.Appearance_Animations.capitalized], present: { context, _, present in
SettingsSearchableItem(id: .appearance(7), title: strings.Appearance_ReduceMotion, alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_Animations), icon: icon, breadcrumbs: [strings.Settings_Appearance, strings.Appearance_Animations], present: { context, _, present in
presentAppearanceSettings(context, present, .animations)
}),
]
}
func settingsSearchableItems(context: AccountContext, notificationExceptionsList: Signal<NotificationExceptionsList?, NoError>) -> Signal<[SettingsSearchableItem], NoError> {
func settingsSearchableItems(context: AccountContext, notificationExceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>) -> Signal<[SettingsSearchableItem], NoError> {
let watchAppInstalled = (context.watchManager?.watchAppInstalled ?? .single(false))
|> take(1)
@ -694,6 +693,12 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
return viewSettings
}
let hasArchivedStickerPacks = archivedStickerPacks
|> take(1)
|> map { stickerPacks -> Bool in
return !(stickerPacks?.isEmpty ?? true)
}
let proxyServers = context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.proxySettings])
|> map { sharedData -> ProxySettings in
if let value = sharedData.entries[SharedDataKeys.proxySettings] as? ProxySettings {
@ -706,8 +711,8 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
return settings.servers
}
return combineLatest(watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, proxyServers)
|> map { watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, proxyServers in
return combineLatest(watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, hasArchivedStickerPacks, proxyServers)
|> map { watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, hasArchivedStickerPacks, proxyServers in
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
var allItems: [SettingsSearchableItem] = []
@ -723,7 +728,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
let callItems = callSearchableItems(context: context)
allItems.append(contentsOf: callItems)
let stickerItems = stickerSearchableItems(context: context)
let stickerItems = stickerSearchableItems(context: context, hasArchivedStickerPacks: hasArchivedStickerPacks)
allItems.append(contentsOf: stickerItems)
let notificationItems = notificationSearchableItems(context: context, settings: notificationSettings, exceptionsList: notificationExceptionsList)

View File

@ -280,16 +280,16 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
let stickers: Signal<[(String?, FoundStickerItem)], NoError> = Signal { subscriber in
var signals: Signal<[Signal<(String?, [FoundStickerItem]), NoError>], NoError> = .single([])
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.isSingleEmoji {
let query = text.trimmingCharacters(in: .whitespacesAndNewlines)
if query.isSingleEmoji {
signals = .single([searchStickers(account: self.context.account, query: text.firstEmoji)
|> take(1)
|> map { (nil, $0) }])
} else if trimmed.count > 1 {
} else if query.count > 1 {
signals = self.emojiKeywordsPromise.get()
|> mapToSignal { keywords in
if let keywords = keywords {
return searchEmojiKeywords(keywords: keywords, query: trimmed.lowercased(), completeMatch: true)
return searchEmojiKeywords(keywords: keywords, query: query.lowercased(), completeMatch: query.count < 3)
|> map { result -> [Signal<(String?, [FoundStickerItem]), NoError>] in
var signals: [Signal<(String?, [FoundStickerItem]), NoError>] = []
for emoji in result {