Merge commit 'f3120ee918d07bc9c109c8d2f83759e671d9942e'

This commit is contained in:
Ali 2019-11-07 17:16:24 +04:00
commit 7c912987e1
30 changed files with 2202 additions and 2170 deletions

View File

@ -5082,6 +5082,9 @@ Any member of this group will be able to see messages in the channel.";
"ClearCache.StorageFree" = "Free"; "ClearCache.StorageFree" = "Free";
"ClearCache.ClearCache" = "Clear Telegram Cache"; "ClearCache.ClearCache" = "Clear Telegram Cache";
"ClearCache.Clear" = "Clear"; "ClearCache.Clear" = "Clear";
"ClearCache.Forever" = "Forever";
"ChatList.DeletedChats_1" = "Deleted 1 chat"; "ChatList.DeletedChats_1" = "Deleted 1 chat";
"ChatList.DeletedChats_any" = "Deleted %@ chats"; "ChatList.DeletedChats_any" = "Deleted %@ chats";
"Appearance.ColorThemeNight" = "COLOR THEME — AUTO-NIGHT MODE";

View File

@ -31,8 +31,6 @@ public final class AnimationNode : ASDisplayNode {
view.backgroundColor = .clear view.backgroundColor = .clear
view.isOpaque = false view.isOpaque = false
view.logHierarchyKeypaths()
if let colors = colors { if let colors = colors {
for (key, value) in colors { for (key, value) in colors {
let colorCallback = LOTColorValueCallback(color: value.cgColor) let colorCallback = LOTColorValueCallback(color: value.cgColor)

View File

@ -1221,7 +1221,7 @@
{ {
[super scrollViewDidScroll:scrollView]; [super scrollViewDidScroll:scrollView];
_mapView.compassInsets = UIEdgeInsetsMake(TGLocationMapInset + 108.0f + (scrollView.contentOffset.y + scrollView.contentInset.top) / 2.0f, 0.0f, 0.0f, 10.0f + TGScreenPixel); _mapView.compassInsets = UIEdgeInsetsMake(TGLocationMapInset + 120.0f + (scrollView.contentOffset.y + scrollView.contentInset.top) / 2.0f, 0.0f, 0.0f, 10.0f + TGScreenPixel);
} }
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

View File

@ -202,11 +202,16 @@ public final class MediaBox {
return "\(self.basePath)/\(cacheString)/\(fileNameForId(id)):\(representation.uniqueId)" return "\(self.basePath)/\(cacheString)/\(fileNameForId(id)):\(representation.uniqueId)"
} }
public func storeResourceData(_ id: MediaResourceId, data: Data) { public func storeResourceData(_ id: MediaResourceId, data: Data, synchronous: Bool = false) {
self.dataQueue.async { let begin = {
let paths = self.storePathsForId(id) let paths = self.storePathsForId(id)
let _ = try? data.write(to: URL(fileURLWithPath: paths.complete), options: [.atomic]) let _ = try? data.write(to: URL(fileURLWithPath: paths.complete), options: [.atomic])
} }
if synchronous {
begin()
} else {
self.dataQueue.async(begin)
}
} }
public func moveResourceData(_ id: MediaResourceId, fromTempPath: String) { public func moveResourceData(_ id: MediaResourceId, fromTempPath: String) {

View File

@ -13,7 +13,7 @@ import PresentationDataUtils
private func stringForKeepMediaTimeout(strings: PresentationStrings, timeout: Int32) -> String { private func stringForKeepMediaTimeout(strings: PresentationStrings, timeout: Int32) -> String {
if timeout > 1 * 31 * 24 * 60 * 60 { if timeout > 1 * 31 * 24 * 60 * 60 {
return strings.MessageTimer_Forever return strings.ClearCache_Forever
} else { } else {
return timeIntervalString(strings: strings, value: timeout) return timeIntervalString(strings: strings, value: timeout)
} }

View File

@ -288,12 +288,12 @@ private func storageUsageControllerEntries(presentationData: PresentationData, c
let totalSpaceValue = CGFloat(totalSpace) let totalSpaceValue = CGFloat(totalSpace)
if telegramCacheSize > 0 { if telegramCacheSize > 0 {
categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageCache, size: totalTelegramSize, fraction: CGFloat(totalTelegramSize) / totalSpaceValue, color: presentationData.theme.list.itemAccentColor)) categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageCache, size: totalTelegramSize, fraction: CGFloat(totalTelegramSize) / totalSpaceValue, color: presentationData.theme.list.itemBarChart.color1))
} else { } else {
categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageServiceFiles, size: totalTelegramSize, fraction: CGFloat(totalTelegramSize) / totalSpaceValue, color: presentationData.theme.list.itemAccentColor)) categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageServiceFiles, size: totalTelegramSize, fraction: CGFloat(totalTelegramSize) / totalSpaceValue, color: presentationData.theme.list.itemBarChart.color1))
} }
categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageOtherApps, size: otherAppsSpace, fraction: CGFloat(otherAppsSpace) / totalSpaceValue, color: presentationData.theme.list.itemBlocksSeparatorColor)) categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageOtherApps, size: otherAppsSpace, fraction: CGFloat(otherAppsSpace) / totalSpaceValue, color: presentationData.theme.list.itemBarChart.color2))
categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageFree, size: freeSpace, fraction: CGFloat(freeSpace) / totalSpaceValue, color: UIColor(rgb: 0xf2f1f7))) categories.append(StorageUsageCategory(title: presentationData.strings.ClearCache_StorageFree, size: freeSpace, fraction: CGFloat(freeSpace) / totalSpaceValue, color: presentationData.theme.list.itemBarChart.color3))
entries.append(.storageUsage(presentationData.theme, presentationData.dateTimeFormat, categories)) entries.append(.storageUsage(presentationData.theme, presentationData.dateTimeFormat, categories))
@ -433,11 +433,10 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
controller?.updateItem(groupIndex: 0, itemIndex: itemIndex, { item in controller?.updateItem(groupIndex: 0, itemIndex: itemIndex, { item in
let title: String let title: String
var filteredSize = sizeIndex.values.reduce(0, { $0 + ($1.0 ? $1.1 : 0) }) var filteredSize = sizeIndex.values.reduce(0, { $0 + ($1.0 ? $1.1 : 0) })
selectedSize = filteredSize
if otherSize.0 { if otherSize.0 {
filteredSize += otherSize.1 filteredSize += otherSize.1
} }
selectedSize = filteredSize
if filteredSize == 0 { if filteredSize == 0 {
title = presentationData.strings.Cache_ClearNone title = presentationData.strings.Cache_ClearNone

View File

@ -180,7 +180,7 @@ private final class StorageUsageItemNode: ListViewItemNode {
let inset: CGFloat = 16.0 let inset: CGFloat = 16.0
let horizontalSpacing: CGFloat = 32.0 let horizontalSpacing: CGFloat = 32.0
let verticalSpacing: CGFloat = 22.0 let verticalSpacing: CGFloat = 22.0
var textOrigin: CGPoint = CGPoint(x: horizontalSpacing, y: 52.0) var textOrigin: CGPoint = CGPoint(x: params.leftInset + horizontalSpacing, y: 52.0)
for i in 0 ..< item.categories.count { for i in 0 ..< item.categories.count {
let makeTextLayout = makeNodesLayout[i] let makeTextLayout = makeNodesLayout[i]
@ -281,7 +281,7 @@ private final class StorageUsageItemNode: ListViewItemNode {
var categoryWidth = max(floor(lineWidth * category.fraction), 2.0) var categoryWidth = max(floor(lineWidth * category.fraction), 2.0)
if i == strongSelf.lineNodes.count - 1 { if i == strongSelf.lineNodes.count - 1 {
categoryWidth = lineWidth - (lineOrigin.x - lineInset) categoryWidth = max(0.0, lineWidth - (lineOrigin.x - lineInset))
} }
let lineRect = CGRect(origin: lineOrigin, size: CGSize(width: categoryWidth, height: 21.0)) let lineRect = CGRect(origin: lineOrigin, size: CGSize(width: categoryWidth, height: 21.0))

View File

@ -360,7 +360,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
private func themeSettingsControllerEntries(presentationData: PresentationData, theme: PresentationTheme, themeReference: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], availableThemes: [PresentationThemeReference], autoNightSettings: AutomaticThemeSwitchSetting, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, largeEmoji: Bool, disableAnimations: Bool, availableAppIcons: [PresentationAppIcon], currentAppIconName: String?) -> [ThemeSettingsControllerEntry] { private func themeSettingsControllerEntries(presentationData: PresentationData, theme: PresentationTheme, themeReference: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], availableThemes: [PresentationThemeReference], autoNightSettings: AutomaticThemeSwitchSetting, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, largeEmoji: Bool, disableAnimations: Bool, availableAppIcons: [PresentationAppIcon], currentAppIconName: String?) -> [ThemeSettingsControllerEntry] {
var entries: [ThemeSettingsControllerEntry] = [] var entries: [ThemeSettingsControllerEntry] = []
entries.append(.themeListHeader(presentationData.theme, strings.Appearance_ColorTheme.uppercased())) let title = presentationData.autoNightModeTriggered ? strings.Appearance_ColorThemeNight.uppercased() : strings.Appearance_ColorTheme.uppercased()
entries.append(.themeListHeader(presentationData.theme, title))
entries.append(.chatPreview(presentationData.theme, theme, wallpaper, fontSize, presentationData.strings, dateTimeFormat, presentationData.nameDisplayOrder, [ChatPreviewMessageItem(outgoing: false, reply: (presentationData.strings.Appearance_PreviewReplyAuthor, presentationData.strings.Appearance_PreviewReplyText), text: presentationData.strings.Appearance_PreviewIncomingText), ChatPreviewMessageItem(outgoing: true, reply: nil, text: presentationData.strings.Appearance_PreviewOutgoingText)])) entries.append(.chatPreview(presentationData.theme, theme, wallpaper, fontSize, presentationData.strings, dateTimeFormat, presentationData.nameDisplayOrder, [ChatPreviewMessageItem(outgoing: false, reply: (presentationData.strings.Appearance_PreviewReplyAuthor, presentationData.strings.Appearance_PreviewReplyText), text: presentationData.strings.Appearance_PreviewIncomingText), ChatPreviewMessageItem(outgoing: true, reply: nil, text: presentationData.strings.Appearance_PreviewOutgoingText)]))
entries.append(.themeItem(presentationData.theme, presentationData.strings, availableThemes, themeReference, themeSpecificAccentColors, themeSpecificAccentColors[themeReference.index])) entries.append(.themeItem(presentationData.theme, presentationData.strings, availableThemes, themeReference, themeSpecificAccentColors, themeSpecificAccentColors[themeReference.index]))
@ -371,22 +372,22 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
entries.append(.wallpaper(presentationData.theme, strings.Settings_ChatBackground)) entries.append(.wallpaper(presentationData.theme, strings.Settings_ChatBackground))
let title: String let autoNightMode: String
switch autoNightSettings.trigger { switch autoNightSettings.trigger {
case .system: case .system:
if #available(iOSApplicationExtension 13.0, iOS 13.0, *) { if #available(iOSApplicationExtension 13.0, iOS 13.0, *) {
title = strings.AutoNightTheme_System autoNightMode = strings.AutoNightTheme_System
} else { } else {
title = strings.AutoNightTheme_Disabled autoNightMode = strings.AutoNightTheme_Disabled
} }
case .explicitNone: case .explicitNone:
title = strings.AutoNightTheme_Disabled autoNightMode = strings.AutoNightTheme_Disabled
case .timeBased: case .timeBased:
title = strings.AutoNightTheme_Scheduled autoNightMode = strings.AutoNightTheme_Scheduled
case .brightness: case .brightness:
title = strings.AutoNightTheme_Automatic autoNightMode = strings.AutoNightTheme_Automatic
} }
entries.append(.autoNightTheme(presentationData.theme, strings.Appearance_AutoNightTheme, title)) entries.append(.autoNightTheme(presentationData.theme, strings.Appearance_AutoNightTheme, autoNightMode))
entries.append(.fontSizeHeader(presentationData.theme, strings.Appearance_TextSize.uppercased())) entries.append(.fontSizeHeader(presentationData.theme, strings.Appearance_TextSize.uppercased()))
entries.append(.fontSize(presentationData.theme, fontSize)) entries.append(.fontSize(presentationData.theme, fontSize))
@ -568,16 +569,17 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
let largeEmoji = presentationData.largeEmoji let largeEmoji = presentationData.largeEmoji
let disableAnimations = presentationData.disableAnimations let disableAnimations = presentationData.disableAnimations
let accentColor = settings.themeSpecificAccentColors[settings.theme.index]?.color let themeReference: PresentationThemeReference
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: settings.theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: settings.themeSpecificAccentColors[settings.theme.index]?.baseColor ?? .blue, preview: true) ?? defaultPresentationTheme if presentationData.autoNightModeTriggered {
themeReference = settings.automaticThemeSwitchSetting.theme
let wallpaper: TelegramWallpaper
if let themeSpecificWallpaper = settings.themeSpecificChatWallpapers[settings.theme.index] {
wallpaper = themeSpecificWallpaper
} else { } else {
wallpaper = settings.chatWallpaper themeReference = settings.theme
} }
let theme = presentationData.theme
let accentColor = settings.themeSpecificAccentColors[themeReference.index]?.color
let wallpaper = settings.themeSpecificChatWallpapers[themeReference.index] ?? settings.chatWallpaper
let rightNavigationButton = ItemListNavigationButton(content: .icon(.action), style: .regular, enabled: true, action: { let rightNavigationButton = ItemListNavigationButton(content: .icon(.action), style: .regular, enabled: true, action: {
moreImpl?() moreImpl?()
}) })
@ -586,13 +588,13 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
let cloudThemes: [PresentationThemeReference] = cloudThemes.map { .cloud(PresentationCloudTheme(theme: $0, resolvedWallpaper: nil)) } let cloudThemes: [PresentationThemeReference] = cloudThemes.map { .cloud(PresentationCloudTheme(theme: $0, resolvedWallpaper: nil)) }
var availableThemes = defaultThemes var availableThemes = defaultThemes
if defaultThemes.first(where: { $0.index == settings.theme.index }) == nil && cloudThemes.first(where: { $0.index == settings.theme.index }) == nil { if defaultThemes.first(where: { $0.index == themeReference.index }) == nil && cloudThemes.first(where: { $0.index == themeReference.index }) == nil {
availableThemes.append(settings.theme) availableThemes.append(themeReference)
} }
availableThemes.append(contentsOf: cloudThemes) availableThemes.append(contentsOf: cloudThemes)
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Appearance_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back)) let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Appearance_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
let listState = ItemListNodeState(entries: themeSettingsControllerEntries(presentationData: presentationData, theme: theme, themeReference: settings.theme, themeSpecificAccentColors: settings.themeSpecificAccentColors, availableThemes: availableThemes, autoNightSettings: settings.automaticThemeSwitchSetting, strings: presentationData.strings, wallpaper: wallpaper, fontSize: fontSize, dateTimeFormat: dateTimeFormat, largeEmoji: largeEmoji, disableAnimations: disableAnimations, availableAppIcons: availableAppIcons, currentAppIconName: currentAppIconName), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false) let listState = ItemListNodeState(entries: themeSettingsControllerEntries(presentationData: presentationData, theme: theme, themeReference: themeReference, themeSpecificAccentColors: settings.themeSpecificAccentColors, availableThemes: availableThemes, autoNightSettings: settings.automaticThemeSwitchSetting, strings: presentationData.strings, wallpaper: wallpaper, fontSize: fontSize, dateTimeFormat: dateTimeFormat, largeEmoji: largeEmoji, disableAnimations: disableAnimations, availableAppIcons: availableAppIcons, currentAppIconName: currentAppIconName), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false)
return (controllerState, (listState, arguments)) return (controllerState, (listState, arguments))
} }
@ -616,6 +618,8 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
return return
} }
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
let resolvedWallpaper: Signal<TelegramWallpaper?, NoError> let resolvedWallpaper: Signal<TelegramWallpaper?, NoError>
if case let .file(file) = presentationTheme.chat.defaultWallpaper, file.id == 0 { if case let .file(file) = presentationTheme.chat.defaultWallpaper, file.id == 0 {
resolvedWallpaper = cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings) resolvedWallpaper = cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings)
@ -647,6 +651,14 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
current = PresentationThemeSettings.defaultSettings current = PresentationThemeSettings.defaultSettings
} }
var theme = current.theme
var automaticThemeSwitchSetting = current.automaticThemeSwitchSetting
if autoNightModeTriggered {
automaticThemeSwitchSetting.theme = updatedTheme
} else {
theme = updatedTheme
}
let chatWallpaper: TelegramWallpaper let chatWallpaper: TelegramWallpaper
if let themeSpecificWallpaper = current.themeSpecificChatWallpapers[updatedTheme.index] { if let themeSpecificWallpaper = current.themeSpecificChatWallpapers[updatedTheme.index] {
chatWallpaper = themeSpecificWallpaper chatWallpaper = themeSpecificWallpaper
@ -655,7 +667,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
chatWallpaper = resolvedWallpaper ?? presentationTheme.chat.defaultWallpaper chatWallpaper = resolvedWallpaper ?? presentationTheme.chat.defaultWallpaper
} }
return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: updatedTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}) })
}) })
}).start() }).start()

View File

@ -112,7 +112,7 @@ private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, sl
if let color = color { if let color = color {
colorValue = Int32(bitPattern: color.rgb) colorValue = Int32(bitPattern: color.rgb)
intensityValue = intensity intensityValue = intensity
} else { } else if isPattern {
colorValue = 0xd6e2ee colorValue = 0xd6e2ee
intensityValue = 50 intensityValue = 50
} }
@ -384,10 +384,11 @@ public class WallpaperGalleryController: ViewController {
let updatedSettings = WallpaperSettings(blur: options.contains(.blur), motion: options.contains(.motion), color: baseSettings?.color, intensity: baseSettings?.intensity) let updatedSettings = WallpaperSettings(blur: options.contains(.blur), motion: options.contains(.motion), color: baseSettings?.color, intensity: baseSettings?.intensity)
let wallpaper = wallpaper.withUpdatedSettings(updatedSettings) let wallpaper = wallpaper.withUpdatedSettings(updatedSettings)
let autoNightModeTriggered = strongSelf.presentationData.autoNightModeTriggered
let _ = (updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in let _ = (updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
var chatWallpaper = current.chatWallpaper var chatWallpaper = current.chatWallpaper
if automaticThemeShouldSwitchNow(settings: current.automaticThemeSwitchSetting, systemUserInterfaceStyle: .light) { if autoNightModeTriggered {
themeSpecificChatWallpapers[current.automaticThemeSwitchSetting.theme.index] = wallpaper themeSpecificChatWallpapers[current.automaticThemeSwitchSetting.theme.index] = wallpaper
} else { } else {
themeSpecificChatWallpapers[current.theme.index] = wallpaper themeSpecificChatWallpapers[current.theme.index] = wallpaper
@ -412,23 +413,41 @@ public class WallpaperGalleryController: ViewController {
if options.contains(.blur) { if options.contains(.blur) {
if let resource = resource { if let resource = resource {
let representation = CachedBlurredWallpaperRepresentation() let representation = CachedBlurredWallpaperRepresentation()
let _ = strongSelf.context.account.postbox.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true).start()
if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { var data: Data?
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data) if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
let _ = strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true).start(completed: { data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
let _ = (strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|> filter({ $0.complete })
|> take(1)
|> deliverOnMainQueue).start(next: { _ in
completion(wallpaper) completion(wallpaper)
}) })
} }
} }
} else if case let .file(file) = wallpaper { } else if case let .file(file) = wallpaper, let resource = resource {
if file.isPattern, let color = file.settings.color, let intensity = file.settings.intensity { if file.isPattern, let color = file.settings.color, let intensity = file.settings.intensity {
let representation = CachedPatternWallpaperRepresentation(color: color, intensity: intensity) let representation = CachedPatternWallpaperRepresentation(color: color, intensity: intensity)
let _ = strongSelf.context.account.postbox.mediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true).start()
if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(file.file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { var data: Data?
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(file.file.resource.id, data: data) if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
let _ = strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true).start(completed: { data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
let _ = (strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|> filter({ $0.complete })
|> take(1)
|> deliverOnMainQueue).start(next: { _ in
completion(wallpaper) completion(wallpaper)
}) })
} }

View File

@ -292,8 +292,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
signal = wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: fileReference, representations: convertedRepresentations, alwaysShowThumbnailFirst: true, autoFetchFullSize: false) signal = wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: fileReference, representations: convertedRepresentations, alwaysShowThumbnailFirst: true, autoFetchFullSize: false)
} }
fetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: convertedRepresentations[convertedRepresentations.count - 1].reference) fetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: convertedRepresentations[convertedRepresentations.count - 1].reference)
let account = context.account let account = self.context.account
statusSignal = context.sharedContext.accountManager.mediaBox.resourceStatus(file.file.resource) statusSignal = self.context.sharedContext.accountManager.mediaBox.resourceStatus(file.file.resource)
|> take(1) |> take(1)
|> mapToSignal { status -> Signal<MediaResourceStatus, NoError> in |> mapToSignal { status -> Signal<MediaResourceStatus, NoError> in
if case .Local = status { if case .Local = status {

View File

@ -179,7 +179,8 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
mediaPlaceholderColor: UIColor(rgb: 0x1c1c1d), mediaPlaceholderColor: UIColor(rgb: 0x1c1c1d),
scrollIndicatorColor: UIColor(white: 1.0, alpha: 0.3), scrollIndicatorColor: UIColor(white: 1.0, alpha: 0.3),
pageIndicatorInactiveColor: UIColor(white: 1.0, alpha: 0.3), pageIndicatorInactiveColor: UIColor(white: 1.0, alpha: 0.3),
inputClearButtonColor: UIColor(rgb: 0x8b9197) inputClearButtonColor: UIColor(rgb: 0x8b9197),
itemBarChart: PresentationThemeItemBarChart(color1: accentColor, color2: UIColor(rgb: 0x929196), color3: UIColor(rgb: 0x333333))
) )
let chatList = PresentationThemeChatList( let chatList = PresentationThemeChatList(

View File

@ -155,7 +155,8 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
mediaPlaceholderColor: accentColor.withMultiplied(hue: 1.019, saturation: 0.585, brightness: 0.23), mediaPlaceholderColor: accentColor.withMultiplied(hue: 1.019, saturation: 0.585, brightness: 0.23),
scrollIndicatorColor: UIColor(white: 1.0, alpha: 0.3), scrollIndicatorColor: UIColor(white: 1.0, alpha: 0.3),
pageIndicatorInactiveColor: mainSecondaryTextColor.withAlphaComponent(0.4), pageIndicatorInactiveColor: mainSecondaryTextColor.withAlphaComponent(0.4),
inputClearButtonColor: mainSecondaryColor inputClearButtonColor: mainSecondaryColor,
itemBarChart: PresentationThemeItemBarChart(color1: accentColor, color2: UIColor(rgb: 0x929196), color3: UIColor(rgb: 0x333333))
) )
let chatList = PresentationThemeChatList( let chatList = PresentationThemeChatList(

View File

@ -163,7 +163,8 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr
mediaPlaceholderColor: UIColor(rgb: 0xe4e4e4), mediaPlaceholderColor: UIColor(rgb: 0xe4e4e4),
scrollIndicatorColor: UIColor(white: 0.0, alpha: 0.3), scrollIndicatorColor: UIColor(white: 0.0, alpha: 0.3),
pageIndicatorInactiveColor: UIColor(rgb: 0xe3e3e7), pageIndicatorInactiveColor: UIColor(rgb: 0xe3e3e7),
inputClearButtonColor: UIColor(rgb: 0xcccccc) inputClearButtonColor: UIColor(rgb: 0xcccccc),
itemBarChart: PresentationThemeItemBarChart(color1: accentColor, color2: UIColor(rgb: 0xc8c7cc), color3: UIColor(rgb: 0xf2f1f7))
) )
let chatList = PresentationThemeChatList( let chatList = PresentationThemeChatList(

View File

@ -26,16 +26,6 @@ public struct PresentationDateTimeFormat: Equatable {
} }
} }
public struct PresentationVolumeControlStatusBarIcons: Equatable {
public let offIcon: UIImage
public let halfIcon: UIImage
public let fullIcon: UIImage
public var images: (UIImage, UIImage, UIImage) {
return (self.offIcon, self.halfIcon, self.fullIcon)
}
}
public struct PresentationAppIcon: Equatable { public struct PresentationAppIcon: Equatable {
public let name: String public let name: String
public let imageName: String public let imageName: String
@ -61,8 +51,8 @@ public enum PresentationDateFormat {
public final class PresentationData: Equatable { public final class PresentationData: Equatable {
public let strings: PresentationStrings public let strings: PresentationStrings
public let theme: PresentationTheme public let theme: PresentationTheme
public let autoNightModeTriggered: Bool
public let chatWallpaper: TelegramWallpaper public let chatWallpaper: TelegramWallpaper
public let volumeControlStatusBarIcons: PresentationVolumeControlStatusBarIcons
public let fontSize: PresentationFontSize public let fontSize: PresentationFontSize
public let dateTimeFormat: PresentationDateTimeFormat public let dateTimeFormat: PresentationDateTimeFormat
public let nameDisplayOrder: PresentationPersonNameOrder public let nameDisplayOrder: PresentationPersonNameOrder
@ -70,11 +60,11 @@ public final class PresentationData: Equatable {
public let disableAnimations: Bool public let disableAnimations: Bool
public let largeEmoji: Bool public let largeEmoji: Bool
public init(strings: PresentationStrings, theme: PresentationTheme, chatWallpaper: TelegramWallpaper, volumeControlStatusBarIcons: PresentationVolumeControlStatusBarIcons, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, nameSortOrder: PresentationPersonNameOrder, disableAnimations: Bool, largeEmoji: Bool) { public init(strings: PresentationStrings, theme: PresentationTheme, autoNightModeTriggered: Bool, chatWallpaper: TelegramWallpaper, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, nameSortOrder: PresentationPersonNameOrder, disableAnimations: Bool, largeEmoji: Bool) {
self.strings = strings self.strings = strings
self.theme = theme self.theme = theme
self.autoNightModeTriggered = autoNightModeTriggered
self.chatWallpaper = chatWallpaper self.chatWallpaper = chatWallpaper
self.volumeControlStatusBarIcons = volumeControlStatusBarIcons
self.fontSize = fontSize self.fontSize = fontSize
self.dateTimeFormat = dateTimeFormat self.dateTimeFormat = dateTimeFormat
self.nameDisplayOrder = nameDisplayOrder self.nameDisplayOrder = nameDisplayOrder
@ -84,7 +74,7 @@ public final class PresentationData: Equatable {
} }
public static func ==(lhs: PresentationData, rhs: PresentationData) -> Bool { public static func ==(lhs: PresentationData, rhs: PresentationData) -> Bool {
return lhs.strings === rhs.strings && lhs.theme === rhs.theme && lhs.chatWallpaper == rhs.chatWallpaper && lhs.volumeControlStatusBarIcons == rhs.volumeControlStatusBarIcons && lhs.fontSize == rhs.fontSize && lhs.dateTimeFormat == rhs.dateTimeFormat && lhs.disableAnimations == rhs.disableAnimations && lhs.largeEmoji == rhs.largeEmoji return lhs.strings === rhs.strings && lhs.theme === rhs.theme && lhs.autoNightModeTriggered == rhs.autoNightModeTriggered && lhs.chatWallpaper == rhs.chatWallpaper && lhs.fontSize == rhs.fontSize && lhs.dateTimeFormat == rhs.dateTimeFormat && lhs.disableAnimations == rhs.disableAnimations && lhs.largeEmoji == rhs.largeEmoji
} }
} }
@ -116,11 +106,6 @@ public func dictFromLocalization(_ value: Localization) -> [String: String] {
return dict return dict
} }
private func volumeControlStatusBarIcons() -> PresentationVolumeControlStatusBarIcons {
let bundle = getAppBundle()
return PresentationVolumeControlStatusBarIcons(offIcon: UIImage(named: "Components/Volume/VolumeOff", in: bundle, compatibleWith: nil)!, halfIcon: UIImage(named: "Components/Volume/VolumeHalf", in: bundle, compatibleWith: nil)!, fullIcon: UIImage(named: "Components/Volume/VolumeFull", in: bundle, compatibleWith: nil)!)
}
private func currentDateTimeFormat() -> PresentationDateTimeFormat { private func currentDateTimeFormat() -> PresentationDateTimeFormat {
let locale = Locale.current let locale = Locale.current
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
@ -249,10 +234,13 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager, s
var effectiveChatWallpaper: TelegramWallpaper = themeSettings.chatWallpaper var effectiveChatWallpaper: TelegramWallpaper = themeSettings.chatWallpaper
let parameters = AutomaticThemeSwitchParameters(settings: themeSettings.automaticThemeSwitchSetting) let parameters = AutomaticThemeSwitchParameters(settings: themeSettings.automaticThemeSwitchSetting)
let autoNightModeTriggered: Bool
if automaticThemeShouldSwitchNow(parameters, systemUserInterfaceStyle: systemUserInterfaceStyle) { if automaticThemeShouldSwitchNow(parameters, systemUserInterfaceStyle: systemUserInterfaceStyle) {
effectiveTheme = themeSettings.automaticThemeSwitchSetting.theme effectiveTheme = themeSettings.automaticThemeSwitchSetting.theme
autoNightModeTriggered = true
} else { } else {
effectiveTheme = themeSettings.theme effectiveTheme = themeSettings.theme
autoNightModeTriggered = false
} }
let effectiveAccentColor = themeSettings.themeSpecificAccentColors[effectiveTheme.index]?.color let effectiveAccentColor = themeSettings.themeSpecificAccentColors[effectiveTheme.index]?.color
@ -276,7 +264,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager, s
} }
let nameDisplayOrder = contactSettings.nameDisplayOrder let nameDisplayOrder = contactSettings.nameDisplayOrder
let nameSortOrder = currentPersonNameSortOrder() let nameSortOrder = currentPersonNameSortOrder()
return InitialPresentationDataAndSettings(presentationData: PresentationData(strings: stringsValue, theme: themeValue, chatWallpaper: effectiveChatWallpaper, volumeControlStatusBarIcons: volumeControlStatusBarIcons(), fontSize: themeSettings.fontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji), automaticMediaDownloadSettings: automaticMediaDownloadSettings, callListSettings: callListSettings, inAppNotificationSettings: inAppNotificationSettings, mediaInputSettings: mediaInputSettings, experimentalUISettings: experimentalUISettings) return InitialPresentationDataAndSettings(presentationData: PresentationData(strings: stringsValue, theme: themeValue, autoNightModeTriggered: autoNightModeTriggered, chatWallpaper: effectiveChatWallpaper, fontSize: themeSettings.fontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji), automaticMediaDownloadSettings: automaticMediaDownloadSettings, callListSettings: callListSettings, inAppNotificationSettings: inAppNotificationSettings, mediaInputSettings: mediaInputSettings, experimentalUISettings: experimentalUISettings)
} }
} }
@ -499,11 +487,11 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI
if inForeground { if inForeground {
return automaticThemeShouldSwitch(themeSettings.automaticThemeSwitchSetting, systemUserInterfaceStyle: systemUserInterfaceStyle) return automaticThemeShouldSwitch(themeSettings.automaticThemeSwitchSetting, systemUserInterfaceStyle: systemUserInterfaceStyle)
|> distinctUntilChanged |> distinctUntilChanged
|> map { shouldSwitch in |> map { autoNightModeTriggered in
var effectiveTheme: PresentationThemeReference var effectiveTheme: PresentationThemeReference
var effectiveChatWallpaper: TelegramWallpaper = currentWallpaper var effectiveChatWallpaper: TelegramWallpaper = currentWallpaper
if shouldSwitch { if autoNightModeTriggered {
let automaticTheme = themeSettings.automaticThemeSwitchSetting.theme let automaticTheme = themeSettings.automaticThemeSwitchSetting.theme
if let themeSpecificWallpaper = themeSettings.themeSpecificChatWallpapers[automaticTheme.index] { if let themeSpecificWallpaper = themeSettings.themeSpecificChatWallpapers[automaticTheme.index] {
effectiveChatWallpaper = themeSpecificWallpaper effectiveChatWallpaper = themeSpecificWallpaper
@ -546,7 +534,7 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI
let nameDisplayOrder = contactSettings.nameDisplayOrder let nameDisplayOrder = contactSettings.nameDisplayOrder
let nameSortOrder = currentPersonNameSortOrder() let nameSortOrder = currentPersonNameSortOrder()
return PresentationData(strings: stringsValue, theme: themeValue, chatWallpaper: effectiveChatWallpaper, volumeControlStatusBarIcons: volumeControlStatusBarIcons(), fontSize: themeSettings.fontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji) return PresentationData(strings: stringsValue, theme: themeValue, autoNightModeTriggered: autoNightModeTriggered, chatWallpaper: effectiveChatWallpaper, fontSize: themeSettings.fontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji)
} }
} else { } else {
return .complete() return .complete()
@ -562,5 +550,5 @@ public func defaultPresentationData() -> PresentationData {
let nameSortOrder = currentPersonNameSortOrder() let nameSortOrder = currentPersonNameSortOrder()
let themeSettings = PresentationThemeSettings.defaultSettings let themeSettings = PresentationThemeSettings.defaultSettings
return PresentationData(strings: defaultPresentationStrings, theme: defaultPresentationTheme, chatWallpaper: .builtin(WallpaperSettings()), volumeControlStatusBarIcons: volumeControlStatusBarIcons(), fontSize: themeSettings.fontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji) return PresentationData(strings: defaultPresentationStrings, theme: defaultPresentationTheme, autoNightModeTriggered: false, chatWallpaper: .builtin(WallpaperSettings()), fontSize: themeSettings.fontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji)
} }

View File

@ -289,6 +289,18 @@ public final class PresentationThemeItemDisclosureActions {
} }
} }
public final class PresentationThemeItemBarChart {
public let color1: UIColor
public let color2: UIColor
public let color3: UIColor
public init(color1: UIColor, color2: UIColor, color3: UIColor) {
self.color1 = color1
self.color2 = color2
self.color3 = color3
}
}
public final class PresentationThemeFillStrokeForeground { public final class PresentationThemeFillStrokeForeground {
public let fillColor: UIColor public let fillColor: UIColor
public let strokeColor: UIColor public let strokeColor: UIColor
@ -346,8 +358,9 @@ public final class PresentationThemeList {
public let scrollIndicatorColor: UIColor public let scrollIndicatorColor: UIColor
public let pageIndicatorInactiveColor: UIColor public let pageIndicatorInactiveColor: UIColor
public let inputClearButtonColor: UIColor public let inputClearButtonColor: UIColor
public let itemBarChart: PresentationThemeItemBarChart
public init(blocksBackgroundColor: UIColor, plainBackgroundColor: UIColor, itemPrimaryTextColor: UIColor, itemSecondaryTextColor: UIColor, itemDisabledTextColor: UIColor, itemAccentColor: UIColor, itemHighlightedColor: UIColor, itemDestructiveColor: UIColor, itemPlaceholderTextColor: UIColor, itemBlocksBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemBlocksSeparatorColor: UIColor, itemPlainSeparatorColor: UIColor, disclosureArrowColor: UIColor, sectionHeaderTextColor: UIColor, freeTextColor: UIColor, freeTextErrorColor: UIColor, freeTextSuccessColor: UIColor, freeMonoIconColor: UIColor, itemSwitchColors: PresentationThemeSwitch, itemDisclosureActions: PresentationThemeItemDisclosureActions, itemCheckColors: PresentationThemeFillStrokeForeground, controlSecondaryColor: UIColor, freeInputField: PresentationInputFieldTheme, mediaPlaceholderColor: UIColor, scrollIndicatorColor: UIColor, pageIndicatorInactiveColor: UIColor, inputClearButtonColor: UIColor) { public init(blocksBackgroundColor: UIColor, plainBackgroundColor: UIColor, itemPrimaryTextColor: UIColor, itemSecondaryTextColor: UIColor, itemDisabledTextColor: UIColor, itemAccentColor: UIColor, itemHighlightedColor: UIColor, itemDestructiveColor: UIColor, itemPlaceholderTextColor: UIColor, itemBlocksBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemBlocksSeparatorColor: UIColor, itemPlainSeparatorColor: UIColor, disclosureArrowColor: UIColor, sectionHeaderTextColor: UIColor, freeTextColor: UIColor, freeTextErrorColor: UIColor, freeTextSuccessColor: UIColor, freeMonoIconColor: UIColor, itemSwitchColors: PresentationThemeSwitch, itemDisclosureActions: PresentationThemeItemDisclosureActions, itemCheckColors: PresentationThemeFillStrokeForeground, controlSecondaryColor: UIColor, freeInputField: PresentationInputFieldTheme, mediaPlaceholderColor: UIColor, scrollIndicatorColor: UIColor, pageIndicatorInactiveColor: UIColor, inputClearButtonColor: UIColor, itemBarChart: PresentationThemeItemBarChart) {
self.blocksBackgroundColor = blocksBackgroundColor self.blocksBackgroundColor = blocksBackgroundColor
self.plainBackgroundColor = plainBackgroundColor self.plainBackgroundColor = plainBackgroundColor
self.itemPrimaryTextColor = itemPrimaryTextColor self.itemPrimaryTextColor = itemPrimaryTextColor
@ -376,6 +389,7 @@ public final class PresentationThemeList {
self.scrollIndicatorColor = scrollIndicatorColor self.scrollIndicatorColor = scrollIndicatorColor
self.pageIndicatorInactiveColor = pageIndicatorInactiveColor self.pageIndicatorInactiveColor = pageIndicatorInactiveColor
self.inputClearButtonColor = inputClearButtonColor self.inputClearButtonColor = inputClearButtonColor
self.itemBarChart = itemBarChart
} }
} }

View File

@ -5,7 +5,12 @@ import TelegramCore
import SyncCore import SyncCore
import TelegramUIPreferences import TelegramUIPreferences
private func decodeColor<Key>(_ values: KeyedDecodingContainer<Key>, _ key: Key) throws -> UIColor { private func decodeColor<Key>(_ values: KeyedDecodingContainer<Key>, _ key: Key, decoder: Decoder? = nil, fallbackKey: String? = nil) throws -> UIColor {
if let decoder = decoder as? PresentationThemeDecoding, let fallbackKey = fallbackKey {
let key = (decoder.codingPath.map { $0.stringValue } + [key.stringValue]).joined(separator: ".")
decoder.fallbackKeys[key] = fallbackKey
}
let value = try values.decode(String.self, forKey: key) let value = try values.decode(String.self, forKey: key)
if value.lowercased() == "clear" { if value.lowercased() == "clear" {
return UIColor.clear return UIColor.clear
@ -347,6 +352,7 @@ extension PresentationThemeRootNavigationBar: Codable {
public convenience init(from decoder: Decoder) throws { public convenience init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self) let values = try decoder.container(keyedBy: CodingKeys.self)
self.init(buttonColor: try decodeColor(values, .button), self.init(buttonColor: try decodeColor(values, .button),
disabledButtonColor: try decodeColor(values, .disabledButton), disabledButtonColor: try decodeColor(values, .disabledButton),
primaryTextColor: try decodeColor(values, .primaryText), primaryTextColor: try decodeColor(values, .primaryText),
@ -358,10 +364,10 @@ extension PresentationThemeRootNavigationBar: Codable {
badgeBackgroundColor: try decodeColor(values, .badgeFill), badgeBackgroundColor: try decodeColor(values, .badgeFill),
badgeStrokeColor: try decodeColor(values, .badgeStroke), badgeStrokeColor: try decodeColor(values, .badgeStroke),
badgeTextColor: try decodeColor(values, .badgeText), badgeTextColor: try decodeColor(values, .badgeText),
segmentedBackgroundColor: try decodeColor(values, .segmentedBg), segmentedBackgroundColor: try decodeColor(values, .segmentedBg, decoder: decoder, fallbackKey: "root.searchBar.inputFill"),
segmentedForegroundColor: try decodeColor(values, .segmentedFg), segmentedForegroundColor: try decodeColor(values, .segmentedFg, decoder: decoder, fallbackKey: "root.navBar.background"),
segmentedTextColor: try decodeColor(values, .segmentedText), segmentedTextColor: try decodeColor(values, .segmentedText, decoder: decoder, fallbackKey: "root.navBar.primaryText"),
segmentedDividerColor: try decodeColor(values, .segmentedDivider)) segmentedDividerColor: try decodeColor(values, .segmentedDivider, decoder: decoder, fallbackKey: "root.list.freeInputField.stroke"))
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -603,6 +609,29 @@ extension PresentationThemeItemDisclosureActions: Codable {
} }
} }
extension PresentationThemeItemBarChart: Codable {
enum CodingKeys: String, CodingKey {
case color1
case color2
case color3
}
public convenience init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.init(color1: try decodeColor(values, .color1),
color2: try decodeColor(values, .color2),
color3: try decodeColor(values, .color3))
}
public func encode(to encoder: Encoder) throws {
var values = encoder.container(keyedBy: CodingKeys.self)
try encodeColor(&values, self.color1, .color1)
try encodeColor(&values, self.color2, .color2)
try encodeColor(&values, self.color3, .color3)
}
}
extension PresentationThemeFillStrokeForeground: Codable { extension PresentationThemeFillStrokeForeground: Codable {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case bg case bg
@ -683,6 +712,7 @@ extension PresentationThemeList: Codable {
case scrollIndicator case scrollIndicator
case pageIndicatorInactive case pageIndicatorInactive
case inputClearButton case inputClearButton
case itemBarChart
} }
public convenience init(from decoder: Decoder) throws { public convenience init(from decoder: Decoder) throws {
@ -714,7 +744,8 @@ extension PresentationThemeList: Codable {
mediaPlaceholderColor: try decodeColor(values, .mediaPlaceholder), mediaPlaceholderColor: try decodeColor(values, .mediaPlaceholder),
scrollIndicatorColor: try decodeColor(values, .scrollIndicator), scrollIndicatorColor: try decodeColor(values, .scrollIndicator),
pageIndicatorInactiveColor: try decodeColor(values, .pageIndicatorInactive), pageIndicatorInactiveColor: try decodeColor(values, .pageIndicatorInactive),
inputClearButtonColor: try decodeColor(values, .inputClearButton)) inputClearButtonColor: try decodeColor(values, .inputClearButton),
itemBarChart: try values.decode(PresentationThemeItemBarChart.self, forKey: .itemBarChart))
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -747,6 +778,7 @@ extension PresentationThemeList: Codable {
try encodeColor(&values, self.scrollIndicatorColor, .scrollIndicator) try encodeColor(&values, self.scrollIndicatorColor, .scrollIndicator)
try encodeColor(&values, self.pageIndicatorInactiveColor, .pageIndicatorInactive) try encodeColor(&values, self.pageIndicatorInactiveColor, .pageIndicatorInactive)
try encodeColor(&values, self.inputClearButtonColor, .inputClearButton) try encodeColor(&values, self.inputClearButtonColor, .inputClearButton)
try values.encode(self.itemBarChart, forKey: .itemBarChart)
} }
} }

View File

@ -113,6 +113,23 @@ fileprivate class PresentationThemeEncoding: Encoder {
return container return container
} }
private func dictionaryForNodes(_ nodes: [Node]) -> [String: Any] {
var dictionary: [String: Any] = [:]
for node in nodes {
var value: Any?
switch node.value {
case let .string(string):
value = string
case let .subnode(subnodes):
value = dictionaryForNodes(subnodes)
}
if let key = node.key {
dictionary[key] = value
}
}
return dictionary
}
func entry(for codingKey: [String]) -> Any? { func entry(for codingKey: [String]) -> Any? {
var currentNode: Node = self.data.rootNode var currentNode: Node = self.data.rootNode
for component in codingKey { for component in codingKey {
@ -123,8 +140,8 @@ fileprivate class PresentationThemeEncoding: Encoder {
if component == codingKey.last { if component == codingKey.last {
if case let .string(string) = node.value { if case let .string(string) = node.value {
return string return string
} else { } else if case let .subnode(nodes) = node.value {
return nil return dictionaryForNodes(nodes)
} }
} else { } else {
currentNode = node currentNode = node
@ -404,6 +421,7 @@ class PresentationThemeDecoding: Decoder {
var referenceTheme: PresentationTheme? var referenceTheme: PresentationTheme?
var serviceBackgroundColor: UIColor? var serviceBackgroundColor: UIColor?
var resolvedWallpaper: TelegramWallpaper? var resolvedWallpaper: TelegramWallpaper?
var fallbackKeys: [String: String] = [:]
private var _referenceCoding: PresentationThemeEncoding? private var _referenceCoding: PresentationThemeEncoding?
fileprivate var referenceCoding: PresentationThemeEncoding? { fileprivate var referenceCoding: PresentationThemeEncoding? {
@ -511,13 +529,42 @@ fileprivate struct PresentationThemeKeyedDecodingContainer<K : CodingKey>: Keyed
return entry is NSNull return entry is NSNull
} }
public func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { private func storageEntry(forKey key: [String]) -> Any? {
var containerEntry: Any? = self.container[key.stringValue] if let container = self.decoder.storage.containers.first as? [String: Any] {
if containerEntry == nil { func entry(container: [String: Any], forKey key: [String]) -> Any? {
containerEntry = self.decoder.referenceCoding?.entry(for: self.codingPath.map { $0.stringValue } + [key.stringValue]) if let keyComponent = key.first, let value = container[keyComponent] {
if key.count == 1 {
return value
} else if let subContainer = value as? [String: Any] {
return entry(container: subContainer, forKey: Array(key.suffix(from: 1)))
}
}
return nil
}
return entry(container: container, forKey: key)
} else {
return nil
}
} }
guard let entry = containerEntry else { private func containerEntry(forKey key: Key) -> Any? {
var containerEntry: Any? = self.container[key.stringValue]
if containerEntry == nil {
let initialKey = self.codingPath.map { $0.stringValue } + [key.stringValue]
let initialKeyString = initialKey.joined(separator: ".")
if let fallbackKeyString = self.decoder.fallbackKeys[initialKeyString] {
let fallbackKey = fallbackKeyString.components(separatedBy: ".")
containerEntry = self.storageEntry(forKey: fallbackKey)
}
if containerEntry == nil {
containerEntry = self.decoder.referenceCoding?.entry(for: initialKey)
}
}
return containerEntry
}
public func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool {
guard let entry = self.containerEntry(forKey: key) else {
throw PresentationThemeDecodingError.keyNotFound throw PresentationThemeDecodingError.keyNotFound
} }
@ -532,12 +579,7 @@ fileprivate struct PresentationThemeKeyedDecodingContainer<K : CodingKey>: Keyed
} }
public func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { public func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 {
var containerEntry: Any? = self.container[key.stringValue] guard let entry = self.containerEntry(forKey: key) else {
if containerEntry == nil {
containerEntry = self.decoder.referenceCoding?.entry(for: self.codingPath.map { $0.stringValue } + [key.stringValue])
}
guard let entry = containerEntry else {
throw PresentationThemeDecodingError.keyNotFound throw PresentationThemeDecodingError.keyNotFound
} }
@ -552,12 +594,7 @@ fileprivate struct PresentationThemeKeyedDecodingContainer<K : CodingKey>: Keyed
} }
public func decode(_ type: String.Type, forKey key: Key) throws -> String { public func decode(_ type: String.Type, forKey key: Key) throws -> String {
var containerEntry: Any? = self.container[key.stringValue] guard let entry = self.containerEntry(forKey: key) else {
if containerEntry == nil {
containerEntry = self.decoder.referenceCoding?.entry(for: self.codingPath.map { $0.stringValue } + [key.stringValue])
}
guard let entry = containerEntry else {
throw PresentationThemeDecodingError.keyNotFound throw PresentationThemeDecodingError.keyNotFound
} }
@ -572,12 +609,7 @@ fileprivate struct PresentationThemeKeyedDecodingContainer<K : CodingKey>: Keyed
} }
public func decode<T : Decodable>(_ type: T.Type, forKey key: Key) throws -> T { public func decode<T : Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
var containerEntry: Any? = self.container[key.stringValue] guard let entry = self.containerEntry(forKey: key) else {
if containerEntry == nil {
containerEntry = self.decoder.referenceCoding?.entry(for: self.codingPath.map { $0.stringValue } + [key.stringValue])
}
guard let entry = containerEntry else {
throw PresentationThemeDecodingError.keyNotFound throw PresentationThemeDecodingError.keyNotFound
} }

View File

@ -1,9 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"provides-namespace" : true
}
}

View File

@ -1,22 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "vol_full@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "vol_full@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 B

View File

@ -1,22 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "vol_half@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "vol_half@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

View File

@ -1,22 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "vol_off@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "vol_off@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

View File

@ -1702,7 +1702,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
}) })
}, displaySwipeToReplyHint: { [weak self] in }, displaySwipeToReplyHint: { [weak self] in
if let strongSelf = self { if let strongSelf = self, let validLayout = strongSelf.validLayout, min(validLayout.size.width, validLayout.size.height) > 320.0 {
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .swipeToReply(title: strongSelf.presentationData.strings.Conversation_SwipeToReplyHintTitle, text: strongSelf.presentationData.strings.Conversation_SwipeToReplyHintText), elevatedLayout: true, action: { _ in }), in: .window(.root)) strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .swipeToReply(title: strongSelf.presentationData.strings.Conversation_SwipeToReplyHintTitle, text: strongSelf.presentationData.strings.Conversation_SwipeToReplyHintText), elevatedLayout: true, action: { _ in }), in: .window(.root))
} }
}, requestMessageUpdate: { [weak self] id in }, requestMessageUpdate: { [weak self] id in
@ -5461,7 +5461,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if editMediaOptions != nil { if editMediaOptions != nil {
strongSelf.editMessageMediaWithLegacySignals(signals!) strongSelf.editMessageMediaWithLegacySignals(signals!)
} else { } else {
strongSelf.enqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime) strongSelf.enqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime > 0 ? scheduleTime : nil)
} }
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() //strongSelf.clearInputText()