mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-29 09:20:32 +00:00
Merge commit '4fe0d477157bf975f9478d7334d628ad9d9930a8'
This commit is contained in:
@@ -14,6 +14,7 @@ import PresentationDataUtils
|
||||
import LegacyMediaPickerUI
|
||||
import WallpaperResources
|
||||
import AccountContext
|
||||
import MediaResources
|
||||
|
||||
private final class EditThemeControllerArguments {
|
||||
let context: AccountContext
|
||||
@@ -503,11 +504,40 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
resolvedWallpaper = nil
|
||||
}
|
||||
|
||||
|
||||
let prepare: Signal<CreateThemeResult, CreateThemeError>
|
||||
if let resolvedWallpaper = resolvedWallpaper, case let .file(file) = resolvedWallpaper, resolvedWallpaper.isPattern {
|
||||
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)
|
||||
prepare = (context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|
||||
|> filter({ $0.complete })
|
||||
|> take(1)
|
||||
|> castError(CreateThemeError.self)
|
||||
|> mapToSignal { _ -> Signal<CreateThemeResult, CreateThemeError> in
|
||||
return .complete()
|
||||
})
|
||||
} else {
|
||||
prepare = .complete()
|
||||
}
|
||||
} else {
|
||||
prepare = .complete()
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case .create:
|
||||
if let themeResource = themeResource {
|
||||
let _ = (createTheme(account: context.account, title: state.title, resource: themeResource, thumbnailData: themeThumbnailData, settings: settings)
|
||||
|> deliverOnMainQueue).start(next: { next in
|
||||
let _ = (prepare |> then(createTheme(account: context.account, title: state.title, resource: themeResource, thumbnailData: themeThumbnailData, settings: settings)
|
||||
|> deliverOnMainQueue)).start(next: { next in
|
||||
if case let .result(resultTheme) = next {
|
||||
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start()
|
||||
let _ = (updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
@@ -540,8 +570,8 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
})
|
||||
}
|
||||
case let .edit(info):
|
||||
let _ = (updateTheme(account: context.account, accountManager: context.sharedContext.accountManager, theme: info.theme, title: state.title, slug: state.slug, resource: themeResource, settings: settings)
|
||||
|> deliverOnMainQueue).start(next: { next in
|
||||
let _ = (prepare |> then(updateTheme(account: context.account, accountManager: context.sharedContext.accountManager, theme: info.theme, title: state.title, slug: state.slug, resource: themeResource, settings: settings)
|
||||
|> deliverOnMainQueue)).start(next: { next in
|
||||
if case let .result(resultTheme) = next {
|
||||
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start()
|
||||
let _ = (updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
|
||||
@@ -41,6 +41,8 @@ public final class ThemePreviewController: ViewController {
|
||||
return self._ready
|
||||
}
|
||||
|
||||
private var validLayout: ContainerViewLayout?
|
||||
|
||||
private var didPlayPresentationAnimation = false
|
||||
|
||||
private var presentationData: PresentationData
|
||||
@@ -399,11 +401,11 @@ public final class ThemePreviewController: ViewController {
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] previousDefaultTheme in
|
||||
if let strongSelf = self {
|
||||
if let strongSelf = self, let layout = strongSelf.validLayout, layout.size.width >= 375.0 {
|
||||
Queue.mainQueue().after(0.3) {
|
||||
let navigationController = strongSelf.navigationController as? NavigationController
|
||||
if let (previousDefaultTheme, autoNightMode) = previousDefaultTheme {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .actionSucceeded(title: strongSelf.presentationData.strings.Theme_ThemeChanged, text: strongSelf.presentationData.strings.Theme_ThemeChangedText, cancel: strongSelf.presentationData.strings.Undo_Undo), elevatedLayout: false, animateInAsReplacement: false, action: { value in
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .actionSucceeded(title: strongSelf.presentationData.strings.Theme_ThemeChanged, text: strongSelf.presentationData.strings.Theme_ThemeChangedText, cancel: strongSelf.presentationData.strings.Undo_Undo), elevatedLayout: true, animateInAsReplacement: false, action: { value in
|
||||
if value == .undo {
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current -> PresentationThemeSettings in
|
||||
var updated: PresentationThemeSettings
|
||||
@@ -435,6 +437,8 @@ public final class ThemePreviewController: ViewController {
|
||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
|
||||
self.validLayout = layout
|
||||
|
||||
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
|
||||
let wallpaper: TelegramWallpaper?
|
||||
|
||||
var stableId: Int64 {
|
||||
return self.themeReference.index
|
||||
return self.themeReference.generalThemeReference.index
|
||||
}
|
||||
|
||||
static func ==(lhs: ThemeSettingsThemeEntry, rhs: ThemeSettingsThemeEntry) -> Bool {
|
||||
|
||||
@@ -31,8 +31,10 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
private let cancelButton = HighlightableButtonNode()
|
||||
private let doneButton = HighlightableButtonNode()
|
||||
private let cancelButton = HighlightTrackingButtonNode()
|
||||
private let cancelHighlightBackgroundNode = ASDisplayNode()
|
||||
private let doneButton = HighlightTrackingButtonNode()
|
||||
private let doneHighlightBackgroundNode = ASDisplayNode()
|
||||
private let separatorNode = ASDisplayNode()
|
||||
private let topSeparatorNode = ASDisplayNode()
|
||||
|
||||
@@ -47,7 +49,9 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.cancelHighlightBackgroundNode)
|
||||
self.addSubnode(self.cancelButton)
|
||||
self.addSubnode(self.doneHighlightBackgroundNode)
|
||||
self.addSubnode(self.doneButton)
|
||||
self.addSubnode(self.separatorNode)
|
||||
self.addSubnode(self.topSeparatorNode)
|
||||
@@ -57,11 +61,11 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
self.cancelButton.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
strongSelf.cancelButton.backgroundColor = strongSelf.theme.list.itemHighlightedBackgroundColor
|
||||
strongSelf.cancelHighlightBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.cancelHighlightBackgroundNode.alpha = 1.0
|
||||
} else {
|
||||
UIView.animate(withDuration: 0.3, animations: {
|
||||
strongSelf.cancelButton.backgroundColor = .clear
|
||||
})
|
||||
strongSelf.cancelHighlightBackgroundNode.alpha = 0.0
|
||||
strongSelf.cancelHighlightBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,11 +73,11 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
self.doneButton.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
strongSelf.doneButton.backgroundColor = strongSelf.theme.list.itemHighlightedBackgroundColor
|
||||
strongSelf.doneHighlightBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneHighlightBackgroundNode.alpha = 1.0
|
||||
} else {
|
||||
UIView.animate(withDuration: 0.3, animations: {
|
||||
strongSelf.doneButton.backgroundColor = .clear
|
||||
})
|
||||
strongSelf.doneHighlightBackgroundNode.alpha = 0.0
|
||||
strongSelf.doneHighlightBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +96,8 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
self.backgroundColor = theme.rootController.tabBar.backgroundColor
|
||||
self.separatorNode.backgroundColor = theme.rootController.tabBar.separatorColor
|
||||
self.topSeparatorNode.backgroundColor = theme.rootController.tabBar.separatorColor
|
||||
self.cancelHighlightBackgroundNode.backgroundColor = theme.list.itemHighlightedBackgroundColor
|
||||
self.doneHighlightBackgroundNode.backgroundColor = theme.list.itemHighlightedBackgroundColor
|
||||
|
||||
let cancelTitle: String
|
||||
switch self.cancelButtonType {
|
||||
@@ -118,7 +124,9 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
|
||||
func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
self.cancelButton.frame = CGRect(origin: CGPoint(), size: CGSize(width: floor(size.width / 2.0), height: size.height))
|
||||
self.cancelHighlightBackgroundNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: floor(size.width / 2.0), height: size.height))
|
||||
self.doneButton.frame = CGRect(origin: CGPoint(x: floor(size.width / 2.0), y: 0.0), size: CGSize(width: size.width - floor(size.width / 2.0), height: size.height))
|
||||
self.doneHighlightBackgroundNode.frame = CGRect(origin: CGPoint(x: floor(size.width / 2.0), y: 0.0), size: CGSize(width: size.width - floor(size.width / 2.0), height: size.height))
|
||||
self.separatorNode.frame = CGRect(origin: CGPoint(x: floor(size.width / 2.0), y: 0.0), size: CGSize(width: UIScreenPixel, height: size.height + layout.intrinsicInsets.bottom))
|
||||
self.topSeparatorNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: UIScreenPixel))
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
}
|
||||
|
||||
public let baseTheme: TelegramBaseTheme
|
||||
public let accentColor: Int32
|
||||
public let messageColors: (top: Int32, bottom: Int32)?
|
||||
public let accentColor: UInt32
|
||||
public let messageColors: (top: UInt32, bottom: UInt32)?
|
||||
public let wallpaper: TelegramWallpaper?
|
||||
|
||||
public init(baseTheme: TelegramBaseTheme, accentColor: Int32, messageColors: (top: Int32, bottom: Int32)?, wallpaper: TelegramWallpaper?) {
|
||||
public init(baseTheme: TelegramBaseTheme, accentColor: UInt32, messageColors: (top: UInt32, bottom: UInt32)?, wallpaper: TelegramWallpaper?) {
|
||||
self.baseTheme = baseTheme
|
||||
self.accentColor = accentColor
|
||||
self.messageColors = messageColors
|
||||
@@ -38,9 +38,9 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.baseTheme = TelegramBaseTheme(rawValue: decoder.decodeInt32ForKey("baseTheme", orElse: 0)) ?? .classic
|
||||
self.accentColor = decoder.decodeInt32ForKey("accent", orElse: 0)
|
||||
self.accentColor = UInt32(bitPattern: decoder.decodeInt32ForKey("accent", orElse: 0))
|
||||
if let topMessageColor = decoder.decodeOptionalInt32ForKey("topMessage"), let bottomMessageColor = decoder.decodeOptionalInt32ForKey("bottomMessage") {
|
||||
self.messageColors = (topMessageColor, bottomMessageColor)
|
||||
self.messageColors = (UInt32(bitPattern: topMessageColor), UInt32(bitPattern: bottomMessageColor))
|
||||
} else {
|
||||
self.messageColors = nil
|
||||
}
|
||||
@@ -49,10 +49,10 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.baseTheme.rawValue, forKey: "baseTheme")
|
||||
encoder.encodeInt32(self.accentColor, forKey: "accent")
|
||||
encoder.encodeInt32(Int32(bitPattern: self.accentColor), forKey: "accent")
|
||||
if let (topMessageColor, bottomMessageColor) = self.messageColors {
|
||||
encoder.encodeInt32(topMessageColor, forKey: "topMessage")
|
||||
encoder.encodeInt32(bottomMessageColor, forKey: "bottomMessage")
|
||||
encoder.encodeInt32(Int32(bitPattern: topMessageColor), forKey: "topMessage")
|
||||
encoder.encodeInt32(Int32(bitPattern: bottomMessageColor), forKey: "bottomMessage")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "topMessage")
|
||||
encoder.encodeNil(forKey: "bottomMessage")
|
||||
|
||||
@@ -48,11 +48,11 @@ extension TelegramThemeSettings {
|
||||
convenience init?(apiThemeSettings: Api.ThemeSettings) {
|
||||
switch apiThemeSettings {
|
||||
case let .themeSettings(flags, baseTheme, accentColor, messageTopColor, messageBottomColor, wallpaper):
|
||||
var messageColors: (Int32, Int32)?
|
||||
var messageColors: (UInt32, UInt32)?
|
||||
if let messageTopColor = messageTopColor, let messageBottomColor = messageBottomColor {
|
||||
messageColors = (messageTopColor, messageBottomColor)
|
||||
messageColors = (UInt32(bitPattern: messageTopColor), UInt32(bitPattern: messageBottomColor))
|
||||
}
|
||||
self.init(baseTheme: TelegramBaseTheme(apiBaseTheme: baseTheme) ?? .classic, accentColor: accentColor, messageColors: messageColors, wallpaper: wallpaper.flatMap(TelegramWallpaper.init(apiWallpaper:)))
|
||||
self.init(baseTheme: TelegramBaseTheme(apiBaseTheme: baseTheme) ?? .classic, accentColor: UInt32(bitPattern: accentColor), messageColors: messageColors, wallpaper: wallpaper.flatMap(TelegramWallpaper.init(apiWallpaper:)))
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@@ -72,6 +72,15 @@ extension TelegramThemeSettings {
|
||||
flags |= 1 << 1
|
||||
}
|
||||
|
||||
return .inputThemeSettings(flags: flags, baseTheme: self.baseTheme.apiBaseTheme, accentColor: self.accentColor, messageTopColor: self.messageColors?.0, messageBottomColor: self.messageColors?.1, wallpaper: inputWallpaper, wallpaperSettings: inputWallpaperSettings)
|
||||
var messageTopColor: Int32?
|
||||
var messageBottomColor: Int32?
|
||||
if let color = self.messageColors?.0 {
|
||||
messageTopColor = Int32(bitPattern: color)
|
||||
}
|
||||
if let color = self.messageColors?.1 {
|
||||
messageBottomColor = Int32(bitPattern: color)
|
||||
}
|
||||
|
||||
return .inputThemeSettings(flags: flags, baseTheme: self.baseTheme.apiBaseTheme, accentColor: Int32(bitPattern: self.accentColor), messageTopColor: messageTopColor, messageBottomColor: messageBottomColor, wallpaper: inputWallpaper, wallpaperSettings: inputWallpaperSettings)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ extension TelegramWallpaper: Codable {
|
||||
default:
|
||||
let optionKeys = ["motion", "blur"]
|
||||
|
||||
if value.count == 6, let color = UIColor(hexString: value) {
|
||||
if [6, 8].contains(value.count), let color = UIColor(hexString: value) {
|
||||
self = .color(color.argb)
|
||||
} else {
|
||||
let components = value.components(separatedBy: " ")
|
||||
@@ -80,7 +80,7 @@ extension TelegramWallpaper: Codable {
|
||||
if optionKeys.contains(component) {
|
||||
continue
|
||||
}
|
||||
if component.count == 6, let value = UIColor(hexString: component) {
|
||||
if [6, 8].contains(component.count), let value = UIColor(hexString: component) {
|
||||
if color == nil {
|
||||
color = value.argb
|
||||
} else if bottomColor == nil {
|
||||
|
||||
@@ -1766,7 +1766,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.selectionScrollDisplayLink = ConstantDisplayLinkAnimator(update: { [weak self] in
|
||||
self?.selectionScrollActivationTimer = nil
|
||||
if let strongSelf = self, let delta = strongSelf.selectionScrollDelta {
|
||||
let distance: CGFloat = 10.0 * min(1.0, 0.15 + abs(delta * delta))
|
||||
let distance: CGFloat = 15.0 * min(1.0, 0.15 + abs(delta * delta))
|
||||
let direction: ListViewScrollDirection = delta > 0.0 ? .up : .down
|
||||
strongSelf.scrollWithDirection(direction, distance: distance)
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.textNode.attributedText = attributedText
|
||||
displayUndo = true
|
||||
undoText = cancel
|
||||
self.originalRemainingSeconds = 3
|
||||
self.originalRemainingSeconds = 5
|
||||
case let .emoji(path, text):
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
@@ -535,7 +535,12 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.checkTimer()
|
||||
}
|
||||
|
||||
var dismissed = false
|
||||
func animateOut(completion: @escaping () -> Void) {
|
||||
guard !self.dismissed else {
|
||||
return
|
||||
}
|
||||
self.dismissed = true
|
||||
self.panelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { _ in })
|
||||
self.panelWrapperNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false) { _ in
|
||||
completion()
|
||||
|
||||
@@ -527,7 +527,7 @@ public func patternColor(for color: UIColor, intensity: CGFloat, prominent: Bool
|
||||
} else {
|
||||
brightness = max(0.0, min(1.0, 1.0 - brightness * 0.65))
|
||||
}
|
||||
let alpha = (prominent ? 0.5 : 0.4) * intensity
|
||||
let alpha = (prominent ? 0.6 : 0.55) * intensity
|
||||
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
|
||||
}
|
||||
return .black
|
||||
|
||||
Reference in New Issue
Block a user