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 hashScalar = "#" as UnicodeScalar
private let atScalar = "@" as UnicodeScalar private let atScalar = "@" as UnicodeScalar
private let slashScalar = "/" as UnicodeScalar private let slashScalar = "/" as UnicodeScalar
private let dotsScalar = ":" as UnicodeScalar private let colonScalar = ":" as UnicodeScalar
private let alphanumerics = CharacterSet.alphanumerics private let alphanumerics = CharacterSet.alphanumerics
private func scalarCanPrependQueryControl(_ c: UnicodeScalar?) -> Bool { private func scalarCanPrependQueryControl(_ c: UnicodeScalar?) -> Bool {
@ -101,7 +101,8 @@ func textInputStateContextQueryRangeAndType(_ inputState: ChatTextInputState) ->
var possibleQueryRange: NSRange? 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)] return [(NSRange(location: 0, length: inputLength), [.emoji], nil)]
} }
@ -140,7 +141,7 @@ func textInputStateContextQueryRangeAndType(_ inputState: ChatTextInputState) ->
possibleQueryRange = NSRange(location: index, length: maxIndex - index) possibleQueryRange = NSRange(location: index, length: maxIndex - index)
} }
break break
} else if c == dotsScalar { } else if c == colonScalar {
if scalarCanPrependQueryControl(previousC) { if scalarCanPrependQueryControl(previousC) {
possibleTypes = possibleTypes.intersection([.emojiSearch]) possibleTypes = possibleTypes.intersection([.emojiSearch])
definedType = true definedType = true
@ -231,11 +232,6 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
switch chatPresentationInterfaceState.inputMode { switch chatPresentationInterfaceState.inputMode {
case .media: 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) accessoryItems.append(.keyboard)
return ChatTextInputPanelState(accessoryItems: accessoryItems, contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState) return ChatTextInputPanelState(accessoryItems: accessoryItems, contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
case .inputButtons: case .inputButtons:
@ -286,7 +282,3 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
} }
} }
} }
func urlPreviewForPresentationInterfaceState() {
}

View File

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

View File

@ -78,7 +78,8 @@ struct InstantPageGalleryEntry: Equatable {
if let image = self.media.media as? TelegramMediaImage { 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) 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 { } else if let file = self.media.media as? TelegramMediaFile {
if file.isVideo {
var indexData: GalleryItemIndexData? var indexData: GalleryItemIndexData?
if let location = self.location { if let location = self.location {
indexData = GalleryItemIndexData(position: location.position, totalCount: location.totalCount) indexData = GalleryItemIndexData(position: location.position, totalCount: location.totalCount)
@ -92,6 +93,15 @@ struct InstantPageGalleryEntry: Equatable {
} }
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 }) 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 {
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)
}
} else if let embedWebpage = self.media.media as? TelegramMediaWebpage, case let .Loaded(webpageContent) = embedWebpage.content { } else if let embedWebpage = self.media.media as? TelegramMediaWebpage, case let .Loaded(webpageContent) = embedWebpage.content {
if let content = WebEmbedVideoContent(webPage: embedWebpage, webpageContent: webpageContent) { 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 }) 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 backgroundNode: ASDisplayNode
private let separatorNode: ASDisplayNode private let separatorNode: ASDisplayNode
private let textBackgroundNode: ASImageNode private let textBackgroundNode: ASDisplayNode
private var activityIndicator: ActivityIndicator? private var activityIndicator: ActivityIndicator?
private let iconNode: ASImageNode private let iconNode: ASImageNode
private let textField: SearchBarTextField private let textField: SearchBarTextField
@ -333,10 +333,10 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
self.separatorNode = ASDisplayNode() self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true self.separatorNode.isLayerBacked = true
self.textBackgroundNode = ASImageNode() self.textBackgroundNode = ASDisplayNode()
self.textBackgroundNode.isLayerBacked = false self.textBackgroundNode.isLayerBacked = false
self.textBackgroundNode.displaysAsynchronously = false self.textBackgroundNode.displaysAsynchronously = false
self.textBackgroundNode.displayWithoutProcessing = true self.textBackgroundNode.cornerRadius = self.fieldStyle.cornerDiameter / 2.0
self.iconNode = ASImageNode() self.iconNode = ASImageNode()
self.iconNode.isLayerBacked = true self.iconNode.isLayerBacked = true
@ -391,7 +391,7 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
if self.fieldStyle != .modern { if self.fieldStyle != .modern {
self.separatorNode.backgroundColor = theme.separator 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.textField.textColor = theme.primaryText
self.clearButton.setImage(generateClearIcon(color: theme.inputClear), for: []) self.clearButton.setImage(generateClearIcon(color: theme.inputClear), for: [])
self.iconNode.image = generateLoupeIcon(color: theme.inputIcon) 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.animateAlpha(from: 0.0, to: 1.0, duration: duration)
self.separatorNode.layer.animateFrame(from: initialSeparatorFrame, to: self.separatorNode.frame, duration: duration, timingFunction: timingFunction) 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) self.textBackgroundNode.layer.animateFrame(from: initialTextBackgroundFrame, to: self.textBackgroundNode.frame, duration: duration, timingFunction: timingFunction)
let textFieldFrame = self.textField.frame let textFieldFrame = self.textField.frame

View File

@ -77,7 +77,7 @@ class SearchBarPlaceholderNode: ASDisplayNode {
return return
} }
if let _ = point { 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) strongSelf.backgroundNode.backgroundColor = strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9)
} else { } else {
strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.4) 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 openProxy: () -> Void
let openSavedMessages: () -> Void let openSavedMessages: () -> Void
let openRecentCalls: () -> Void let openRecentCalls: () -> Void
let openPrivacyAndSecurity: () -> Void let openPrivacyAndSecurity: (AccountPrivacySettings?) -> Void
let openDataAndStorage: () -> Void let openDataAndStorage: () -> Void
let openStickerPacks: ([ArchivedStickerPackItem]?) -> Void let openStickerPacks: ([ArchivedStickerPackItem]?) -> Void
let openNotificationsAndSounds: (NotificationExceptionsList?) -> Void let openNotificationsAndSounds: (NotificationExceptionsList?) -> Void
@ -77,7 +77,7 @@ private enum SettingsEntry: ItemListNodeEntry {
case stickers(PresentationTheme, UIImage?, String, String, [ArchivedStickerPackItem]?) case stickers(PresentationTheme, UIImage?, String, String, [ArchivedStickerPackItem]?)
case notificationsAndSounds(PresentationTheme, UIImage?, String, NotificationExceptionsList?, Bool) case notificationsAndSounds(PresentationTheme, UIImage?, String, NotificationExceptionsList?, Bool)
case privacyAndSecurity(PresentationTheme, UIImage?, String) case privacyAndSecurity(PresentationTheme, UIImage?, String, AccountPrivacySettings?)
case dataAndStorage(PresentationTheme, UIImage?, String) case dataAndStorage(PresentationTheme, UIImage?, String)
case themes(PresentationTheme, UIImage?, String) case themes(PresentationTheme, UIImage?, String)
case language(PresentationTheme, UIImage?, String, String) case language(PresentationTheme, UIImage?, String, String)
@ -241,8 +241,8 @@ private enum SettingsEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .privacyAndSecurity(lhsTheme, lhsImage, lhsText): case let .privacyAndSecurity(lhsTheme, lhsImage, lhsText, _):
if case let .privacyAndSecurity(rhsTheme, rhsImage, rhsText) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText { if case let .privacyAndSecurity(rhsTheme, rhsImage, rhsText, _) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText {
return true return true
} else { } else {
return false 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: { 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) 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: { 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): case let .dataAndStorage(theme, image, text):
return ItemListDisclosureItem(theme: theme, icon: image, title: text, label: "", sectionId: ItemListSectionId(self.section), style: .blocks, action: { 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 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] = [] var entries: [SettingsEntry] = []
if let peer = peerViewMainPeer(view) as? TelegramUser { 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) let notificationsWarning = shouldDisplayNotificationsPermissionWarning(status: notificationsAuthorizationStatus, suppressed: notificationsWarningSuppressed)
entries.append(.notificationsAndSounds(presentationData.theme, PresentationResourcesSettings.notifications, presentationData.strings.Settings_NotificationsAndSounds, notifyExceptions, notificationsWarning)) 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(.dataAndStorage(presentationData.theme, PresentationResourcesSettings.dataAndStorage, presentationData.strings.Settings_ChatSettings))
entries.append(.themes(presentationData.theme, PresentationResourcesSettings.appearance, presentationData.strings.Settings_Appearance)) entries.append(.themes(presentationData.theme, PresentationResourcesSettings.appearance, presentationData.strings.Settings_Appearance))
let languageName = presentationData.strings.primaryComponent.localizedName 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)])>() let accountsAndPeers = Promise<((Account, Peer)?, [(Account, Peer, Int32)])>()
accountsAndPeers.set(activeAccountsAndPeers(context: context)) accountsAndPeers.set(activeAccountsAndPeers(context: context))
let privacySettings = Promise<[PeerId: AccountPrivacySettings]>([:]) let privacySettings = Promise<AccountPrivacySettings?>(nil)
let openFaq: (Promise<ResolvedUrl>) -> Void = { resolvedUrl in let openFaq: (Promise<ResolvedUrl>) -> Void = { resolvedUrl in
let _ = (contextValue.get() let _ = (contextValue.get()
@ -677,23 +677,13 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|> take(1)).start(next: { context in |> take(1)).start(next: { context in
pushControllerImpl?(CallListController(context: context, mode: .navigation)) pushControllerImpl?(CallListController(context: context, mode: .navigation))
}) })
}, openPrivacyAndSecurity: { }, openPrivacyAndSecurity: { privacySettingsValue in
let _ = (contextValue.get() let _ = (contextValue.get()
|> deliverOnMainQueue |> deliverOnMainQueue
|> take(1)).start(next: { context in |> take(1)).start(next: { context in
let _ = (privacySettings.get() pushControllerImpl?(privacyAndSecurityController(context: context, initialSettings: privacySettingsValue, updatedSettings: { settings in
|> take(1) privacySettings.set(.single(settings))
|> 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))
})) }))
}))
})
}) })
}, openDataAndStorage: { }, openDataAndStorage: {
let _ = (contextValue.get() 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) let hasWatchApp = Promise<Bool>(false)
hasWatchApp.set( hasWatchApp.set(
contextValue.get() contextValue.get()
@ -1049,7 +1050,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
return context.account.viewTracker.featuredStickerPacks() 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 |> 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 proxySettings: ProxySettings = preferencesAndExceptions.0.entries[SharedDataKeys.proxySettings] as? ProxySettings ?? ProxySettings.defaultSettings
let inAppNotificationSettings: InAppNotificationSettings = preferencesAndExceptions.0.entries[ApplicationSpecificSharedDataKeys.inAppNotificationSettings] as? InAppNotificationSettings ?? InAppNotificationSettings.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) presentControllerImpl?(v, a)
}, pushController: { v in }, pushController: { v in
pushControllerImpl?(v) pushControllerImpl?(v)
}, getNavigationController: getNavigationControllerImpl, exceptionsList: notifyExceptions.get()) }, getNavigationController: getNavigationControllerImpl, exceptionsList: notifyExceptions.get(), archivedStickerPacks: archivedPacks.get())
let (hasPassport, hasWatchApp) = hasPassportAndWatch 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)) return (controllerState, (listState, arguments))
} }

View File

@ -61,12 +61,13 @@ final class SettingsSearchItem: ItemListControllerSearch {
let pushController: (ViewController) -> Void let pushController: (ViewController) -> Void
let getNavigationController: (() -> NavigationController?)? let getNavigationController: (() -> NavigationController?)?
let exceptionsList: Signal<NotificationExceptionsList?, NoError> let exceptionsList: Signal<NotificationExceptionsList?, NoError>
let archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>
private var updateActivity: ((Bool) -> Void)? private var updateActivity: ((Bool) -> Void)?
private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false) private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false)
private let activityDisposable = MetaDisposable() 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.context = context
self.theme = theme self.theme = theme
self.placeholder = placeholder self.placeholder = placeholder
@ -76,6 +77,7 @@ final class SettingsSearchItem: ItemListControllerSearch {
self.pushController = pushController self.pushController = pushController
self.getNavigationController = getNavigationController self.getNavigationController = getNavigationController
self.exceptionsList = exceptionsList self.exceptionsList = exceptionsList
self.archivedStickerPacks = archivedStickerPacks
self.activityDisposable.set((activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in self.activityDisposable.set((activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in
if value { if value {
return .single(value) |> delay(0.2, queue: Queue.mainQueue()) return .single(value) |> delay(0.2, queue: Queue.mainQueue())
@ -139,7 +141,7 @@ final class SettingsSearchItem: ItemListControllerSearch {
pushController(c) pushController(c)
}, presentController: { c, a in }, presentController: { c, a in
presentController(c, a) 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 var presentationDataDisposable: Disposable?
private let presentationDataPromise: Promise<PresentationData> 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.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.presentationDataPromise = Promise(self.presentationData) self.presentationDataPromise = Promise(self.presentationData)
@ -343,7 +345,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
}) })
let searchableItems = Promise<[SettingsSearchableItem]>() 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)) let queryAndFoundItems = combineLatest(searchableItems.get(), faqSearchableItems(context: context))
|> mapToSignal { searchableItems, faqSearchableItems -> Signal<(String, [SettingsSearchableItem])?, NoError> in |> mapToSignal { searchableItems, faqSearchableItems -> Signal<(String, [SettingsSearchableItem])?, NoError> in
@ -367,7 +369,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
self.recentListNode.isHidden = false 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 |> map { searchableItems, recentItems -> [SettingsSearchableItem] in
let searchableItemsMap = searchableItems.reduce([SettingsSearchableItemId : SettingsSearchableItem]()) { (map, item) -> [SettingsSearchableItemId: SettingsSearchableItem] in let searchableItemsMap = searchableItems.reduce([SettingsSearchableItemId : SettingsSearchableItem]()) { (map, item) -> [SettingsSearchableItemId: SettingsSearchableItem] in
var map = map var map = map
@ -605,10 +607,11 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode {
let presentController: (ViewController, Any?) -> Void let presentController: (ViewController, Any?) -> Void
let getNavigationController: (() -> NavigationController?)? let getNavigationController: (() -> NavigationController?)?
let exceptionsList: Signal<NotificationExceptionsList?, NoError> let exceptionsList: Signal<NotificationExceptionsList?, NoError>
let archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>
var cancel: () -> Void 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.context = context
self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.cancel = cancel self.cancel = cancel
@ -616,6 +619,7 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode {
self.presentController = presentController self.presentController = presentController
self.getNavigationController = getNavigationController self.getNavigationController = getNavigationController
self.exceptionsList = exceptionsList self.exceptionsList = exceptionsList
self.archivedStickerPacks = archivedStickerPacks
super.init() 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() 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 case faq
} }
enum SettingsSearchableItemId: Hashable { enum SettingsSearchableItemId: Hashable {
case profile(Int32) case profile(Int32)
case proxy(Int32) case proxy(Int32)
@ -152,7 +150,7 @@ struct SettingsSearchableItem {
} }
private func synonyms(_ string: String?) -> [String] { private func synonyms(_ string: String?) -> [String] {
if let string = string { if let string = string, !string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
return string.components(separatedBy: "|") return string.components(separatedBy: "|")
} else { } else {
return [] 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 icon: SettingsSearchableItemIcon = .stickers
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
let presentStickerSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController) -> Void, InstalledStickerPacksEntryTag?) -> Void = { context, present, itemTag in let presentStickerSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController) -> Void, InstalledStickerPacksEntryTag?) -> Void = { context, present, itemTag in
present(.push, installedStickerPacksController(context: context, mode: .general, archivedPacks: nil, updatedPacks: { _ in present(.push, installedStickerPacksController(context: context, mode: .general, archivedPacks: nil, updatedPacks: { _ in }, focusOnItemTag: itemTag))
}, focusOnItemTag: itemTag))
} }
return [ var items: [SettingsSearchableItem] = []
SettingsSearchableItem(id: .stickers(0), title: strings.ChatSettings_Stickers, alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_Title), icon: icon, breadcrumbs: [], present: { context, _, present in
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) 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
})) }))
}), 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
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 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 })) present(.push, installedStickerPacksController(context: context, mode: .masks, archivedPacks: nil, updatedPacks: { _ in }))
}) }))
] return items
} }
private func notificationSearchableItems(context: AccountContext, settings: GlobalNotificationSettingsSet, exceptionsList: NotificationExceptionsList?) -> [SettingsSearchableItem] { 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 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) 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) 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) 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 controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.privateChats.sound), defaultSound: nil, completion: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
@ -336,16 +335,16 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
}) })
present(.modal, controller) 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})) 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) 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) 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 controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.groupChats.sound), defaultSound: nil, completion: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
var settings = settings var settings = settings
@ -355,16 +354,16 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
}) })
present(.modal, controller) 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})) 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) 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) 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 controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.channels.sound), defaultSound: nil, completion: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
var settings = settings var settings = settings
@ -374,31 +373,31 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob
}) })
present(.modal, controller) 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})) 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) 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) 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) 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 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) 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) 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) 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) 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) 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 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 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)) 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) 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 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 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)) 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)) 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)) 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 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 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) 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) 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 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 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)) 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) 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) 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)) let watchAppInstalled = (context.watchManager?.watchAppInstalled ?? .single(false))
|> take(1) |> take(1)
@ -694,6 +693,12 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
return viewSettings return viewSettings
} }
let hasArchivedStickerPacks = archivedStickerPacks
|> take(1)
|> map { stickerPacks -> Bool in
return !(stickerPacks?.isEmpty ?? true)
}
let proxyServers = context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.proxySettings]) let proxyServers = context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.proxySettings])
|> map { sharedData -> ProxySettings in |> map { sharedData -> ProxySettings in
if let value = sharedData.entries[SharedDataKeys.proxySettings] as? ProxySettings { if let value = sharedData.entries[SharedDataKeys.proxySettings] as? ProxySettings {
@ -706,8 +711,8 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
return settings.servers return settings.servers
} }
return combineLatest(watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, proxyServers) return combineLatest(watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, hasArchivedStickerPacks, proxyServers)
|> map { watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, proxyServers in |> map { watchAppInstalled, canAddAccount, notificationSettings, notificationExceptionsList, hasArchivedStickerPacks, proxyServers in
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
var allItems: [SettingsSearchableItem] = [] var allItems: [SettingsSearchableItem] = []
@ -723,7 +728,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
let callItems = callSearchableItems(context: context) let callItems = callSearchableItems(context: context)
allItems.append(contentsOf: callItems) allItems.append(contentsOf: callItems)
let stickerItems = stickerSearchableItems(context: context) let stickerItems = stickerSearchableItems(context: context, hasArchivedStickerPacks: hasArchivedStickerPacks)
allItems.append(contentsOf: stickerItems) allItems.append(contentsOf: stickerItems)
let notificationItems = notificationSearchableItems(context: context, settings: notificationSettings, exceptionsList: notificationExceptionsList) 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 let stickers: Signal<[(String?, FoundStickerItem)], NoError> = Signal { subscriber in
var signals: Signal<[Signal<(String?, [FoundStickerItem]), NoError>], NoError> = .single([]) var signals: Signal<[Signal<(String?, [FoundStickerItem]), NoError>], NoError> = .single([])
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines) let query = text.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.isSingleEmoji { if query.isSingleEmoji {
signals = .single([searchStickers(account: self.context.account, query: text.firstEmoji) signals = .single([searchStickers(account: self.context.account, query: text.firstEmoji)
|> take(1) |> take(1)
|> map { (nil, $0) }]) |> map { (nil, $0) }])
} else if trimmed.count > 1 { } else if query.count > 1 {
signals = self.emojiKeywordsPromise.get() signals = self.emojiKeywordsPromise.get()
|> mapToSignal { keywords in |> mapToSignal { keywords in
if let keywords = keywords { 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 |> map { result -> [Signal<(String?, [FoundStickerItem]), NoError>] in
var signals: [Signal<(String?, [FoundStickerItem]), NoError>] = [] var signals: [Signal<(String?, [FoundStickerItem]), NoError>] = []
for emoji in result { for emoji in result {