diff --git a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift index 6006ed94e6..bd1121cc73 100644 --- a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift +++ b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift @@ -515,7 +515,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers themeSpecificChatWallpapers[themeReference.index] = nil - return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) }) |> deliverOnMainQueue).start(completed: { if !hasCustomFile { saveThemeTemplateFile(state.title, themeResource, { @@ -549,7 +549,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers themeSpecificChatWallpapers[themeReference.index] = nil - return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) }) |> deliverOnMainQueue).start(completed: { if let themeResource = themeResource, !hasCustomFile { saveThemeTemplateFile(state.title, themeResource, { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift index a32575de45..adf2fda3be 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift @@ -228,6 +228,7 @@ final class ThemeAccentColorController: ViewController { } let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: accentColor, messageColors: bubbleColors, wallpaper: wallpaper) + let baseThemeReference = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: baseTheme)) let save: Signal @@ -246,7 +247,10 @@ final class ThemeAccentColorController: ViewController { var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers themeSpecificChatWallpapers[themeReference.index] = nil - return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + var themeSpecificAccentColors = current.themeSpecificAccentColors + themeSpecificAccentColors[baseThemeReference.index] = PresentationThemeAccentColor(themeIndex: themeReference.index) + + return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) }) |> deliverOnMainQueue).start(completed: { if let strongSelf = self { strongSelf.completion?() @@ -272,7 +276,10 @@ final class ThemeAccentColorController: ViewController { var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers themeSpecificChatWallpapers[themeReference.index] = nil - return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + var themeSpecificAccentColors = current.themeSpecificAccentColors + themeSpecificAccentColors[baseThemeReference.index] = PresentationThemeAccentColor(themeIndex: themeReference.index) + + return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) }) |> deliverOnMainQueue).start(completed: { if let strongSelf = self { strongSelf.completion?() @@ -283,35 +290,6 @@ final class ThemeAccentColorController: ViewController { }, error: { error in }) } - -// let _ = (prepare -// |> then(updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in -// let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered -// var currentTheme = current.theme -// if autoNightModeTriggered { -// currentTheme = current.automaticThemeSwitchSetting.theme -// } -// -// -// -// if create { -// -// } else { -// -// } -// -// var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers -// -// -// themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: nil)] = wallpaper -// -// return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) -// })) |> deliverOnMainQueue).start(completed: { [weak self] in -// if let strongSelf = self { -// strongSelf.completion?() -// strongSelf.dismiss() -// } -// }) } } }) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift index c002f3be53..34b81ce429 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift @@ -68,7 +68,7 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry { case settingInfo(PresentationTheme, String) case themeHeader(PresentationTheme, String) - case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper]) + case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper]) var section: ItemListSectionId { switch self { @@ -186,8 +186,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry { } else { return false } - case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeChatWallpapers): - if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeChatWallpapers) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeChatWallpapers == rhsThemeChatWallpapers { + case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeChatWallpapers): + if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsAllThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeChatWallpapers) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsAllThemes == rhsAllThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeChatWallpapers == rhsThemeChatWallpapers { return true } else { return false @@ -244,8 +244,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry { return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) case let .themeHeader(theme, title): return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) - case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers): - return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in + case let .themeItem(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers): + return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in arguments.updateTheme(theme) }, contextAction: nil) } @@ -313,7 +313,16 @@ private func themeAutoNightSettingsControllerEntries(theme: PresentationTheme, s break case .system, .timeBased, .brightness: entries.append(.themeHeader(theme, strings.AutoNightTheme_PreferredTheme)) - entries.append(.themeItem(theme, strings, availableThemes, switchSetting.theme, settings.themeSpecificAccentColors, settings.themeSpecificChatWallpapers)) + + let generalThemes: [PresentationThemeReference] = availableThemes.filter { reference in + if case let .cloud(theme) = reference { + return theme.theme.settings == nil + } else { + return true + } + } + + entries.append(.themeItem(theme, strings, generalThemes, availableThemes, switchSetting.theme, settings.themeSpecificAccentColors, settings.themeSpecificChatWallpapers)) } return entries diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift index 462af36f40..189c6c7e92 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift @@ -341,7 +341,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode { var updatedAccentColor = false var updatedSelected = false - if currentItem == nil || currentItem?.color != item.color { + if currentItem == nil || currentItem?.color != item.color || currentItem?.themeReference != item.themeReference { updatedAccentColor = true } if currentItem?.selected != item.selected { @@ -418,7 +418,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode { strongSelf.dotsNode.bounds = bounds if updatedSelected { - strongSelf.setSelected(item.selected, animated: currentItem != nil && !animated) + strongSelf.setSelected(item.selected, animated: !updatedAccentColor && currentItem != nil) } } }) @@ -663,17 +663,17 @@ private struct ThemeSettingsAccentColorItemNodeTransition { let deletions: [ListViewDeleteItem] let insertions: [ListViewInsertItem] let updates: [ListViewUpdateItem] - let crossfade: Bool + let updatePosition: Bool } -private func preparedTransition(action: @escaping (ThemeSettingsColorOption?, Bool) -> Void, contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)?, openColorPicker: @escaping (Bool) -> Void, from fromEntries: [ThemeSettingsColorEntry], to toEntries: [ThemeSettingsColorEntry], crossfade: Bool) -> ThemeSettingsAccentColorItemNodeTransition { +private func preparedTransition(action: @escaping (ThemeSettingsColorOption?, Bool) -> Void, contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)?, openColorPicker: @escaping (Bool) -> Void, from fromEntries: [ThemeSettingsColorEntry], to toEntries: [ThemeSettingsColorEntry], updatePosition: Bool) -> ThemeSettingsAccentColorItemNodeTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(action: action, contextAction: contextAction, openColorPicker: openColorPicker), directionHint: .Down) } let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(action: action, contextAction: contextAction, openColorPicker: openColorPicker), directionHint: nil) } - return ThemeSettingsAccentColorItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates, crossfade: crossfade) + return ThemeSettingsAccentColorItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates, updatePosition: updatePosition) } private func ensureColorVisible(listNode: ListView, accentColor: ThemeSettingsColorOption?, animated: Bool) -> Bool { @@ -758,19 +758,15 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { self.enqueuedTransitions.remove(at: 0) var options = ListViewDeleteAndInsertOptions() - if self.initialized && transition.crossfade { - options.insert(.AnimateCrossfade) - } - var scrollToItem: ListViewScrollToItem? - if !self.initialized || transition.crossfade { + if !self.initialized || transition.updatePosition { if let index = item.colors.firstIndex(where: { $0.index == item.currentColor?.index }) { scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-56.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down) self.initialized = true } } - - self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { _ in + + self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { [weak self] _ in }) } @@ -932,8 +928,8 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { } let previousEntries = strongSelf.entries ?? [] - let crossfade = previousEntries.count != entries.count || (currentItem != nil && (currentItem?.generalThemeReference.index != item.generalThemeReference.index)) - let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, crossfade: crossfade) + let updatePosition = currentItem != nil && (previousEntries.count != entries.count || (currentItem?.generalThemeReference.index != item.generalThemeReference.index)) + let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, updatePosition: updatePosition) strongSelf.enqueueTransition(transition) strongSelf.entries = entries diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index c2a271b38a..fd3fee4c71 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -133,10 +133,10 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { case fontSize(PresentationTheme, PresentationFontSize) case chatPreview(PresentationTheme, PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, [ChatPreviewMessageItem]) case wallpaper(PresentationTheme, String) - case accentColor(PresentationTheme, PresentationThemeReference, PresentationThemeReference, PresentationThemeCustomColors?, [PresentationThemeReference], ThemeSettingsColorOption?) + case accentColor(PresentationTheme, PresentationThemeReference, PresentationThemeReference, [PresentationThemeReference], ThemeSettingsColorOption?) case autoNightTheme(PresentationTheme, String, String) case textSize(PresentationTheme, String, String) - case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper], PresentationThemeAccentColor?) + case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper], PresentationThemeAccentColor?) case iconHeader(PresentationTheme, String) case iconItem(PresentationTheme, PresentationStrings, [PresentationAppIcon], String?) case otherHeader(PresentationTheme, String) @@ -208,8 +208,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { } else { return false } - case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsCustomColors, lhsThemes, lhsColor): - if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsCustomColors, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsCustomColors == rhsCustomColors, lhsThemes == rhsThemes, lhsColor == rhsColor { + case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsThemes, lhsColor): + if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsThemes == rhsThemes, lhsColor == rhsColor { return true } else { return false @@ -232,8 +232,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { } else { return false } - case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor): - if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeSpecificChatWallpapers, rhsCurrentColor) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeSpecificChatWallpapers == rhsThemeSpecificChatWallpapers, lhsCurrentColor == rhsCurrentColor { + case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor): + if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsAllThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeSpecificChatWallpapers, rhsCurrentColor) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsAllThemes == rhsAllThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeSpecificChatWallpapers == rhsThemeSpecificChatWallpapers, lhsCurrentColor == rhsCurrentColor { return true } else { return false @@ -308,7 +308,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openWallpaperSettings() }) - case let .accentColor(theme, generalThemeReference, currentTheme, customColors, themes, color): + case let .accentColor(theme, generalThemeReference, currentTheme, themes, color): var colorItems: [ThemeSettingsAccentColor] = [] for theme in themes { @@ -317,7 +317,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { var defaultColor: PresentationThemeAccentColor? = PresentationThemeAccentColor(baseColor: .blue) var colors = PresentationThemeBaseColor.allCases - colors = colors.filter { $0 != .custom && $0 != .preset } + colors = colors.filter { $0 != .custom && $0 != .preset && $0 != .theme } if case let .builtin(name) = generalThemeReference { if name == .dayClassic { colorItems.append(.default) @@ -358,14 +358,6 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { let currentColor = color ?? defaultColor.flatMap { .accentColor($0) } colorItems.append(contentsOf: colors.map { .color($0) }) - if let customColors = customColors { -// colorItems.insert(contentsOf: customColors.colors.reversed().map { .custom($0) }, at: 0) - } else { -// if let currentColor = currentColor, currentColor.baseColor == .custom { -// colorItems.insert(.custom(currentColor), at: 0) -// } - } - return ThemeSettingsAccentColorItem(theme: theme, sectionId: self.section, generalThemeReference: generalThemeReference, themeReference: currentTheme, colors: colorItems, currentColor: currentColor, updated: { color in if let color = color { switch color { @@ -392,9 +384,9 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { }) case let .themeListHeader(theme, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _): - return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in - if case let .cloud(theme) = theme, theme.theme.file == nil { + case let .themeItem(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _): + return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in + if case let .cloud(theme) = theme, theme.theme.file == nil && theme.theme.settings == nil { if theme.theme.isCreator { arguments.editTheme(theme) } @@ -448,8 +440,8 @@ private func themeSettingsControllerEntries(presentationData: PresentationData, } else { generalThemeReference = themeReference } - - entries.append(.themeItem(presentationData.theme, presentationData.strings, generalThemes, generalThemeReference, presentationThemeSettings.themeSpecificAccentColors, presentationThemeSettings.themeSpecificChatWallpapers, presentationThemeSettings.themeSpecificAccentColors[themeReference.index])) + + entries.append(.themeItem(presentationData.theme, presentationData.strings, generalThemes, availableThemes, themeReference, presentationThemeSettings.themeSpecificAccentColors, presentationThemeSettings.themeSpecificChatWallpapers, presentationThemeSettings.themeSpecificAccentColors[themeReference.index])) if case let .builtin(builtinTheme) = generalThemeReference { let colorThemes = availableThemes.filter { reference in @@ -467,7 +459,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData, colorOption = .theme(themeReference) } - entries.append(.accentColor(presentationData.theme, generalThemeReference, themeReference, presentationThemeSettings.themeSpecificCustomColors[generalThemeReference.index], colorThemes, colorOption)) + entries.append(.accentColor(presentationData.theme, generalThemeReference, themeReference, colorThemes, colorOption)) } entries.append(.wallpaper(presentationData.theme, strings.Settings_ChatBackground)) @@ -526,6 +518,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The var presentCrossfadeControllerImpl: ((Bool) -> Void)? var selectThemeImpl: ((PresentationThemeReference) -> Void)? + var selectAccentColorImpl: ((PresentationThemeAccentColor?) -> Void)? var moreImpl: (() -> Void)? let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start() @@ -555,87 +548,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The }, openWallpaperSettings: { pushControllerImpl?(ThemeGridController(context: context)) }, selectAccentColor: { accentColor in - var wallpaperSignal: Signal = .single(nil) - if let colorWallpaper = accentColor?.wallpaper, case let .file(file) = colorWallpaper { - wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings) - |> mapToSignal { cachedWallpaper in - if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper { - let resource = file.file.resource - let representation = CachedPatternWallpaperRepresentation(color: file.settings.color ?? 0xd6e2ee, bottomColor: file.settings.bottomColor, intensity: file.settings.intensity ?? 50, rotation: file.settings.rotation) - - var data: Data? - if let path = context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { - data = maybeData - } else if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { - data = maybeData - } - - if let data = data { - context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) - return (context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true) - |> filter({ $0.complete }) - |> take(1) - |> mapToSignal { _ -> Signal in - return .single(wallpaper) - }) - } else { - return .single(nil) - } - } else { - return .single(nil) - } - } - } - - let _ = (wallpaperSignal - |> deliverOnMainQueue).start(next: { presetWallpaper in - let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in - let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered - var currentTheme = current.theme - if autoNightModeTriggered { - currentTheme = current.automaticThemeSwitchSetting.theme - } - - let generalThemeReference: PresentationThemeReference - if case let .cloud(theme) = currentTheme, let settings = theme.theme.settings { - generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)) - } else { - generalThemeReference = currentTheme - } - - currentTheme = generalThemeReference - var updatedTheme = current.theme - var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting - - if autoNightModeTriggered { - var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting - updatedAutomaticThemeSwitchSetting.theme = generalThemeReference - } else { - updatedTheme = generalThemeReference - } - - guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper) else { - return current - } - - var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers - var themeSpecificAccentColors = current.themeSpecificAccentColors - themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper) - - if case let .builtin(theme) = generalThemeReference { - if let wallpaper = current.themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)], wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin { - themeSpecificChatWallpapers[currentTheme.index] = nil - if let accentColor = accentColor { - themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)] = nil - } - } - } - - return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) - }).start() - - presentCrossfadeControllerImpl?(true) - }) + selectAccentColorImpl?(accentColor) }, openAccentColorPicker: { themeReference, create in let controller = ThemeAccentColorController(context: context, mode: .colors(themeReference: themeReference, create: create)) pushControllerImpl?(controller) @@ -971,15 +884,24 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The let _ = (cloudThemes.get() |> delay(0.5, queue: Queue.mainQueue()) |> take(1) |> deliverOnMainQueue).start(next: { themes in - if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == cloudTheme.theme.id }) { - let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil }) - let newTheme: PresentationThemeReference - if let previousThemeIndex = previousThemeIndex { - newTheme = .cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil)) - } else { - newTheme = .builtin(.nightAccent) + if isCurrent, let settings = cloudTheme.theme.settings { + let colorThemes = themes.filter { theme in + if let settings = theme.settings { + return true + } else { + return false + } + } + + if let currentThemeIndex = colorThemes.firstIndex(where: { $0.id == cloudTheme.theme.id }) { + let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil }) + let newTheme: PresentationThemeReference + if let previousThemeIndex = previousThemeIndex { + selectThemeImpl?(.cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil))) + } else { + selectAccentColorImpl?(nil) + } } - selectThemeImpl?(newTheme) } let _ = deleteThemeInteractively(account: context.account, accountManager: context.sharedContext.accountManager, theme: cloudTheme.theme).start() @@ -993,67 +915,6 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The presentControllerImpl?(actionSheet, nil) }) }))) - } else { - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_ShareThemeColor, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor) - }, action: { c, f in - c.dismiss(completion: { - - }) - }))) - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_RemoveThemeColor, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) - }, action: { c, f in - c.dismiss(completion: { - let actionSheet = ActionSheetController(presentationData: presentationData) - var items: [ActionSheetItem] = [] - items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_RemoveThemeColorConfirmation, color: .destructive, action: { [weak actionSheet] in - actionSheet?.dismissAnimated() - - let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in - let themeReference: PresentationThemeReference - if presentationData.autoNightModeTriggered { - themeReference = current.automaticThemeSwitchSetting.theme - } else { - themeReference = current.theme - } - - var themeSpecificAccentColors = current.themeSpecificAccentColors - var themeSpecificCustomColors = current.themeSpecificCustomColors - var customColors = themeSpecificCustomColors[themeReference.index]?.colors ?? [] - - var updatedAccentColor: PresentationThemeAccentColor? - if let index = customColors.firstIndex(where: { $0.index == accentColor.index }) { - if index > 0 { - updatedAccentColor = customColors[index - 1] - } else { - if case let .builtin(theme) = themeReference { - switch theme { - case .dayClassic: - updatedAccentColor = nil - case .day, .night, .nightAccent: - updatedAccentColor = PresentationThemeAccentColor(baseColor: .blue) - } - } else { - updatedAccentColor = PresentationThemeAccentColor(baseColor: .blue) - } - } - customColors.remove(at: index) - } else { - updatedAccentColor = PresentationThemeAccentColor(baseColor: .blue) - } - - themeSpecificAccentColors[themeReference.index] = updatedAccentColor - themeSpecificCustomColors[themeReference.index] = PresentationThemeCustomColors(colors: customColors) - return current.withUpdatedThemeSpecificCustomColors(themeSpecificCustomColors).withUpdatedThemeSpecificAccentColors(themeSpecificAccentColors) - }).start() - })) - actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [ - ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in - actionSheet?.dismissAnimated() - }) - ])]) - presentControllerImpl?(actionSheet, nil) - }) - }))) } } let contextController = ContextController(account: context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: themeController, sourceNode: node)), items: .single(items), reactionItems: [], gesture: gesture) @@ -1212,24 +1073,140 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The } let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: cloudTheme).start() - let _ = (resolvedWallpaper - |> mapToSignal { resolvedWallpaper -> Signal in + let currentTheme = context.sharedContext.accountManager.transaction { transaction -> (PresentationThemeReference) in + let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings) as? PresentationThemeSettings ?? PresentationThemeSettings.defaultSettings + if autoNightModeTriggered { + return settings.automaticThemeSwitchSetting.theme + } else { + return settings.theme + } + } + + let _ = (combineLatest(resolvedWallpaper, currentTheme) + |> map { resolvedWallpaper, currentTheme -> Bool in var updatedTheme = theme + var currentThemeBaseIndex: Int64? + if case let .cloud(info) = currentTheme, let settings = info.theme.settings { + currentThemeBaseIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index + } else { + currentThemeBaseIndex = currentTheme.index + } + + var baseThemeIndex: Int64? + var updatedThemeBaseIndex: Int64? if case let .cloud(info) = theme { updatedTheme = .cloud(PresentationCloudTheme(theme: info.theme, resolvedWallpaper: resolvedWallpaper)) + if let settings = info.theme.settings { + baseThemeIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index + updatedThemeBaseIndex = baseThemeIndex + } + } else { + updatedThemeBaseIndex = theme.index } - return updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in + + let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in + var updatedThemeSpecificAccentColors = current.themeSpecificAccentColors + if let baseThemeIndex = baseThemeIndex { + updatedThemeSpecificAccentColors[baseThemeIndex] = PresentationThemeAccentColor(themeIndex: updatedTheme.index) + } + if autoNightModeTriggered { var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting updatedAutomaticThemeSwitchSetting.theme = updatedTheme - return current.withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting) + + return current.withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting).withUpdatedThemeSpecificAccentColors(updatedThemeSpecificAccentColors) } else { - return current.withUpdatedTheme(updatedTheme) + return current.withUpdatedTheme(updatedTheme).withUpdatedThemeSpecificAccentColors(updatedThemeSpecificAccentColors) } - }) - }).start() + }).start() + + return currentThemeBaseIndex != updatedThemeBaseIndex + } |> deliverOnMainQueue).start(next: { crossfadeAccentColors in + presentCrossfadeControllerImpl?((cloudTheme == nil || cloudTheme?.settings != nil) && !crossfadeAccentColors) + }) + } + selectAccentColorImpl = { accentColor in + var wallpaperSignal: Signal = .single(nil) + if let colorWallpaper = accentColor?.wallpaper, case let .file(file) = colorWallpaper { + wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings) + |> mapToSignal { cachedWallpaper in + if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper { + let resource = file.file.resource + let representation = CachedPatternWallpaperRepresentation(color: file.settings.color ?? 0xd6e2ee, bottomColor: file.settings.bottomColor, intensity: file.settings.intensity ?? 50, rotation: file.settings.rotation) + + var data: Data? + if let path = context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { + data = maybeData + } else if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { + data = maybeData + } + + if let data = data { + context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) + return (context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true) + |> filter({ $0.complete }) + |> take(1) + |> mapToSignal { _ -> Signal in + return .single(wallpaper) + }) + } else { + return .single(nil) + } + } else { + return .single(nil) + } + } + } - presentCrossfadeControllerImpl?(cloudTheme == nil || cloudTheme?.settings != nil) + let _ = (wallpaperSignal + |> deliverOnMainQueue).start(next: { presetWallpaper in + let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in + let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered + var currentTheme = current.theme + if autoNightModeTriggered { + currentTheme = current.automaticThemeSwitchSetting.theme + } + + let generalThemeReference: PresentationThemeReference + if case let .cloud(theme) = currentTheme, let settings = theme.theme.settings { + generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)) + } else { + generalThemeReference = currentTheme + } + + currentTheme = generalThemeReference + var updatedTheme = current.theme + var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting + + if autoNightModeTriggered { + var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting + updatedAutomaticThemeSwitchSetting.theme = generalThemeReference + } else { + updatedTheme = generalThemeReference + } + + guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper) else { + return current + } + + var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers + var themeSpecificAccentColors = current.themeSpecificAccentColors + themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper) + + if case let .builtin(theme) = generalThemeReference { + if let wallpaper = current.themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)], wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin { + themeSpecificChatWallpapers[currentTheme.index] = nil + if let accentColor = accentColor { + themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)] = nil + } + } + } + + return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + }).start() + + presentCrossfadeControllerImpl?(true) + }) } moreImpl = { let presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift index e177537d76..782f25eaef 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift @@ -273,7 +273,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { if let strongSelf = self { strongSelf.item = item - if case let .cloud(theme) = item.themeReference, theme.theme.file == nil { + if case let .cloud(theme) = item.themeReference, theme.theme.file == nil && theme.theme.settings == nil { if updatedTheme { strongSelf.imageNode.setSignal(createThemeImage(theme: item.theme)) } @@ -345,6 +345,7 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem { let theme: PresentationTheme let strings: PresentationStrings let themes: [PresentationThemeReference] + let allThemes: [PresentationThemeReference] let displayUnsupported: Bool let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor] let themeSpecificChatWallpapers: [Int64: TelegramWallpaper] @@ -353,11 +354,12 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem { let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)? let tag: ItemListItemTag? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) { + init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], allThemes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) { self.context = context self.theme = theme self.strings = strings self.themes = themes + self.allThemes = allThemes self.displayUnsupported = displayUnsupported self.themeSpecificAccentColors = themeSpecificAccentColors self.themeSpecificChatWallpapers = themeSpecificChatWallpapers @@ -594,14 +596,26 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { strongSelf.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0 + 2.0) strongSelf.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: contentSize.height, height: contentSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) + var themes: [Int64: PresentationThemeReference] = [:] + for theme in item.allThemes { + themes[theme.index] = theme + } + var entries: [ThemeSettingsThemeEntry] = [] var index: Int = 0 - for theme in item.themes { + for var theme in item.themes { if !item.displayUnsupported, case let .cloud(theme) = theme, theme.theme.file == nil { continue } let title = themeDisplayName(strings: item.strings, reference: theme) - let accentColor = item.themeSpecificAccentColors[theme.index] + var accentColor = item.themeSpecificAccentColors[theme.index] + if let customThemeIndex = accentColor?.themeIndex { + if let customTheme = themes[customThemeIndex] { + theme = customTheme + } + accentColor = nil + } + let wallpaper = accentColor?.wallpaper entries.append(ThemeSettingsThemeEntry(index: index, themeReference: theme, title: title, accentColor: accentColor, selected: item.currentTheme.index == theme.index, theme: item.theme, wallpaper: wallpaper)) index += 1 diff --git a/submodules/TelegramCore/Sources/Wallpaper.swift b/submodules/TelegramCore/Sources/Wallpaper.swift index 6a13cce534..9b13b9fae1 100644 --- a/submodules/TelegramCore/Sources/Wallpaper.swift +++ b/submodules/TelegramCore/Sources/Wallpaper.swift @@ -25,6 +25,9 @@ func apiWallpaperSettings(_ wallpaperSettings: WallpaperSettings) -> Api.WallPap if wallpaperSettings.motion { flags |= (1 << 2) } + if let _ = wallpaperSettings.intensity { + flags |= (1 << 3) + } if let _ = wallpaperSettings.bottomColor { flags |= (1 << 4) } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index e4d7795242..078e387066 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -221,7 +221,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit ) } -public func makeDefaultDarkPresentationTheme(preview: Bool) -> PresentationTheme { +public func makeDefaultDarkPresentationTheme(customIndex: Int64? = nil, preview: Bool) -> PresentationTheme { let rootTabBar = PresentationThemeRootTabBar( backgroundColor: UIColor(rgb: 0x1c1c1d), separatorColor: UIColor(rgb: 0x3d3d40), @@ -532,7 +532,7 @@ public func makeDefaultDarkPresentationTheme(preview: Bool) -> PresentationTheme return PresentationTheme( name: .builtin(.night), - index: PresentationThemeReference.builtin(.night).index, + index: customIndex ?? PresentationThemeReference.builtin(.night).index, referenceTheme: .night, overallDarkAppearance: true, intro: intro, diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 18483b9b9d..8d2f453945 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -441,7 +441,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme ) } -public func makeDefaultDarkTintedPresentationTheme(preview: Bool) -> PresentationTheme { +public func makeDefaultDarkTintedPresentationTheme(customIndex: Int64? = nil, preview: Bool) -> PresentationTheme { let accentColor = defaultDarkTintedAccentColor let secondaryBadgeTextColor: UIColor @@ -788,7 +788,7 @@ public func makeDefaultDarkTintedPresentationTheme(preview: Bool) -> Presentatio return PresentationTheme( name: .builtin(.nightAccent), - index: PresentationThemeReference.builtin(.nightAccent).index, + index: customIndex ?? PresentationThemeReference.builtin(.nightAccent).index, referenceTheme: .nightAccent, overallDarkAppearance: true, intro: intro, diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 5a8d14a491..611639e3ac 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -311,7 +311,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ac ) } -public func makeDefaultDayPresentationTheme(serviceBackgroundColor: UIColor?, day: Bool, preview: Bool) -> PresentationTheme { +public func makeDefaultDayPresentationTheme(customIndex: Int64? = nil, serviceBackgroundColor: UIColor?, day: Bool, preview: Bool) -> PresentationTheme { var serviceBackgroundColor = serviceBackgroundColor ?? defaultServiceBackgroundColor let intro = PresentationThemeIntro( @@ -741,7 +741,7 @@ public func makeDefaultDayPresentationTheme(serviceBackgroundColor: UIColor?, da return PresentationTheme( name: .builtin(day ? .day : .dayClassic), - index: PresentationThemeReference.builtin(day ? .day : .dayClassic).index, + index: customIndex ?? PresentationThemeReference.builtin(day ? .day : .dayClassic).index, referenceTheme: day ? .day : .dayClassic, overallDarkAppearance: false, intro: intro, diff --git a/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift b/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift index db56eab238..fb3c52ce2e 100644 --- a/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift @@ -4,17 +4,17 @@ import Postbox import SyncCore import TelegramUIPreferences -public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference, serviceBackgroundColor: UIColor?, preview: Bool = false) -> PresentationTheme { +public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference, customIndex: Int64? = nil, serviceBackgroundColor: UIColor?, preview: Bool = false) -> PresentationTheme { let theme: PresentationTheme switch reference { case .dayClassic: - theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview) + theme = makeDefaultDayPresentationTheme(customIndex: customIndex, serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview) case .day: - theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview) + theme = makeDefaultDayPresentationTheme(customIndex: customIndex, serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview) case .night: - theme = makeDefaultDarkPresentationTheme(preview: preview) + theme = makeDefaultDarkPresentationTheme(customIndex: customIndex, preview: preview) case .nightAccent: - theme = makeDefaultDarkTintedPresentationTheme(preview: preview) + theme = makeDefaultDarkTintedPresentationTheme(customIndex: customIndex, preview: preview) } return theme } @@ -35,11 +35,11 @@ public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool return theme } -public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, accentColor: UIColor? = nil, backgroundColors: (UIColor, UIColor?)? = nil, bubbleColors: (UIColor, UIColor?)? = nil, wallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? { +public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, customIndex: Int64? = nil, accentColor: UIColor? = nil, backgroundColors: (UIColor, UIColor?)? = nil, bubbleColors: (UIColor, UIColor?)? = nil, wallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? { let theme: PresentationTheme switch themeReference { case let .builtin(reference): - let defaultTheme = makeDefaultPresentationTheme(reference: reference, serviceBackgroundColor: serviceBackgroundColor, preview: preview) + let defaultTheme = makeDefaultPresentationTheme(reference: reference, customIndex: customIndex, serviceBackgroundColor: serviceBackgroundColor, preview: preview) theme = customizePresentationTheme(defaultTheme, editing: true, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper) case let .local(info): if let path = mediaBox.completedResourcePath(info.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data, themeReference: themeReference, resolvedWallpaper: info.resolvedWallpaper) { @@ -49,7 +49,7 @@ public func makePresentationTheme(mediaBox: MediaBox, themeReference: Presentati } case let .cloud(info): if let settings = info.theme.settings { - if let loadedTheme = makePresentationTheme(mediaBox: mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: accentColor ?? UIColor(rgb: UInt32(bitPattern: settings.accentColor)), backgroundColors: nil, bubbleColors: bubbleColors ?? settings.messageColors.flatMap { (UIColor(rgb: UInt32(bitPattern: $0.top)), UIColor(rgb: UInt32(bitPattern: $0.bottom))) }, wallpaper: wallpaper ?? settings.wallpaper, serviceBackgroundColor: serviceBackgroundColor, preview: preview) { + if let loadedTheme = makePresentationTheme(mediaBox: mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), customIndex: themeReference.index, accentColor: accentColor ?? UIColor(rgb: UInt32(bitPattern: settings.accentColor)), backgroundColors: nil, bubbleColors: bubbleColors ?? settings.messageColors.flatMap { (UIColor(rgb: UInt32(bitPattern: $0.top)), UIColor(rgb: UInt32(bitPattern: $0.bottom))) }, wallpaper: wallpaper ?? settings.wallpaper, serviceBackgroundColor: serviceBackgroundColor, preview: preview) { theme = loadedTheme } else { return nil diff --git a/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift b/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift index cfc7c701a1..ab8fbf9b7a 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift @@ -139,7 +139,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { theme = updatedTheme } - return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) }) }).start() } diff --git a/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift b/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift index 6796e6ec0a..eeccfd0e1d 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift @@ -134,7 +134,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager { var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers themeSpecificChatWallpapers[themeReference.index] = updatedWallpaper themeSpecificChatWallpapers[coloredThemeIndex(reference: themeReference, accentColor: current.themeSpecificAccentColors[themeReference.index])] = updatedWallpaper - return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) + return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) })).start() } } diff --git a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift index 2ec4c2b19a..79a5417cd3 100644 --- a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift @@ -353,6 +353,7 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable { case white case custom case preset + case theme public var color: UIColor { let value: UInt32 @@ -379,39 +380,13 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable { value = 0x000000 case .white: value = 0xffffff - case .custom, .preset: + case .custom, .preset, .theme: return .clear } return UIColor(rgb: value) } } -public struct PresentationThemeCustomColors: PostboxCoding, Equatable { - public static func == (lhs: PresentationThemeCustomColors, rhs: PresentationThemeCustomColors) -> Bool { - return lhs.colors == rhs.colors - } - - public let colors: [PresentationThemeAccentColor] - - public init(colors: [PresentationThemeAccentColor]) { - self.colors = colors - } - - public init(decoder: PostboxDecoder) { - if let colors = try? decoder.decodeObjectArrayWithCustomDecoderForKey("v", decoder: { decoder in - return PresentationThemeAccentColor(decoder: decoder) - }) { - self.colors = colors - } else { - self.colors = [] - } - } - - public func encode(_ encoder: PostboxEncoder) { - encoder.encodeObjectArray(self.colors, forKey: "v") - } -} - public struct PresentationThemeAccentColor: PostboxCoding, Equatable { public static func == (lhs: PresentationThemeAccentColor, rhs: PresentationThemeAccentColor) -> Bool { return lhs.index == rhs.index && lhs.baseColor == rhs.baseColor && lhs.accentColor == rhs.accentColor && lhs.bubbleColors?.0 == rhs.bubbleColors?.0 && lhs.bubbleColors?.1 == rhs.bubbleColors?.1 @@ -422,6 +397,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { public var accentColor: Int32? public var bubbleColors: (Int32, Int32?)? public var wallpaper: TelegramWallpaper? + public var themeIndex: Int64? public init(baseColor: PresentationThemeBaseColor) { if baseColor != .preset && baseColor != .custom { @@ -443,6 +419,15 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { self.wallpaper = wallpaper } + public init(themeIndex: Int64) { + self.index = -1 + self.baseColor = .theme + self.accentColor = nil + self.bubbleColors = nil + self.wallpaper = nil + self.themeIndex = themeIndex + } + public init(decoder: PostboxDecoder) { self.index = decoder.decodeInt32ForKey("i", orElse: -1) self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue @@ -457,6 +442,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { self.bubbleColors = nil } self.wallpaper = decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper + self.themeIndex = decoder.decodeOptionalInt64ForKey("t") } public func encode(_ encoder: PostboxEncoder) { @@ -483,6 +469,11 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { } else { encoder.encodeNil(forKey: "w") } + if let themeIndex = self.themeIndex { + encoder.encodeInt64(themeIndex, forKey: "t") + } else { + encoder.encodeNil(forKey: "t") + } } public var color: UIColor { @@ -525,7 +516,6 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { public struct PresentationThemeSettings: PreferencesEntry { public var theme: PresentationThemeReference public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor] - public var themeSpecificCustomColors: [Int64: PresentationThemeCustomColors] public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper] public var useSystemFont: Bool public var fontSize: PresentationFontSize @@ -565,24 +555,16 @@ public struct PresentationThemeSettings: PreferencesEntry { resources.append(contentsOf: wallpaperResources(chatWallpaper)) } } - for (_, colors) in self.themeSpecificCustomColors { - for color in colors.colors { - if let wallpaper = color.wallpaper { - resources.append(contentsOf: wallpaperResources(wallpaper)) - } - } - } return resources } public static var defaultSettings: PresentationThemeSettings { - return PresentationThemeSettings(theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificCustomColors: [:], themeSpecificChatWallpapers: [:], useSystemFont: true, fontSize: .regular, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(trigger: .system, theme: .builtin(.night)), largeEmoji: true, disableAnimations: true) + return PresentationThemeSettings(theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificChatWallpapers: [:], useSystemFont: true, fontSize: .regular, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(trigger: .system, theme: .builtin(.night)), largeEmoji: true, disableAnimations: true) } - public init(theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificCustomColors: [Int64: PresentationThemeCustomColors], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], useSystemFont: Bool, fontSize: PresentationFontSize, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, disableAnimations: Bool) { + public init(theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], useSystemFont: Bool, fontSize: PresentationFontSize, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, disableAnimations: Bool) { self.theme = theme self.themeSpecificAccentColors = themeSpecificAccentColors - self.themeSpecificCustomColors = themeSpecificCustomColors self.themeSpecificChatWallpapers = themeSpecificChatWallpapers self.useSystemFont = useSystemFont self.fontSize = fontSize @@ -600,12 +582,6 @@ public struct PresentationThemeSettings: PreferencesEntry { return TelegramWallpaper(decoder: decoder) }) - self.themeSpecificCustomColors = decoder.decodeObjectDictionaryForKey("themeSpecificCustomColors", keyDecoder: { decoder in - return decoder.decodeInt64ForKey("k", orElse: 0) - }, valueDecoder: { decoder in - return PresentationThemeCustomColors(decoder: decoder) - }) - self.themeSpecificAccentColors = decoder.decodeObjectDictionaryForKey("themeSpecificAccentColors", keyDecoder: { decoder in return decoder.decodeInt64ForKey("k", orElse: 0) }, valueDecoder: { decoder in @@ -624,9 +600,6 @@ public struct PresentationThemeSettings: PreferencesEntry { encoder.encodeObjectDictionary(self.themeSpecificAccentColors, forKey: "themeSpecificAccentColors", keyEncoder: { key, encoder in encoder.encodeInt64(key, forKey: "k") }) - encoder.encodeObjectDictionary(self.themeSpecificCustomColors, forKey: "themeSpecificCustomColors", keyEncoder: { key, encoder in - encoder.encodeInt64(key, forKey: "k") - }) encoder.encodeObjectDictionary(self.themeSpecificChatWallpapers, forKey: "themeSpecificChatWallpapers", keyEncoder: { key, encoder in encoder.encodeInt64(key, forKey: "k") }) @@ -646,43 +619,39 @@ public struct PresentationThemeSettings: PreferencesEntry { } public static func ==(lhs: PresentationThemeSettings, rhs: PresentationThemeSettings) -> Bool { - return lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificCustomColors == rhs.themeSpecificCustomColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.useSystemFont == rhs.useSystemFont && lhs.fontSize == rhs.fontSize && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.disableAnimations == rhs.disableAnimations + return lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.useSystemFont == rhs.useSystemFont && lhs.fontSize == rhs.fontSize && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.disableAnimations == rhs.disableAnimations } public func withUpdatedTheme(_ theme: PresentationThemeReference) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedThemeSpecificAccentColors(_ themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) - } - - public func withUpdatedThemeSpecificCustomColors(_ themeSpecificCustomColors: [Int64: PresentationThemeCustomColors]) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedThemeSpecificChatWallpapers(_ themeSpecificChatWallpapers: [Int64: TelegramWallpaper]) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedUseSystemFont(_ useSystemFont: Bool) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedFontSize(_ fontSize: PresentationFontSize) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedAutomaticThemeSwitchSetting(_ automaticThemeSwitchSetting: AutomaticThemeSwitchSetting) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedLargeEmoji(_ largeEmoji: Bool) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: largeEmoji, disableAnimations: self.disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: largeEmoji, disableAnimations: self.disableAnimations) } public func withUpdatedDisableAnimations(_ disableAnimations: Bool) -> PresentationThemeSettings { - return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: disableAnimations) + return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: disableAnimations) } } diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 034981aafb..18d857c3d4 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -1159,78 +1159,101 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the } else if case let .cloud(theme) = theme, let resource = theme.theme.file?.resource { reference = .theme(theme: .slug(theme.theme.slug), resource: resource) } + + let themeSignal: Signal if let reference = reference { - colorsSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false) - |> mapToSignal { data -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in + themeSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false) + |> map { data -> PresentationTheme? in if let data = data, let theme = makePresentationTheme(data: data) { - var wallpaperSignal: Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete() - var rotation: Int32? - let backgroundColor: (UIColor, UIColor?) - let incomingColor = (theme.chat.message.incoming.bubble.withoutWallpaper.fill, theme.chat.message.incoming.bubble.withoutWallpaper.gradientFill) - let outgoingColor = (theme.chat.message.outgoing.bubble.withoutWallpaper.fill, theme.chat.message.outgoing.bubble.withoutWallpaper.gradientFill) - switch theme.chat.defaultWallpaper { - case .builtin: - backgroundColor = (UIColor(rgb: 0xd6e2ee), nil) - case let .color(color): - backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), nil) - case let .gradient(topColor, bottomColor, settings): - backgroundColor = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor))) - rotation = settings.rotation - case .image: - backgroundColor = (.black, nil) - case let .file(file): - rotation = file.settings.rotation - if file.isPattern, let color = file.settings.color { - backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), file.settings.bottomColor.flatMap { UIColor(rgb: UInt32(bitPattern: $0)) }) - } else { - backgroundColor = (theme.chatList.backgroundColor, nil) - } - wallpaperSignal = cachedWallpaper(account: account, slug: file.slug, settings: file.settings) - |> mapToSignal { wallpaper in - if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { - var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) - return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) - |> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in - guard complete, let fullSizeData = fullSizeData else { - return .complete() - } - accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData) - let _ = accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start() - - if file.isPattern, let color = file.settings.color, let intensity = file.settings.intensity { + return theme + } else { + return nil + } + } + } else if case let .cloud(theme) = theme, let settings = theme.theme.settings { + themeSignal = Signal { subscriber in + let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(rgb: UInt32(bitPattern: settings.accentColor)), backgroundColors: nil, bubbleColors: settings.messageColors.flatMap { (UIColor(rgb: UInt32(bitPattern: $0.top)), UIColor(rgb: UInt32(bitPattern: $0.bottom))) }, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false) + subscriber.putNext(theme) + subscriber.putCompletion() + + return EmptyDisposable + } + } else { + themeSignal = .never() + } + + colorsSignal = themeSignal + |> mapToSignal { theme -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in + if let theme = theme { + var wallpaperSignal: Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete() + var rotation: Int32? + let backgroundColor: (UIColor, UIColor?) + let incomingColor = (theme.chat.message.incoming.bubble.withoutWallpaper.fill, theme.chat.message.incoming.bubble.withoutWallpaper.gradientFill) + let outgoingColor = (theme.chat.message.outgoing.bubble.withoutWallpaper.fill, theme.chat.message.outgoing.bubble.withoutWallpaper.gradientFill) + switch theme.chat.defaultWallpaper { + case .builtin: + backgroundColor = (UIColor(rgb: 0xd6e2ee), nil) + case let .color(color): + backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), nil) + case let .gradient(topColor, bottomColor, settings): + backgroundColor = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor))) + rotation = settings.rotation + case .image: + backgroundColor = (.black, nil) + case let .file(file): + rotation = file.settings.rotation + if file.isPattern, let color = file.settings.color { + backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), file.settings.bottomColor.flatMap { UIColor(rgb: UInt32(bitPattern: $0)) }) + } else { + backgroundColor = (theme.chatList.backgroundColor, nil) + } + wallpaperSignal = cachedWallpaper(account: account, slug: file.slug, settings: file.settings) + |> mapToSignal { wallpaper in + if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { + var convertedRepresentations: [ImageRepresentationWithReference] = [] + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) + return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) + |> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in + guard complete, let fullSizeData = fullSizeData else { + return .complete() + } + accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData) + let _ = accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start() + + if file.isPattern { + if let color = file.settings.color, let intensity = file.settings.intensity { return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(color: color, bottomColor: file.settings.bottomColor, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true) |> mapToSignal { _ in return .complete() } - } else if file.settings.blur { - return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true) - |> mapToSignal { _ in - if let image = UIImage(data: fullSizeData) { - return .single((backgroundColor, incomingColor, outgoingColor, image, rotation)) - } else { - return .complete() - } - } - } else if let image = UIImage(data: fullSizeData) { - return .single((backgroundColor, incomingColor, outgoingColor, image, rotation)) } else { return .complete() } + } else if file.settings.blur { + return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true) + |> mapToSignal { _ in + if let image = UIImage(data: fullSizeData) { + return .single((backgroundColor, incomingColor, outgoingColor, image, rotation)) + } else { + return .complete() + } + } + } else if let image = UIImage(data: fullSizeData) { + return .single((backgroundColor, incomingColor, outgoingColor, image, rotation)) + } else { + return .complete() } - } else { - return .complete() } + } else { + return .complete() } - } - return .single((backgroundColor, incomingColor, outgoingColor, nil, rotation)) - |> then(wallpaperSignal) - } else { - return .complete() + } } + return .single((backgroundColor, incomingColor, outgoingColor, nil, rotation)) + |> then(wallpaperSignal) + } else { + return .complete() } - } else { - colorsSignal = .never() } } return colorsSignal