mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Cloud themes improvements
This commit is contained in:
parent
4ac24e4369
commit
f3db3a29b0
@ -8,6 +8,11 @@
|
|||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>${APP_NAME}</string>
|
<string>${APP_NAME}</string>
|
||||||
|
<key>CFBundleDocumentTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict/>
|
||||||
|
<dict/>
|
||||||
|
</array>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIcons</key>
|
<key>CFBundleIcons</key>
|
||||||
@ -332,5 +337,29 @@
|
|||||||
<false/>
|
<false/>
|
||||||
<key>UIViewGroupOpacity</key>
|
<key>UIViewGroupOpacity</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>UTImportedTypeDeclarations</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Telegram iOS Color Theme File</string>
|
||||||
|
<key>UTTypeIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>BlueIcon@3x.png</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>org.telegram.Telegram-iOS.theme</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>tgios-theme</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -33,7 +33,5 @@
|
|||||||
<string>merchant.privatbank.test.telergramios</string>
|
<string>merchant.privatbank.test.telergramios</string>
|
||||||
<string>merchant.privatbank.prod.telergram</string>
|
<string>merchant.privatbank.prod.telergram</string>
|
||||||
</array>
|
</array>
|
||||||
<key>com.apple.developer.carplay-messaging</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -4660,19 +4660,27 @@ Any member of this group will be able to see messages in the channel.";
|
|||||||
|
|
||||||
"Appearance.CreateTheme" = "Create New Theme";
|
"Appearance.CreateTheme" = "Create New Theme";
|
||||||
"Appearance.EditTheme" = "Edit Theme";
|
"Appearance.EditTheme" = "Edit Theme";
|
||||||
|
"Appearance.ShareTheme" = "Share";
|
||||||
"Appearance.RemoveTheme" = "Remove";
|
"Appearance.RemoveTheme" = "Remove";
|
||||||
"Appearance.CreateThemeInfo" = "A new theme template has been created from your current theme and added to your Saved Messages.";
|
"Appearance.RemoveThemeConfirmation" = "Remove Theme";
|
||||||
|
|
||||||
"Conversation.Theme" = "Color Theme";
|
"Conversation.Theme" = "Color Theme";
|
||||||
"Conversation.ViewTheme" = "VIEW THEME";
|
"Conversation.ViewTheme" = "VIEW THEME";
|
||||||
|
|
||||||
"Message.Theme" = "Color Theme";
|
"Message.Theme" = "Color Theme";
|
||||||
|
|
||||||
"EditTheme.Title" = "Edit Theme";
|
"EditTheme.CreateTitle" = "Create Theme";
|
||||||
"EditTheme.Preview" = "PREVIEW";
|
"EditTheme.EditTitle" = "Edit Theme";
|
||||||
"EditTheme.Title" = "Title";
|
"EditTheme.Title" = "Theme Name";
|
||||||
"EditTheme.ShortLink" = "Short Link";
|
"EditTheme.ShortLink" = "link";
|
||||||
"EditTheme.ShortLinkInfo" = "Short Link";
|
"EditTheme.ShortLinkInfo" = "Short Link Info";
|
||||||
|
"EditTheme.Preview" = "CHAT PREVIEW";
|
||||||
|
"EditTheme.UploadNewTheme" = "Select a File...";
|
||||||
|
"EditTheme.UploadEditedTheme" = "Select Updated File...";
|
||||||
|
"EditTheme.UploadNewInfo" = "This theme will be based on your current theme and wallpaper. Otherwise, you can use a custom theme file if you already have one.";
|
||||||
|
"EditTheme.UploadEditedInfo" = "You can select a new file to update the theme. It will be updated for all users.";
|
||||||
|
"EditTheme.ThemeTemplateAlert" = "A copy of your theme template has been added to your Saved Messages.";
|
||||||
|
"EditTheme.FileReadError" = "Invalid theme file";
|
||||||
|
|
||||||
"Wallpaper.ErrorNotFound" = "Sorry, this chat background doesn't seem to exist.";
|
"Wallpaper.ErrorNotFound" = "Sorry, this chat background doesn't seem to exist.";
|
||||||
"Theme.ErrorNotFound" = "Sorry, this color theme doesn't seem to exist.";
|
"Theme.ErrorNotFound" = "Sorry, this color theme doesn't seem to exist.";
|
||||||
|
@ -152,7 +152,7 @@ private final class BotCheckoutPasswordAlertContentNode: AlertContentNode {
|
|||||||
self.textFieldNode.textField.textColor = theme.actionSheet.primaryTextColor
|
self.textFieldNode.textField.textColor = theme.actionSheet.primaryTextColor
|
||||||
self.textFieldNode.textField.font = Font.regular(12.0)
|
self.textFieldNode.textField.font = Font.regular(12.0)
|
||||||
self.textFieldNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(12.0)]
|
self.textFieldNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(12.0)]
|
||||||
self.textFieldNode.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textFieldNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textFieldNode.textField.isSecureTextEntry = true
|
self.textFieldNode.textField.isSecureTextEntry = true
|
||||||
self.textFieldNode.textField.tintColor = theme.list.itemAccentColor
|
self.textFieldNode.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ final class BotPaymentCardInputItemNode: BotPaymentItemNode, STPPaymentCardTextF
|
|||||||
self.cardField.textColor = theme.list.itemPrimaryTextColor
|
self.cardField.textColor = theme.list.itemPrimaryTextColor
|
||||||
self.cardField.textErrorColor = theme.list.itemDestructiveColor
|
self.cardField.textErrorColor = theme.list.itemDestructiveColor
|
||||||
self.cardField.placeholderColor = theme.list.itemPlaceholderTextColor
|
self.cardField.placeholderColor = theme.list.itemPlaceholderTextColor
|
||||||
self.cardField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.cardField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cardField.frame = CGRect(origin: CGPoint(x: 5.0, y: 0.0), size: CGSize(width: width - 10.0, height: 44.0))
|
self.cardField.frame = CGRect(origin: CGPoint(x: 5.0, y: 0.0), size: CGSize(width: width - 10.0, height: 44.0))
|
||||||
|
@ -79,7 +79,7 @@ final class BotPaymentFieldItemNode: BotPaymentItemNode, UITextFieldDelegate {
|
|||||||
self.titleNode.attributedText = NSAttributedString(string: self.title, font: titleFont, textColor: theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.title, font: titleFont, textColor: theme.list.itemPrimaryTextColor)
|
||||||
self.textField.textField.textColor = theme.list.itemPrimaryTextColor
|
self.textField.textField.textColor = theme.list.itemPrimaryTextColor
|
||||||
self.textField.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: titleFont, textColor: theme.list.itemPlaceholderTextColor)
|
self.textField.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: titleFont, textColor: theme.list.itemPlaceholderTextColor)
|
||||||
self.textField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textField.textField.tintColor = theme.list.itemAccentColor
|
self.textField.textField.tintColor = theme.list.itemAccentColor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ final class BotPaymentFieldItemNode: BotPaymentItemNode, UITextFieldDelegate {
|
|||||||
if self.theme !== theme {
|
if self.theme !== theme {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.title, font: titleFont, textColor: theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.title, font: titleFont, textColor: theme.list.itemPrimaryTextColor)
|
||||||
self.textField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textField.textField.tintColor = theme.list.itemAccentColor
|
self.textField.textField.tintColor = theme.list.itemAccentColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ class CreatePollOptionItemNode: ItemListRevealOptionsItemNode, ItemListItemNode,
|
|||||||
strongSelf.textNode.attributedPlaceholderText = attributedPlaceholderText
|
strongSelf.textNode.attributedPlaceholderText = attributedPlaceholderText
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.textNode.keyboardAppearance = item.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
strongSelf.textNode.keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
|
|
||||||
strongSelf.textClippingNode.frame = CGRect(origin: CGPoint(x: revealOffset + leftInset, y: textTopInset), size: CGSize(width: params.width - leftInset - params.rightInset, height: textLayout.size.height))
|
strongSelf.textClippingNode.frame = CGRect(origin: CGPoint(x: revealOffset + leftInset, y: textTopInset), size: CGSize(width: params.width - leftInset - params.rightInset, height: textLayout.size.height))
|
||||||
strongSelf.textNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: params.width - leftInset - rightInset, height: textLayout.size.height + 1.0))
|
strongSelf.textNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: params.width - leftInset - rightInset, height: textLayout.size.height + 1.0))
|
||||||
|
@ -93,7 +93,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
self.effectView = UIVisualEffectView()
|
self.effectView = UIVisualEffectView()
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
} else {
|
} else {
|
||||||
if theme.chatList.searchBarKeyboardColor == .dark {
|
if theme.rootController.keyboardColor == .dark {
|
||||||
self.effectView.effect = UIBlurEffect(style: .dark)
|
self.effectView.effect = UIBlurEffect(style: .dark)
|
||||||
} else {
|
} else {
|
||||||
self.effectView.effect = UIBlurEffect(style: .light)
|
self.effectView.effect = UIBlurEffect(style: .light)
|
||||||
|
@ -17,8 +17,8 @@ import OpenInExternalAppUI
|
|||||||
private let deleteImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: .white)
|
private let deleteImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: .white)
|
||||||
private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionAction"), color: .white)
|
private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionAction"), color: .white)
|
||||||
|
|
||||||
private let backwardImage = UIImage(bundleImageName: "Media Gallery/BackwardButton")
|
private let backwardImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/BackwardButton"), color: .white)
|
||||||
private let forwardImage = UIImage(bundleImageName: "Media Gallery/ForwardButton")
|
private let forwardImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/ForwardButton"), color: .white)
|
||||||
private let pauseImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/PauseButton"), color: .white)
|
private let pauseImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/PauseButton"), color: .white)
|
||||||
private let playImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/PlayButton"), color: .white)
|
private let playImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/PlayButton"), color: .white)
|
||||||
|
|
||||||
@ -600,8 +600,13 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
|||||||
self.actionButton.frame = CGRect(origin: CGPoint(x: leftInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
self.actionButton.frame = CGRect(origin: CGPoint(x: leftInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
||||||
self.deleteButton.frame = CGRect(origin: CGPoint(x: width - 44.0 - rightInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
self.deleteButton.frame = CGRect(origin: CGPoint(x: width - 44.0 - rightInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
||||||
|
|
||||||
self.backwardButton.frame = CGRect(origin: CGPoint(x: floor((width - 44.0) / 2.0) - 66.0, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
if let image = self.backwardButton.image(for: .normal) {
|
||||||
self.forwardButton.frame = CGRect(origin: CGPoint(x: floor((width - 44.0) / 2.0) + 66.0, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
self.backwardButton.frame = CGRect(origin: CGPoint(x: floor((width - image.size.width) / 2.0) - 66.0, y: panelHeight - bottomInset - 44.0 + 7.0), size: image.size)
|
||||||
|
|
||||||
|
}
|
||||||
|
if let image = self.forwardButton.image(for: .normal) {
|
||||||
|
self.forwardButton.frame = CGRect(origin: CGPoint(x: floor((width - image.size.width) / 2.0) + 66.0, y: panelHeight - bottomInset - 44.0 + 7.0), size: image.size)
|
||||||
|
}
|
||||||
|
|
||||||
self.playbackControlButton.frame = CGRect(origin: CGPoint(x: floor((width - 44.0) / 2.0), y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
self.playbackControlButton.frame = CGRect(origin: CGPoint(x: floor((width - 44.0) / 2.0), y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
seekable = value.duration >= 45.0
|
seekable = value.duration >= 30.0
|
||||||
}
|
}
|
||||||
|
|
||||||
var fetching = false
|
var fetching = false
|
||||||
|
@ -672,7 +672,7 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo
|
|||||||
if strongSelf.inputSeparator == nil {
|
if strongSelf.inputSeparator == nil {
|
||||||
animateIn = true
|
animateIn = true
|
||||||
}
|
}
|
||||||
let keyboardAppearance = item.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
let keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
switch editingName {
|
switch editingName {
|
||||||
case let .personName(firstName, lastName):
|
case let .personName(firstName, lastName):
|
||||||
if strongSelf.inputSeparator == nil {
|
if strongSelf.inputSeparator == nil {
|
||||||
|
@ -251,7 +251,7 @@ public class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNod
|
|||||||
strongSelf.textNode.attributedPlaceholderText = attributedPlaceholderText
|
strongSelf.textNode.attributedPlaceholderText = attributedPlaceholderText
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.textNode.keyboardAppearance = item.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
strongSelf.textNode.keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
|
|
||||||
strongSelf.textClippingNode.frame = CGRect(origin: CGPoint(x: leftInset, y: textTopInset), size: CGSize(width: params.width - leftInset - params.rightInset, height: textLayout.size.height))
|
strongSelf.textClippingNode.frame = CGRect(origin: CGPoint(x: leftInset, y: textTopInset), size: CGSize(width: params.width - leftInset - params.rightInset, height: textLayout.size.height))
|
||||||
strongSelf.textNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: params.width - leftInset - 16.0 - rightInset, height: textLayout.size.height + 1.0))
|
strongSelf.textNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: params.width - leftInset - 16.0 - rightInset, height: textLayout.size.height + 1.0))
|
||||||
|
@ -13,6 +13,21 @@ public enum ItemListSingleLineInputItemType: Equatable {
|
|||||||
case username
|
case username
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ItemListSingleLineInputClearType: Equatable {
|
||||||
|
case none
|
||||||
|
case always
|
||||||
|
case onFocus
|
||||||
|
|
||||||
|
var hasButton: Bool {
|
||||||
|
switch self {
|
||||||
|
case .none:
|
||||||
|
return false
|
||||||
|
case .always, .onFocus:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
|
public class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
@ -22,7 +37,7 @@ public class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
|
|||||||
let type: ItemListSingleLineInputItemType
|
let type: ItemListSingleLineInputItemType
|
||||||
let returnKeyType: UIReturnKeyType
|
let returnKeyType: UIReturnKeyType
|
||||||
let spacing: CGFloat
|
let spacing: CGFloat
|
||||||
let clearButton: Bool
|
let clearType: ItemListSingleLineInputClearType
|
||||||
let enabled: Bool
|
let enabled: Bool
|
||||||
public let sectionId: ItemListSectionId
|
public let sectionId: ItemListSectionId
|
||||||
let action: () -> Void
|
let action: () -> Void
|
||||||
@ -32,7 +47,7 @@ public class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
|
|||||||
let updatedFocus: ((Bool) -> Void)?
|
let updatedFocus: ((Bool) -> Void)?
|
||||||
public let tag: ItemListItemTag?
|
public let tag: ItemListItemTag?
|
||||||
|
|
||||||
public init(theme: PresentationTheme, strings: PresentationStrings, title: NSAttributedString, text: String, placeholder: String, type: ItemListSingleLineInputItemType = .regular(capitalization: true, autocorrection: true), returnKeyType: UIReturnKeyType = .`default`, spacing: CGFloat = 0.0, clearButton: Bool = false, enabled: Bool = true, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId, textUpdated: @escaping (String) -> Void, shouldUpdateText: @escaping (String) -> Bool = { _ in return true }, processPaste: ((String) -> String)? = nil, updatedFocus: ((Bool) -> Void)? = nil, action: @escaping () -> Void) {
|
public init(theme: PresentationTheme, strings: PresentationStrings, title: NSAttributedString, text: String, placeholder: String, type: ItemListSingleLineInputItemType = .regular(capitalization: true, autocorrection: true), returnKeyType: UIReturnKeyType = .`default`, spacing: CGFloat = 0.0, clearType: ItemListSingleLineInputClearType = .none, enabled: Bool = true, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId, textUpdated: @escaping (String) -> Void, shouldUpdateText: @escaping (String) -> Bool = { _ in return true }, processPaste: ((String) -> String)? = nil, updatedFocus: ((Bool) -> Void)? = nil, action: @escaping () -> Void) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.title = title
|
self.title = title
|
||||||
@ -41,7 +56,7 @@ public class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
|
|||||||
self.type = type
|
self.type = type
|
||||||
self.returnKeyType = returnKeyType
|
self.returnKeyType = returnKeyType
|
||||||
self.spacing = spacing
|
self.spacing = spacing
|
||||||
self.clearButton = clearButton
|
self.clearType = clearType
|
||||||
self.enabled = enabled
|
self.enabled = enabled
|
||||||
self.tag = tag
|
self.tag = tag
|
||||||
self.sectionId = sectionId
|
self.sectionId = sectionId
|
||||||
@ -153,7 +168,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg
|
|||||||
self.textNode.textField.font = Font.regular(17.0)
|
self.textNode.textField.font = Font.regular(17.0)
|
||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
self.textNode.textField.textColor = item.theme.list.itemPrimaryTextColor
|
self.textNode.textField.textColor = item.theme.list.itemPrimaryTextColor
|
||||||
self.textNode.textField.keyboardAppearance = item.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textNode.textField.keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textNode.textField.tintColor = item.theme.list.itemAccentColor
|
self.textNode.textField.tintColor = item.theme.list.itemAccentColor
|
||||||
self.textNode.textField.accessibilityHint = item.placeholder
|
self.textNode.textField.accessibilityHint = item.placeholder
|
||||||
}
|
}
|
||||||
@ -180,7 +195,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg
|
|||||||
let leftInset: CGFloat = 16.0 + params.leftInset
|
let leftInset: CGFloat = 16.0 + params.leftInset
|
||||||
var rightInset: CGFloat = 16.0 + params.rightInset
|
var rightInset: CGFloat = 16.0 + params.rightInset
|
||||||
|
|
||||||
if item.clearButton {
|
if item.clearType.hasButton {
|
||||||
rightInset += 32.0
|
rightInset += 32.0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +225,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg
|
|||||||
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||||
|
|
||||||
strongSelf.textNode.textField.textColor = item.theme.list.itemPrimaryTextColor
|
strongSelf.textNode.textField.textColor = item.theme.list.itemPrimaryTextColor
|
||||||
strongSelf.textNode.textField.keyboardAppearance = item.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
strongSelf.textNode.textField.keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
strongSelf.textNode.textField.tintColor = item.theme.list.itemAccentColor
|
strongSelf.textNode.textField.tintColor = item.theme.list.itemAccentColor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,9 +305,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg
|
|||||||
strongSelf.clearIconNode.frame = CGRect(origin: CGPoint(x: params.width - params.rightInset - buttonSize.width + floor((buttonSize.width - image.size.width) / 2.0), y: floor((layout.contentSize.height - image.size.height) / 2.0)), size: image.size)
|
strongSelf.clearIconNode.frame = CGRect(origin: CGPoint(x: params.width - params.rightInset - buttonSize.width + floor((buttonSize.width - image.size.width) / 2.0), y: floor((layout.contentSize.height - image.size.height) / 2.0)), size: image.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.clearIconNode.isHidden = !item.clearButton || item.text.isEmpty
|
strongSelf.updateClearButtonVisibility()
|
||||||
strongSelf.clearButtonNode.isHidden = !item.clearButton || item.text.isEmpty
|
|
||||||
strongSelf.clearButtonNode.isAccessibilityElement = !strongSelf.clearButtonNode.isHidden
|
|
||||||
|
|
||||||
if strongSelf.backgroundNode.supernode == nil {
|
if strongSelf.backgroundNode.supernode == nil {
|
||||||
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
|
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
|
||||||
@ -334,6 +347,24 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateClearButtonVisibility() {
|
||||||
|
guard let item = self.item else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let isHidden: Bool
|
||||||
|
switch item.clearType {
|
||||||
|
case .none:
|
||||||
|
isHidden = true
|
||||||
|
case .always:
|
||||||
|
isHidden = item.text.isEmpty
|
||||||
|
case .onFocus:
|
||||||
|
isHidden = !self.textNode.textField.isFirstResponder || item.text.isEmpty
|
||||||
|
}
|
||||||
|
self.clearIconNode.isHidden = isHidden
|
||||||
|
self.clearButtonNode.isHidden = isHidden
|
||||||
|
self.clearButtonNode.isAccessibilityElement = isHidden
|
||||||
|
}
|
||||||
|
|
||||||
override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||||
}
|
}
|
||||||
@ -392,10 +423,12 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg
|
|||||||
|
|
||||||
@objc public func textFieldDidBeginEditing(_ textField: UITextField) {
|
@objc public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||||
self.item?.updatedFocus?(true)
|
self.item?.updatedFocus?(true)
|
||||||
|
self.updateClearButtonVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func textFieldDidEndEditing(_ textField: UITextField) {
|
@objc public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||||
self.item?.updatedFocus?(false)
|
self.item?.updatedFocus?(false)
|
||||||
|
self.updateClearButtonVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animateError() {
|
public func animateError() {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
096C16E62317412A0047887D /* LegacyICloudFilePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 096C16E5231741290047887D /* LegacyICloudFilePicker.swift */; };
|
||||||
D03E3F6E2304C4840049C28B /* LegacyMediaPickerUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D03E3F6C2304C4840049C28B /* LegacyMediaPickerUI.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D03E3F6E2304C4840049C28B /* LegacyMediaPickerUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D03E3F6C2304C4840049C28B /* LegacyMediaPickerUI.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
D03E3F802304C50E0049C28B /* LegacyMediaPickers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03E3F782304C50D0049C28B /* LegacyMediaPickers.swift */; };
|
D03E3F802304C50E0049C28B /* LegacyMediaPickers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03E3F782304C50D0049C28B /* LegacyMediaPickers.swift */; };
|
||||||
D03E3F812304C50E0049C28B /* LegacyImageProcessors.h in Headers */ = {isa = PBXBuildFile; fileRef = D03E3F792304C50D0049C28B /* LegacyImageProcessors.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D03E3F812304C50E0049C28B /* LegacyImageProcessors.h in Headers */ = {isa = PBXBuildFile; fileRef = D03E3F792304C50D0049C28B /* LegacyImageProcessors.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@ -32,6 +33,7 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
096C16E5231741290047887D /* LegacyICloudFilePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyICloudFilePicker.swift; sourceTree = "<group>"; };
|
||||||
D03E3F692304C4840049C28B /* LegacyMediaPickerUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LegacyMediaPickerUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
D03E3F692304C4840049C28B /* LegacyMediaPickerUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LegacyMediaPickerUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D03E3F6C2304C4840049C28B /* LegacyMediaPickerUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyMediaPickerUI.h; sourceTree = "<group>"; };
|
D03E3F6C2304C4840049C28B /* LegacyMediaPickerUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyMediaPickerUI.h; sourceTree = "<group>"; };
|
||||||
D03E3F6D2304C4840049C28B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
D03E3F6D2304C4840049C28B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
@ -111,6 +113,7 @@
|
|||||||
D03E3F782304C50D0049C28B /* LegacyMediaPickers.swift */,
|
D03E3F782304C50D0049C28B /* LegacyMediaPickers.swift */,
|
||||||
D03E3F7B2304C50D0049C28B /* LegacySuggestionContext.swift */,
|
D03E3F7B2304C50D0049C28B /* LegacySuggestionContext.swift */,
|
||||||
D03E3F7F2304C50D0049C28B /* LegacyWallpaperPicker.swift */,
|
D03E3F7F2304C50D0049C28B /* LegacyWallpaperPicker.swift */,
|
||||||
|
096C16E5231741290047887D /* LegacyICloudFilePicker.swift */,
|
||||||
D03E3F6C2304C4840049C28B /* LegacyMediaPickerUI.h */,
|
D03E3F6C2304C4840049C28B /* LegacyMediaPickerUI.h */,
|
||||||
);
|
);
|
||||||
path = Sources;
|
path = Sources;
|
||||||
@ -219,6 +222,7 @@
|
|||||||
files = (
|
files = (
|
||||||
D03E3F872304C50E0049C28B /* LegacyWallpaperPicker.swift in Sources */,
|
D03E3F872304C50E0049C28B /* LegacyWallpaperPicker.swift in Sources */,
|
||||||
D03E3F842304C50E0049C28B /* LegacyImagePicker.swift in Sources */,
|
D03E3F842304C50E0049C28B /* LegacyImagePicker.swift in Sources */,
|
||||||
|
096C16E62317412A0047887D /* LegacyICloudFilePicker.swift in Sources */,
|
||||||
D03E3F822304C50E0049C28B /* LegacyAttachmentMenu.swift in Sources */,
|
D03E3F822304C50E0049C28B /* LegacyAttachmentMenu.swift in Sources */,
|
||||||
D03E3F852304C50E0049C28B /* LegacyImageProcessors.m in Sources */,
|
D03E3F852304C50E0049C28B /* LegacyImageProcessors.m in Sources */,
|
||||||
D03E3F802304C50E0049C28B /* LegacyMediaPickers.swift in Sources */,
|
D03E3F802304C50E0049C28B /* LegacyMediaPickers.swift in Sources */,
|
||||||
|
@ -30,7 +30,21 @@ private final class LegacyICloudFileController: LegacyController, UIDocumentPick
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func legacyICloudFileController(theme: PresentationTheme, completion: @escaping ([URL]) -> Void) -> ViewController {
|
public enum LegacyICloudFilePickerMode {
|
||||||
|
case `default`
|
||||||
|
case `import`
|
||||||
|
|
||||||
|
var documentPickerMode: UIDocumentPickerMode {
|
||||||
|
switch self {
|
||||||
|
case .default:
|
||||||
|
return .open
|
||||||
|
case .import:
|
||||||
|
return .import
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudFilePickerMode = .default, documentTypes: [String] = ["public.item"], completion: @escaping ([URL]) -> Void) -> ViewController {
|
||||||
var dismissImpl: (() -> Void)?
|
var dismissImpl: (() -> Void)?
|
||||||
let legacyController = LegacyICloudFileController(presentation: .modal(animateIn: true), theme: theme, completion: { urls in
|
let legacyController = LegacyICloudFileController(presentation: .modal(animateIn: true), theme: theme, completion: { urls in
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
@ -38,25 +52,9 @@ func legacyICloudFileController(theme: PresentationTheme, completion: @escaping
|
|||||||
})
|
})
|
||||||
legacyController.statusBar.statusBarStyle = .Black
|
legacyController.statusBar.statusBarStyle = .Black
|
||||||
|
|
||||||
let documentTypes: [String] = [
|
let controller = UIDocumentPickerViewController(documentTypes: documentTypes, in: mode.documentPickerMode)
|
||||||
"public.item"
|
|
||||||
// "public.composite-content",
|
|
||||||
// "public.text",
|
|
||||||
// "public.image",
|
|
||||||
// "public.audio",
|
|
||||||
// "public.video",
|
|
||||||
// "public.movie",
|
|
||||||
// "public.font",
|
|
||||||
// "public.data",
|
|
||||||
// "org.telegram.Telegram.webp",
|
|
||||||
// "com.apple.iwork.pages.pages",
|
|
||||||
// "com.apple.iwork.numbers.numbers",
|
|
||||||
// "com.apple.iwork.keynote.key"
|
|
||||||
]
|
|
||||||
|
|
||||||
let controller = UIDocumentPickerViewController(documentTypes: documentTypes, in: .open)
|
|
||||||
controller.delegate = legacyController
|
controller.delegate = legacyController
|
||||||
if #available(iOSApplicationExtension 11.0, iOS 11.0, *) {
|
if #available(iOSApplicationExtension 11.0, iOS 11.0, *), case .default = mode {
|
||||||
controller.allowsMultipleSelection = true
|
controller.allowsMultipleSelection = true
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ final class PasscodeSetupControllerNode: ASDisplayNode {
|
|||||||
passcodeType = .digits6
|
passcodeType = .digits6
|
||||||
}
|
}
|
||||||
|
|
||||||
self.inputFieldNode = PasscodeEntryInputFieldNode(color: self.presentationData.theme.list.itemPrimaryTextColor, accentColor: self.presentationData.theme.list.itemAccentColor, fieldType: passcodeType, keyboardAppearance: self.presentationData.theme.chatList.searchBarKeyboardColor.keyboardAppearance)
|
self.inputFieldNode = PasscodeEntryInputFieldNode(color: self.presentationData.theme.list.itemPrimaryTextColor, accentColor: self.presentationData.theme.list.itemAccentColor, fieldType: passcodeType, keyboardAppearance: self.presentationData.theme.rootController.keyboardColor.keyboardAppearance)
|
||||||
self.inputFieldBackgroundNode = ASImageNode()
|
self.inputFieldBackgroundNode = ASImageNode()
|
||||||
self.inputFieldBackgroundNode.alpha = passcodeType == .alphanumeric ? 1.0 : 0.0
|
self.inputFieldBackgroundNode.alpha = passcodeType == .alphanumeric ? 1.0 : 0.0
|
||||||
self.inputFieldBackgroundNode.contentMode = .scaleToFill
|
self.inputFieldBackgroundNode.contentMode = .scaleToFill
|
||||||
|
@ -143,7 +143,7 @@ final class FormControllerTextInputItemNode: FormBlockItemNode<FormControllerTex
|
|||||||
self.textField.textField.returnKeyType = item.returnKeyType
|
self.textField.textField.returnKeyType = item.returnKeyType
|
||||||
}
|
}
|
||||||
|
|
||||||
self.textField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textField.textField.tintColor = theme.list.itemAccentColor
|
self.textField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
let attributedPlaceholder = NSAttributedString(string: item.placeholder, font: textFont, textColor: theme.list.itemPlaceholderTextColor)
|
let attributedPlaceholder = NSAttributedString(string: item.placeholder, font: textFont, textColor: theme.list.itemPlaceholderTextColor)
|
||||||
|
@ -46,7 +46,7 @@ final class SecureIdAuthPasswordOptionContentNode: ASDisplayNode, SecureIdAuthCo
|
|||||||
self.inputField = TextFieldNode()
|
self.inputField = TextFieldNode()
|
||||||
|
|
||||||
self.inputButtonNode = HighlightableButtonNode()
|
self.inputButtonNode = HighlightableButtonNode()
|
||||||
self.inputActivityNode = ActivityIndicator(type: .custom(theme.list.itemAccentColor, 18.0, 1.5, false))
|
self.inputActivityNode = ActivityIndicator(type: .custom(theme.list.freeInputField.controlColor, 18.0, 1.5, false))
|
||||||
|
|
||||||
if let image = generateTintedImage(image: UIImage(bundleImageName: "Secure ID/PasswordHelpIcon"), color: theme.list.freeInputField.controlColor) {
|
if let image = generateTintedImage(image: UIImage(bundleImageName: "Secure ID/PasswordHelpIcon"), color: theme.list.freeInputField.controlColor) {
|
||||||
self.inputButtonNode.setImage(image, for: [])
|
self.inputButtonNode.setImage(image, for: [])
|
||||||
@ -59,7 +59,7 @@ final class SecureIdAuthPasswordOptionContentNode: ASDisplayNode, SecureIdAuthCo
|
|||||||
self.inputField.textField.font = passwordFont
|
self.inputField.textField.font = passwordFont
|
||||||
self.inputField.textField.textColor = theme.list.freeInputField.primaryColor
|
self.inputField.textField.textColor = theme.list.freeInputField.primaryColor
|
||||||
self.inputField.textField.attributedPlaceholder = NSAttributedString(string: hint.isEmpty ? strings.LoginPassword_PasswordPlaceholder : hint, font: passwordFont, textColor: theme.list.freeInputField.placeholderColor)
|
self.inputField.textField.attributedPlaceholder = NSAttributedString(string: hint.isEmpty ? strings.LoginPassword_PasswordPlaceholder : hint, font: passwordFont, textColor: theme.list.freeInputField.placeholderColor)
|
||||||
self.inputField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.inputField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.inputField.textField.tintColor = theme.list.itemAccentColor
|
self.inputField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
self.buttonNode = HighlightableButtonNode()
|
self.buttonNode = HighlightableButtonNode()
|
||||||
|
@ -126,8 +126,8 @@ final class SecureIdValueFormPhoneItemNode: FormBlockItemNode<SecureIdValueFormP
|
|||||||
self.phoneInputNode.countryCodeField.textField.tintColor = theme.list.itemAccentColor
|
self.phoneInputNode.countryCodeField.textField.tintColor = theme.list.itemAccentColor
|
||||||
self.phoneInputNode.numberField.textField.tintColor = theme.list.itemAccentColor
|
self.phoneInputNode.numberField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
self.phoneInputNode.countryCodeField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneInputNode.countryCodeField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.phoneInputNode.numberField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneInputNode.numberField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
}
|
}
|
||||||
|
|
||||||
self.item = item
|
self.item = item
|
||||||
|
@ -59,7 +59,7 @@ final class SetupTwoStepVerificationContentNode: ASDisplayNode, UITextFieldDeleg
|
|||||||
self.inputNode.textField.font = Font.regular(22.0)
|
self.inputNode.textField.font = Font.regular(22.0)
|
||||||
self.inputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(22.0), textColor: theme.list.itemPlaceholderTextColor)
|
self.inputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(22.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||||
self.inputNode.textField.textAlignment = .center
|
self.inputNode.textField.textAlignment = .center
|
||||||
self.inputNode.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.inputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.inputNode.textField.tintColor = theme.list.itemAccentColor
|
self.inputNode.textField.tintColor = theme.list.itemAccentColor
|
||||||
switch inputType {
|
switch inputType {
|
||||||
case .password:
|
case .password:
|
||||||
@ -126,7 +126,7 @@ final class SetupTwoStepVerificationContentNode: ASDisplayNode, UITextFieldDeleg
|
|||||||
|
|
||||||
func updatePresentationData(_ presentationData: PresentationData) {
|
func updatePresentationData(_ presentationData: PresentationData) {
|
||||||
self.theme = presentationData.theme
|
self.theme = presentationData.theme
|
||||||
self.inputNode.textField.keyboardAppearance = self.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.inputNode.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.inputSeparator.backgroundColor = self.theme.list.itemPlainSeparatorColor
|
self.inputSeparator.backgroundColor = self.theme.list.itemPlainSeparatorColor
|
||||||
self.inputNode.textField.tintColor = self.theme.list.itemAccentColor
|
self.inputNode.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ private enum ChannelAdminEntry: ItemListNodeEntry {
|
|||||||
}
|
}
|
||||||
return ItemListSectionHeaderItem(theme: theme, text: text, accessoryText: accessoryText, sectionId: self.section)
|
return ItemListSectionHeaderItem(theme: theme, text: text, accessoryText: accessoryText, sectionId: self.section)
|
||||||
case let .rank(theme, strings, placeholder, text, enabled):
|
case let .rank(theme, strings, placeholder, text, enabled):
|
||||||
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearButton: enabled, enabled: enabled, tag: ChannelAdminEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in
|
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearType: enabled ? .always : .none, enabled: enabled, tag: ChannelAdminEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in
|
||||||
arguments.updateRank(text, updatedText)
|
arguments.updateRank(text, updatedText)
|
||||||
}, shouldUpdateText: { text in
|
}, shouldUpdateText: { text in
|
||||||
if text.containsEmoji {
|
if text.containsEmoji {
|
||||||
|
@ -845,7 +845,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
|
|||||||
}
|
}
|
||||||
}, openStats: {
|
}, openStats: {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
var urlSignal = channelStatsUrl(postbox: context.account.postbox, network: context.account.network, peerId: peerId, params: "", darkTheme: presentationData.theme.chatList.searchBarKeyboardColor.keyboardAppearance == .dark)
|
var urlSignal = channelStatsUrl(postbox: context.account.postbox, network: context.account.network, peerId: peerId, params: "", darkTheme: presentationData.theme.rootController.keyboardColor.keyboardAppearance == .dark)
|
||||||
|
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
|
@ -80,7 +80,7 @@ private final class ChannelOwnershipTransferPasswordFieldNode: ASDisplayNode, UI
|
|||||||
self.textInputNode.textField.textColor = self.theme.list.itemPrimaryTextColor
|
self.textInputNode.textField.textColor = self.theme.list.itemPrimaryTextColor
|
||||||
self.textInputNode.textField.isSecureTextEntry = true
|
self.textInputNode.textField.isSecureTextEntry = true
|
||||||
self.textInputNode.textField.returnKeyType = .done
|
self.textInputNode.textField.returnKeyType = .done
|
||||||
self.textInputNode.textField.keyboardAppearance = self.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textInputNode.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textInputNode.clipsToBounds = true
|
self.textInputNode.clipsToBounds = true
|
||||||
self.textInputNode.textField.delegate = self
|
self.textInputNode.textField.delegate = self
|
||||||
self.textInputNode.textField.addTarget(self, action: #selector(self.textFieldTextChanged(_:)), for: .editingChanged)
|
self.textInputNode.textField.addTarget(self, action: #selector(self.textFieldTextChanged(_:)), for: .editingChanged)
|
||||||
@ -92,7 +92,7 @@ private final class ChannelOwnershipTransferPasswordFieldNode: ASDisplayNode, UI
|
|||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 16.0, color: theme.actionSheet.inputHollowBackgroundColor, strokeColor: theme.actionSheet.inputBorderColor, strokeWidth: UIScreenPixel)
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 16.0, color: theme.actionSheet.inputHollowBackgroundColor, strokeColor: theme.actionSheet.inputBorderColor, strokeWidth: UIScreenPixel)
|
||||||
self.textInputNode.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textInputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textInputNode.textField.textColor = theme.list.itemPrimaryTextColor
|
self.textInputNode.textField.textColor = theme.list.itemPrimaryTextColor
|
||||||
self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(14.0), NSAttributedString.Key.foregroundColor: theme.actionSheet.inputTextColor]
|
self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(14.0), NSAttributedString.Key.foregroundColor: theme.actionSheet.inputTextColor]
|
||||||
self.textInputNode.textField.tintColor = theme.list.itemAccentColor
|
self.textInputNode.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
@ -90,7 +90,7 @@ final class ChannelStatsControllerNode: ViewControllerTracingNode, WKNavigationD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.refreshDisposable.set((channelStatsUrl(postbox: self.context.account.postbox, network: self.context.account.network, peerId: self.peerId, params: params, darkTheme: self.presentationData.theme.chatList.searchBarKeyboardColor.keyboardAppearance == .dark)
|
self.refreshDisposable.set((channelStatsUrl(postbox: self.context.account.postbox, network: self.context.account.network, peerId: self.peerId, params: params, darkTheme: self.presentationData.theme.rootController.keyboardColor.keyboardAppearance == .dark)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] url in
|
|> deliverOnMainQueue).start(next: { [weak self] url in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
|
@ -287,7 +287,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||||||
}
|
}
|
||||||
}, tag: ChannelVisibilityEntryTag.privateLink)
|
}, tag: ChannelVisibilityEntryTag.privateLink)
|
||||||
case let .editablePublicLink(theme, strings, placeholder, currentText):
|
case let .editablePublicLink(theme, strings, placeholder, currentText):
|
||||||
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: "t.me/", textColor: theme.list.itemPrimaryTextColor), text: currentText, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), clearButton: true, tag: ChannelVisibilityEntryTag.publicLink, sectionId: self.section, textUpdated: { updatedText in
|
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: "t.me/", textColor: theme.list.itemPrimaryTextColor), text: currentText, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), clearType: .always, tag: ChannelVisibilityEntryTag.publicLink, sectionId: self.section, textUpdated: { updatedText in
|
||||||
arguments.updatePublicLinkText(currentText, updatedText)
|
arguments.updatePublicLinkText(currentText, updatedText)
|
||||||
}, updatedFocus: { focus in
|
}, updatedFocus: { focus in
|
||||||
if focus {
|
if focus {
|
||||||
|
@ -209,7 +209,7 @@ private enum GroupStickerPackEntry: ItemListNodeEntry {
|
|||||||
func item(_ arguments: GroupStickerPackSetupControllerArguments) -> ListViewItem {
|
func item(_ arguments: GroupStickerPackSetupControllerArguments) -> ListViewItem {
|
||||||
switch self {
|
switch self {
|
||||||
case let .search(theme, strings, prefix, placeholder, value):
|
case let .search(theme, strings, prefix, placeholder, value):
|
||||||
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: value, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), spacing: 0.0, clearButton: true, tag: nil, sectionId: self.section, textUpdated: { value in
|
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: value, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), spacing: 0.0, clearType: .always, tag: nil, sectionId: self.section, textUpdated: { value in
|
||||||
arguments.updateSearchText(value)
|
arguments.updateSearchText(value)
|
||||||
}, processPaste: { text in
|
}, processPaste: { text in
|
||||||
if let url = (URL(string: text) ?? URL(string: "http://" + text)), url.host == "t.me" || url.host == "telegram.me" {
|
if let url = (URL(string: text) ?? URL(string: "http://" + text)), url.host == "t.me" || url.host == "telegram.me" {
|
||||||
|
@ -183,7 +183,7 @@ class UserInfoEditingPhoneItemNode: ItemListRevealOptionsItemNode, ItemListItemN
|
|||||||
|
|
||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
self.phoneNode.numberField?.textField.textColor = item.theme.list.itemPrimaryTextColor
|
self.phoneNode.numberField?.textField.textColor = item.theme.list.itemPrimaryTextColor
|
||||||
self.phoneNode.numberField?.textField.keyboardAppearance = item.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneNode.numberField?.textField.keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.phoneNode.numberField?.textField.tintColor = item.theme.list.itemAccentColor
|
self.phoneNode.numberField?.textField.tintColor = item.theme.list.itemAccentColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ class UserInfoEditingPhoneItemNode: ItemListRevealOptionsItemNode, ItemListItemN
|
|||||||
strongSelf.labelSeparatorNode.backgroundColor = itemSeparatorColor
|
strongSelf.labelSeparatorNode.backgroundColor = itemSeparatorColor
|
||||||
|
|
||||||
strongSelf.phoneNode.numberField?.textField.textColor = updatedTheme.list.itemPrimaryTextColor
|
strongSelf.phoneNode.numberField?.textField.textColor = updatedTheme.list.itemPrimaryTextColor
|
||||||
strongSelf.phoneNode.numberField?.textField.keyboardAppearance = updatedTheme.chatList.searchBarKeyboardColor.keyboardAppearance
|
strongSelf.phoneNode.numberField?.textField.keyboardAppearance = updatedTheme.rootController.keyboardColor.keyboardAppearance
|
||||||
strongSelf.phoneNode.numberField?.textField.tintColor = item.theme.list.itemAccentColor
|
strongSelf.phoneNode.numberField?.textField.tintColor = item.theme.list.itemAccentColor
|
||||||
|
|
||||||
strongSelf.clearButton.setImage(generateClearIcon(color: updatedTheme.list.inputClearButtonColor), for: [])
|
strongSelf.clearButton.setImage(generateClearIcon(color: updatedTheme.list.inputClearButtonColor), for: [])
|
||||||
|
@ -161,7 +161,7 @@ public final class SearchBarNodeTheme: Equatable {
|
|||||||
self.inputIcon = theme.rootController.navigationSearchBar.inputIconColor
|
self.inputIcon = theme.rootController.navigationSearchBar.inputIconColor
|
||||||
self.inputClear = theme.rootController.navigationSearchBar.inputClearButtonColor
|
self.inputClear = theme.rootController.navigationSearchBar.inputClearButtonColor
|
||||||
self.accent = theme.rootController.navigationSearchBar.accentColor
|
self.accent = theme.rootController.navigationSearchBar.accentColor
|
||||||
self.keyboard = theme.chatList.searchBarKeyboardColor
|
self.keyboard = theme.rootController.keyboardColor
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: SearchBarNodeTheme, rhs: SearchBarNodeTheme) -> Bool {
|
public static func ==(lhs: SearchBarNodeTheme, rhs: SearchBarNodeTheme) -> Bool {
|
||||||
|
@ -127,10 +127,10 @@ final class ChangePhoneNumberControllerNode: ASDisplayNode {
|
|||||||
|
|
||||||
self.phoneInputNode = PhoneInputNode(fontSize: 17.0)
|
self.phoneInputNode = PhoneInputNode(fontSize: 17.0)
|
||||||
self.phoneInputNode.countryCodeField.textField.textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
self.phoneInputNode.countryCodeField.textField.textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
||||||
self.phoneInputNode.countryCodeField.textField.keyboardAppearance = self.presentationData.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneInputNode.countryCodeField.textField.keyboardAppearance = self.presentationData.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.phoneInputNode.countryCodeField.textField.tintColor = self.presentationData.theme.list.itemAccentColor
|
self.phoneInputNode.countryCodeField.textField.tintColor = self.presentationData.theme.list.itemAccentColor
|
||||||
self.phoneInputNode.numberField.textField.textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
self.phoneInputNode.numberField.textField.textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
||||||
self.phoneInputNode.numberField.textField.keyboardAppearance = self.presentationData.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneInputNode.numberField.textField.keyboardAppearance = self.presentationData.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.phoneInputNode.numberField.textField.tintColor = self.presentationData.theme.list.itemAccentColor
|
self.phoneInputNode.numberField.textField.tintColor = self.presentationData.theme.list.itemAccentColor
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
@ -234,7 +234,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode {
|
|||||||
self.effectView = UIVisualEffectView()
|
self.effectView = UIVisualEffectView()
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
} else {
|
} else {
|
||||||
if presentationData.theme.chatList.searchBarKeyboardColor == .dark {
|
if presentationData.theme.rootController.keyboardColor == .dark {
|
||||||
self.effectView.effect = UIBlurEffect(style: .dark)
|
self.effectView.effect = UIBlurEffect(style: .dark)
|
||||||
} else {
|
} else {
|
||||||
self.effectView.effect = UIBlurEffect(style: .light)
|
self.effectView.effect = UIBlurEffect(style: .light)
|
||||||
@ -244,7 +244,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
self.dimNode = ASDisplayNode()
|
||||||
self.dimNode.alpha = 1.0
|
self.dimNode.alpha = 1.0
|
||||||
if presentationData.theme.chatList.searchBarKeyboardColor == .light {
|
if presentationData.theme.rootController.keyboardColor == .light {
|
||||||
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.04)
|
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.04)
|
||||||
} else {
|
} else {
|
||||||
self.dimNode.backgroundColor = presentationData.theme.chatList.backgroundColor.withAlphaComponent(0.2)
|
self.dimNode.backgroundColor = presentationData.theme.chatList.backgroundColor.withAlphaComponent(0.2)
|
||||||
@ -287,7 +287,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode {
|
|||||||
func animateIn() {
|
func animateIn() {
|
||||||
UIView.animate(withDuration: 0.3, animations: {
|
UIView.animate(withDuration: 0.3, animations: {
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
if self.presentationData.theme.chatList.searchBarKeyboardColor == .dark {
|
if self.presentationData.theme.rootController.keyboardColor == .dark {
|
||||||
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
||||||
self.effectView.effect = UIBlurEffect(style: .regular)
|
self.effectView.effect = UIBlurEffect(style: .regular)
|
||||||
if self.effectView.subviews.count == 2 {
|
if self.effectView.subviews.count == 2 {
|
||||||
@ -310,7 +310,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode {
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strongSelf.presentationData.theme.chatList.searchBarKeyboardColor == .dark {
|
if strongSelf.presentationData.theme.rootController.keyboardColor == .dark {
|
||||||
if strongSelf.effectView.subviews.count == 2 {
|
if strongSelf.effectView.subviews.count == 2 {
|
||||||
strongSelf.effectView.subviews[1].isHidden = true
|
strongSelf.effectView.subviews[1].isHidden = true
|
||||||
}
|
}
|
||||||
|
@ -8,70 +8,79 @@ import TelegramPresentationData
|
|||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
import ItemListUI
|
import ItemListUI
|
||||||
import AlertUI
|
import AlertUI
|
||||||
|
import LegacyMediaPickerUI
|
||||||
import AccountContext
|
import AccountContext
|
||||||
|
|
||||||
private final class EditThemeControllerArguments {
|
private final class EditThemeControllerArguments {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let updateState: ((EditThemeControllerState) -> EditThemeControllerState) -> Void
|
let updateState: ((EditThemeControllerState) -> EditThemeControllerState) -> Void
|
||||||
|
let openFile: () -> Void
|
||||||
|
|
||||||
init(context: AccountContext, updateState: @escaping ((EditThemeControllerState) -> EditThemeControllerState) -> Void) {
|
init(context: AccountContext, updateState: @escaping ((EditThemeControllerState) -> EditThemeControllerState) -> Void, openFile: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.updateState = updateState
|
self.updateState = updateState
|
||||||
|
self.openFile = openFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum EditThemeEntryTag: ItemListItemTag {
|
||||||
|
case title
|
||||||
|
|
||||||
|
func isEqual(to other: ItemListItemTag) -> Bool {
|
||||||
|
if let other = other as? EditThemeEntryTag, self == other {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum EditThemeControllerSection: Int32 {
|
private enum EditThemeControllerSection: Int32 {
|
||||||
case chatPreview
|
|
||||||
case info
|
case info
|
||||||
|
case chatPreview
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum EditThemeControllerEntry: ItemListNodeEntry {
|
private enum EditThemeControllerEntry: ItemListNodeEntry {
|
||||||
case chatPreviewHeader(PresentationTheme, String)
|
case title(PresentationTheme, PresentationStrings, String, String, Bool)
|
||||||
case chatPreview(PresentationTheme, PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder)
|
|
||||||
case title(PresentationTheme, PresentationStrings, String, String)
|
|
||||||
case slug(PresentationTheme, PresentationStrings, String, String, Bool)
|
case slug(PresentationTheme, PresentationStrings, String, String, Bool)
|
||||||
case slugInfo(PresentationTheme, String)
|
case slugInfo(PresentationTheme, String)
|
||||||
|
case chatPreviewHeader(PresentationTheme, String)
|
||||||
|
case chatPreview(PresentationTheme, PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder)
|
||||||
|
case uploadTheme(PresentationTheme, String)
|
||||||
|
case uploadInfo(PresentationTheme, String)
|
||||||
|
|
||||||
var section: ItemListSectionId {
|
var section: ItemListSectionId {
|
||||||
switch self {
|
switch self {
|
||||||
case .chatPreviewHeader, .chatPreview:
|
|
||||||
return EditThemeControllerSection.chatPreview.rawValue
|
|
||||||
case .title, .slug, .slugInfo:
|
case .title, .slug, .slugInfo:
|
||||||
return EditThemeControllerSection.info.rawValue
|
return EditThemeControllerSection.info.rawValue
|
||||||
|
case .chatPreviewHeader, .chatPreview, .uploadTheme, .uploadInfo:
|
||||||
|
return EditThemeControllerSection.chatPreview.rawValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var stableId: Int32 {
|
var stableId: Int32 {
|
||||||
switch self {
|
switch self {
|
||||||
case .chatPreviewHeader:
|
|
||||||
return 0
|
|
||||||
case .chatPreview:
|
|
||||||
return 1
|
|
||||||
case .title:
|
case .title:
|
||||||
return 2
|
return 0
|
||||||
case .slug:
|
case .slug:
|
||||||
return 3
|
return 1
|
||||||
case .slugInfo:
|
case .slugInfo:
|
||||||
|
return 2
|
||||||
|
case .chatPreviewHeader:
|
||||||
|
return 3
|
||||||
|
case .chatPreview:
|
||||||
return 4
|
return 4
|
||||||
|
case .uploadTheme:
|
||||||
|
return 5
|
||||||
|
case .uploadInfo:
|
||||||
|
return 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: EditThemeControllerEntry, rhs: EditThemeControllerEntry) -> Bool {
|
static func ==(lhs: EditThemeControllerEntry, rhs: EditThemeControllerEntry) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
case let .chatPreviewHeader(lhsTheme, lhsText):
|
case let .title(lhsTheme, lhsStrings, lhsTitle, lhsValue, lhsDone):
|
||||||
if case let .chatPreviewHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
if case let .title(rhsTheme, rhsStrings, rhsTitle, rhsValue, rhsDone) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsTitle == rhsTitle, lhsValue == rhsValue, lhsDone == rhsDone {
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .chatPreview(lhsTheme, lhsComponentTheme, lhsWallpaper, lhsFontSize, lhsStrings, lhsTimeFormat, lhsNameOrder):
|
|
||||||
if case let .chatPreview(rhsTheme, rhsComponentTheme, rhsWallpaper, rhsFontSize, rhsStrings, rhsTimeFormat, rhsNameOrder) = rhs, lhsComponentTheme === rhsComponentTheme, lhsTheme === rhsTheme, lhsWallpaper == rhsWallpaper, lhsFontSize == rhsFontSize, lhsStrings === rhsStrings, lhsTimeFormat == rhsTimeFormat, lhsNameOrder == rhsNameOrder {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .title(lhsTheme, lhsStrings, lhsTitle, lhsValue):
|
|
||||||
if case let .title(rhsTheme, rhsStrings, rhsTitle, rhsValue) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsTitle == rhsTitle, lhsValue == rhsValue {
|
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -88,6 +97,30 @@ private enum EditThemeControllerEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case let .chatPreviewHeader(lhsTheme, lhsText):
|
||||||
|
if case let .chatPreviewHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .chatPreview(lhsTheme, lhsComponentTheme, lhsWallpaper, lhsFontSize, lhsStrings, lhsTimeFormat, lhsNameOrder):
|
||||||
|
if case let .chatPreview(rhsTheme, rhsComponentTheme, rhsWallpaper, rhsFontSize, rhsStrings, rhsTimeFormat, rhsNameOrder) = rhs, lhsComponentTheme === rhsComponentTheme, lhsTheme === rhsTheme, lhsWallpaper == rhsWallpaper, lhsFontSize == rhsFontSize, lhsStrings === rhsStrings, lhsTimeFormat == rhsTimeFormat, lhsNameOrder == rhsNameOrder {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .uploadTheme(lhsTheme, lhsText):
|
||||||
|
if case let .uploadTheme(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .uploadInfo(lhsTheme, lhsText):
|
||||||
|
if case let .uploadInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,67 +130,109 @@ private enum EditThemeControllerEntry: ItemListNodeEntry {
|
|||||||
|
|
||||||
func item(_ arguments: EditThemeControllerArguments) -> ListViewItem {
|
func item(_ arguments: EditThemeControllerArguments) -> ListViewItem {
|
||||||
switch self {
|
switch self {
|
||||||
case let .chatPreviewHeader(theme, text):
|
case let .title(theme, strings, title, text, done):
|
||||||
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(), text: text, placeholder: title, type: .regular(capitalization: true, autocorrection: false), returnKeyType: done ? .done : .next, clearType: .onFocus, tag: EditThemeEntryTag.title, sectionId: self.section, textUpdated: { value in
|
||||||
case let .chatPreview(theme, componentTheme, wallpaper, fontSize, strings, dateTimeFormat, nameDisplayOrder):
|
|
||||||
return ThemeSettingsChatPreviewItem(context: arguments.context, theme: theme, componentTheme: componentTheme, strings: strings, sectionId: self.section, fontSize: fontSize, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder)
|
|
||||||
case let .title(theme, strings, title, text):
|
|
||||||
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(), text: text, placeholder: title, sectionId: self.section, textUpdated: { value in
|
|
||||||
arguments.updateState { current in
|
arguments.updateState { current in
|
||||||
var state = current
|
var state = current
|
||||||
state.title = value
|
state.title = value
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
}, action: {})
|
}, action: {
|
||||||
|
|
||||||
|
})
|
||||||
case let .slug(theme, strings, title, text, enabled):
|
case let .slug(theme, strings, title, text, enabled):
|
||||||
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: "t.me/addtheme/", textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: title, type: .username, enabled: enabled, sectionId: self.section, textUpdated: { value in
|
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: "t.me/addtheme/", textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: title, type: .username, clearType: .onFocus, enabled: enabled, sectionId: self.section, textUpdated: { value in
|
||||||
arguments.updateState { current in
|
arguments.updateState { current in
|
||||||
var state = current
|
var state = current
|
||||||
state.slug = value
|
state.slug = value
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
}, action: {})
|
}, action: {
|
||||||
|
|
||||||
|
})
|
||||||
case let .slugInfo(theme, text):
|
case let .slugInfo(theme, text):
|
||||||
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
||||||
|
case let .chatPreviewHeader(theme, text):
|
||||||
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
||||||
|
case let .chatPreview(theme, componentTheme, wallpaper, fontSize, strings, dateTimeFormat, nameDisplayOrder):
|
||||||
|
return ThemeSettingsChatPreviewItem(context: arguments.context, theme: theme, componentTheme: componentTheme, strings: strings, sectionId: self.section, fontSize: fontSize, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder)
|
||||||
|
case let .uploadTheme(theme, text):
|
||||||
|
return ItemListActionItem(theme: theme, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
|
arguments.openFile()
|
||||||
|
})
|
||||||
|
case let .uploadInfo(theme, text):
|
||||||
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct EditThemeControllerState: Equatable {
|
public enum EditThemeControllerMode: Equatable {
|
||||||
var title: String
|
case create
|
||||||
var slug: String
|
case edit(PresentationCloudTheme)
|
||||||
|
|
||||||
var isComplete: Bool {
|
|
||||||
if self.title.isEmpty || self.slug.isEmpty {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func EditThemeControllerEntries(presentationData: PresentationData, theme: PresentationTheme?, state: EditThemeControllerState) -> [EditThemeControllerEntry] {
|
private struct EditThemeControllerState: Equatable {
|
||||||
|
var mode: EditThemeControllerMode
|
||||||
|
var title: String
|
||||||
|
var slug: String
|
||||||
|
var previewTheme: PresentationTheme
|
||||||
|
var updatedTheme: PresentationTheme?
|
||||||
|
var updating: Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
private func editThemeControllerEntries(presentationData: PresentationData, state: EditThemeControllerState) -> [EditThemeControllerEntry] {
|
||||||
var entries: [EditThemeControllerEntry] = []
|
var entries: [EditThemeControllerEntry] = []
|
||||||
|
|
||||||
if let theme = theme {
|
var isCreate = false
|
||||||
entries.append(.chatPreviewHeader(presentationData.theme, presentationData.strings.EditTheme_Preview.uppercased()))
|
if case .create = state.mode {
|
||||||
entries.append(.chatPreview(presentationData.theme, theme, theme.chat.defaultWallpaper, presentationData.fontSize, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder))
|
isCreate = true
|
||||||
|
}
|
||||||
|
entries.append(.title(presentationData.theme, presentationData.strings, presentationData.strings.EditTheme_Title, state.title, isCreate))
|
||||||
|
|
||||||
|
if case .edit = state.mode {
|
||||||
|
entries.append(.slug(presentationData.theme, presentationData.strings, presentationData.strings.EditTheme_ShortLink, state.slug, true))
|
||||||
|
entries.append(.slugInfo(presentationData.theme, presentationData.strings.EditTheme_ShortLinkInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.append(.title(presentationData.theme, presentationData.strings, presentationData.strings.EditTheme_Title, state.title))
|
entries.append(.chatPreviewHeader(presentationData.theme, presentationData.strings.EditTheme_Preview.uppercased()))
|
||||||
entries.append(.slug(presentationData.theme, presentationData.strings, presentationData.strings.EditTheme_ShortLink, state.slug, true))
|
entries.append(.chatPreview(presentationData.theme, state.previewTheme, state.previewTheme.chat.defaultWallpaper, presentationData.fontSize, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder))
|
||||||
entries.append(.slugInfo(presentationData.theme, presentationData.strings.EditTheme_ShortLinkInfo))
|
|
||||||
|
let uploadText: String
|
||||||
|
let uploadInfo: String
|
||||||
|
switch state.mode {
|
||||||
|
case .create:
|
||||||
|
uploadText = presentationData.strings.EditTheme_UploadNewTheme
|
||||||
|
uploadInfo = presentationData.strings.EditTheme_UploadNewInfo
|
||||||
|
case let .edit(theme):
|
||||||
|
if let _ = theme.theme.file {
|
||||||
|
uploadText = presentationData.strings.EditTheme_UploadEditedTheme
|
||||||
|
uploadInfo = presentationData.strings.EditTheme_UploadEditedInfo
|
||||||
|
} else {
|
||||||
|
uploadText = presentationData.strings.EditTheme_UploadNewTheme
|
||||||
|
uploadInfo = presentationData.strings.EditTheme_UploadNewInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entries.append(.uploadTheme(presentationData.theme, uploadText))
|
||||||
|
entries.append(.uploadInfo(presentationData.theme, uploadInfo))
|
||||||
|
|
||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EditThemeControllerMode {
|
public func editThemeController(context: AccountContext, mode: EditThemeControllerMode, navigateToChat: ((PeerId) -> Void)? = nil) -> ViewController {
|
||||||
case createNew
|
let initialState: EditThemeControllerState
|
||||||
case createForExisting(TelegramTheme)
|
switch mode {
|
||||||
case edit(TelegramTheme)
|
case .create:
|
||||||
}
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
initialState = EditThemeControllerState(mode: mode, title: "", slug: "", previewTheme: presentationData.theme.withUpdated(name: "", author: nil, defaultWallpaper: presentationData.chatWallpaper), updatedTheme: nil, updating: false)
|
||||||
public func editThemeController(context: AccountContext, theme: TelegramTheme) -> ViewController {
|
case let .edit(theme):
|
||||||
let initialState = EditThemeControllerState(title: theme.title, slug: theme.slug)
|
let previewTheme: PresentationTheme
|
||||||
|
if let file = theme.theme.file, let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let theme = makePresentationTheme(data: data, resolvedWallpaper: theme.resolvedWallpaper) {
|
||||||
|
previewTheme = theme
|
||||||
|
} else {
|
||||||
|
previewTheme = context.sharedContext.currentPresentationData.with { $0 }.theme
|
||||||
|
}
|
||||||
|
initialState = EditThemeControllerState(mode: mode, title: theme.theme.title, slug: theme.theme.slug, previewTheme: previewTheme, updatedTheme: nil, updating: false)
|
||||||
|
}
|
||||||
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
||||||
let stateValue = Atomic(value: initialState)
|
let stateValue = Atomic(value: initialState)
|
||||||
let updateState: ((EditThemeControllerState) -> EditThemeControllerState) -> Void = { f in
|
let updateState: ((EditThemeControllerState) -> EditThemeControllerState) -> Void = { f in
|
||||||
@ -170,28 +245,153 @@ public func editThemeController(context: AccountContext, theme: TelegramTheme) -
|
|||||||
|
|
||||||
let arguments = EditThemeControllerArguments(context: context, updateState: { f in
|
let arguments = EditThemeControllerArguments(context: context, updateState: { f in
|
||||||
updateState(f)
|
updateState(f)
|
||||||
|
}, openFile: {
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = legacyICloudFilePicker(theme: presentationData.theme, mode: .import, documentTypes: ["org.telegram.Telegram-iOS.theme"], completion: { urls in
|
||||||
|
if let url = urls.first, let data = try? Data(contentsOf: url), let theme = makePresentationTheme(data: data) {
|
||||||
|
updateState { current in
|
||||||
|
var state = current
|
||||||
|
state.previewTheme = theme
|
||||||
|
state.updatedTheme = theme
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.EditTheme_FileReadError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
presentControllerImpl?(controller, nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
var previewTheme: PresentationTheme?
|
|
||||||
if let file = theme.file, let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let theme = makePresentationTheme(data: data) {
|
|
||||||
previewTheme = theme
|
|
||||||
}
|
|
||||||
|
|
||||||
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get())
|
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get())
|
||||||
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<EditThemeControllerEntry>, EditThemeControllerEntry.ItemGenerationArguments)) in
|
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<EditThemeControllerEntry>, EditThemeControllerEntry.ItemGenerationArguments)) in
|
||||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
})
|
})
|
||||||
let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: state.isComplete, action: {
|
|
||||||
//let _ = (updateTheme(account: context.account, resource: resource, title: state.title, slug: state.slug) |> deliverOnMainQueue).start(completed: {
|
var focusItemTag: ItemListItemTag?
|
||||||
// dismissImpl?()
|
if case .create = state.mode {
|
||||||
//})
|
focusItemTag = EditThemeEntryTag.title
|
||||||
})
|
}
|
||||||
|
|
||||||
|
let rightNavigationButton: ItemListNavigationButton
|
||||||
|
if state.updating {
|
||||||
|
rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})
|
||||||
|
} else {
|
||||||
|
let isComplete: Bool
|
||||||
|
if case .create = mode {
|
||||||
|
isComplete = !state.title.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty
|
||||||
|
} else {
|
||||||
|
isComplete = !state.title.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty && !state.slug.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.EditTheme_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: isComplete, action: {
|
||||||
let listState = ItemListNodeState(entries: EditThemeControllerEntries(presentationData: presentationData, theme: previewTheme, state: state), style: .blocks, emptyStateItem: nil, animateChanges: false)
|
arguments.updateState { current in
|
||||||
|
var state = current
|
||||||
return (controllerState, (listState, arguments))
|
state.updating = true
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
let saveThemeTemplateFile: (String, LocalFileMediaResource, @escaping () -> Void) -> Void = { title, resource, completion in
|
||||||
|
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: resource.fileId), partialReference: nil, resource: resource, previewRepresentations: [], immediateThumbnailData: nil, mimeType: "application/x-tgtheme-ios", size: nil, attributes: [.FileName(fileName: "\(title).tgios-theme")])
|
||||||
|
let message = EnqueueMessage.message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil)
|
||||||
|
|
||||||
|
let _ = enqueueMessages(account: context.account, peerId: context.account.peerId, messages: [message]).start()
|
||||||
|
|
||||||
|
if let navigateToChat = navigateToChat {
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.EditTheme_ThemeTemplateAlert, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Settings_SavedMessages, action: {
|
||||||
|
completion()
|
||||||
|
|
||||||
|
navigateToChat(context.account.peerId)
|
||||||
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||||
|
completion()
|
||||||
|
})], actionLayout: .vertical), nil)
|
||||||
|
} else {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let theme: PresentationTheme?
|
||||||
|
let custom: Bool
|
||||||
|
if let updatedTheme = state.updatedTheme {
|
||||||
|
theme = updatedTheme.withUpdated(name: state.title, author: "", defaultWallpaper: nil)
|
||||||
|
custom = true
|
||||||
|
} else {
|
||||||
|
if case let .edit(info) = mode, let _ = info.theme.file {
|
||||||
|
theme = nil
|
||||||
|
custom = true
|
||||||
|
} else {
|
||||||
|
theme = state.previewTheme.withUpdated(name: state.title, author: "", defaultWallpaper: nil)
|
||||||
|
custom = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let themeResource: LocalFileMediaResource?
|
||||||
|
|
||||||
|
if let theme = theme, let themeString = encodePresentationTheme(theme), let themeData = themeString.data(using: .utf8) {
|
||||||
|
let resource = LocalFileMediaResource(fileId: arc4random64())
|
||||||
|
context.account.postbox.mediaBox.storeResourceData(resource.id, data: themeData)
|
||||||
|
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: themeData)
|
||||||
|
themeResource = resource
|
||||||
|
} else {
|
||||||
|
themeResource = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch mode {
|
||||||
|
case .create:
|
||||||
|
if let themeResource = themeResource {
|
||||||
|
let _ = (createTheme(account: context.account, resource: themeResource, title: state.title)
|
||||||
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
|
arguments.updateState { current in
|
||||||
|
var state = current
|
||||||
|
state.updating = false
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}, completed: {
|
||||||
|
if !custom {
|
||||||
|
saveThemeTemplateFile(state.title, themeResource, {
|
||||||
|
dismissImpl?()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
dismissImpl?()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case let .edit(theme):
|
||||||
|
let _ = (updateTheme(account: context.account, theme: theme.theme, title: state.title, slug: state.slug, resource: themeResource)
|
||||||
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
|
arguments.updateState { current in
|
||||||
|
var state = current
|
||||||
|
state.updating = false
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}, completed: {
|
||||||
|
if let themeResource = themeResource, !custom {
|
||||||
|
saveThemeTemplateFile(state.title, themeResource, {
|
||||||
|
dismissImpl?()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
dismissImpl?()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let title: String
|
||||||
|
switch mode {
|
||||||
|
case .create:
|
||||||
|
title = presentationData.strings.EditTheme_CreateTitle
|
||||||
|
case let .edit(theme):
|
||||||
|
if theme.theme.file == nil {
|
||||||
|
title = presentationData.strings.EditTheme_CreateTitle
|
||||||
|
} else {
|
||||||
|
title = presentationData.strings.EditTheme_EditTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||||
|
let listState = ItemListNodeState(entries: editThemeControllerEntries(presentationData: presentationData, state: state), style: .blocks, focusItemTag: focusItemTag, emptyStateItem: nil, animateChanges: false)
|
||||||
|
|
||||||
|
return (controllerState, (listState, arguments))
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = ItemListController(context: context, state: signal)
|
let controller = ItemListController(context: context, state: signal)
|
||||||
@ -202,6 +402,7 @@ public func editThemeController(context: AccountContext, theme: TelegramTheme) -
|
|||||||
controller?.present(c, in: .window(.root), with: a)
|
controller?.present(c, in: .window(.root), with: a)
|
||||||
}
|
}
|
||||||
dismissImpl = { [weak controller] in
|
dismissImpl = { [weak controller] in
|
||||||
|
controller?.view.endEditing(true)
|
||||||
let _ = controller?.dismiss()
|
let _ = controller?.dismiss()
|
||||||
}
|
}
|
||||||
return controller
|
return controller
|
||||||
|
@ -116,7 +116,7 @@ public final class ThemePreviewController: ViewController {
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> map { theme in
|
|> map { theme in
|
||||||
if let theme = theme {
|
if let theme = theme {
|
||||||
return .cloud(theme)
|
return .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil))
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import TelegramPresentationData
|
|||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
import ItemListUI
|
import ItemListUI
|
||||||
import AlertUI
|
import AlertUI
|
||||||
|
import ShareController
|
||||||
import AccountContext
|
import AccountContext
|
||||||
|
|
||||||
func themeDisplayName(strings: PresentationStrings, reference: PresentationThemeReference) -> String {
|
func themeDisplayName(strings: PresentationStrings, reference: PresentationThemeReference) -> String {
|
||||||
@ -27,7 +28,7 @@ func themeDisplayName(strings: PresentationStrings, reference: PresentationTheme
|
|||||||
case let .local(theme):
|
case let .local(theme):
|
||||||
name = theme.title
|
name = theme.title
|
||||||
case let .cloud(theme):
|
case let .cloud(theme):
|
||||||
name = theme.title
|
name = theme.theme.title
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
@ -372,6 +373,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
|
|
||||||
var pushControllerImpl: ((ViewController) -> Void)?
|
var pushControllerImpl: ((ViewController) -> Void)?
|
||||||
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||||
|
var getNavigationControllerImpl: (() -> NavigationController?)?
|
||||||
|
|
||||||
var selectThemeImpl: ((PresentationThemeReference) -> Void)?
|
var selectThemeImpl: ((PresentationThemeReference) -> Void)?
|
||||||
var moreImpl: (() -> Void)?
|
var moreImpl: (() -> Void)?
|
||||||
@ -463,34 +465,44 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
|
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
|
||||||
var items: [ActionSheetItem] = []
|
var items: [ActionSheetItem] = []
|
||||||
items.append(ActionSheetTextItem(title: theme.title))
|
items.append(ActionSheetTextItem(title: theme.theme.title))
|
||||||
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_EditTheme, color: .accent, action: { [weak actionSheet] in
|
if theme.theme.isCreator {
|
||||||
|
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_EditTheme, color: .accent, action: { [weak actionSheet] in
|
||||||
|
actionSheet?.dismissAnimated()
|
||||||
|
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_ShareTheme, color: .accent, action: { [weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
|
let controller = ShareController(context: context, subject: .url("https://t.me/addtheme/\(theme.theme.slug)"), preferredAction: .default)
|
||||||
let controller = editThemeController(context: context, theme: theme)
|
presentControllerImpl?(controller, nil)
|
||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
|
||||||
}))
|
}))
|
||||||
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_RemoveTheme, color: .destructive, action: { [weak actionSheet] in
|
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_RemoveTheme, color: .destructive, action: { [weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
|
|
||||||
let _ = (cloudThemes.get()
|
// let _ = (cloudThemes.get()
|
||||||
|> take(1)
|
// |> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { themes in
|
// |> deliverOnMainQueue).start(next: { themes in
|
||||||
if isCurrent, let themeIndex = themes.firstIndex(where: { $0.id == theme.id }) {
|
// if isCurrent, let themeIndex = themes.firstIndex(where: { $0.id == theme.id }) {
|
||||||
let newTheme: PresentationThemeReference
|
// let newTheme: PresentationThemeReference
|
||||||
if themeIndex > 0 {
|
// if themeIndex > 0 {
|
||||||
newTheme = .cloud(themes[themeIndex - 1])
|
// newTheme = .cloud(themes[themeIndex - 1])
|
||||||
} else {
|
// } else {
|
||||||
newTheme = .builtin(.nightAccent)
|
// newTheme = .builtin(.nightAccent)
|
||||||
}
|
// }
|
||||||
selectThemeImpl?(newTheme)
|
// selectThemeImpl?(newTheme)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let updatedThemes = themes.filter { $0.id != theme.id }
|
// let updatedThemes = themes.filter { $0.id != theme.id }
|
||||||
cloudThemes.set(.single(updatedThemes) |> then(updatedCloudThemes))
|
// cloudThemes.set(.single(updatedThemes) |> then(updatedCloudThemes))
|
||||||
|
//
|
||||||
let _ = (deleteTheme(account: context.account, theme: theme)).start()
|
// let _ = (deleteTheme(account: context.account, theme: theme)).start()
|
||||||
})
|
// })
|
||||||
}))
|
}))
|
||||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
|
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
|
||||||
@ -524,7 +536,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
})
|
})
|
||||||
|
|
||||||
let defaultThemes: [PresentationThemeReference] = [.builtin(.dayClassic), .builtin(.day), .builtin(.night), .builtin(.nightAccent)]
|
let defaultThemes: [PresentationThemeReference] = [.builtin(.dayClassic), .builtin(.day), .builtin(.night), .builtin(.nightAccent)]
|
||||||
let cloudThemes: [PresentationThemeReference] = cloudThemes.map { .cloud($0) }
|
let cloudThemes: [PresentationThemeReference] = cloudThemes.map { .cloud(PresentationCloudTheme(theme: $0, resolvedWallpaper: nil)) }
|
||||||
|
|
||||||
var availableThemes = defaultThemes
|
var availableThemes = defaultThemes
|
||||||
if !defaultThemes.contains(settings.theme) && !cloudThemes.contains(settings.theme) {
|
if !defaultThemes.contains(settings.theme) && !cloudThemes.contains(settings.theme) {
|
||||||
@ -544,37 +556,27 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
(controller?.navigationController as? NavigationController)?.pushViewController(c)
|
(controller?.navigationController as? NavigationController)?.pushViewController(c)
|
||||||
}
|
}
|
||||||
presentControllerImpl = { [weak controller] c, a in
|
presentControllerImpl = { [weak controller] c, a in
|
||||||
controller?.present(c, in: .window(.root), with: a)
|
controller?.present(c, in: .window(.root), with: a, blockInteraction: true)
|
||||||
|
}
|
||||||
|
getNavigationControllerImpl = { [weak controller] in
|
||||||
|
return controller?.navigationController as? NavigationController
|
||||||
}
|
}
|
||||||
selectThemeImpl = { theme in
|
selectThemeImpl = { theme in
|
||||||
arguments.selectTheme(theme)
|
arguments.selectTheme(theme)
|
||||||
}
|
}
|
||||||
moreImpl = { [weak controller] in
|
moreImpl = {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
|
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
|
||||||
var items: [ActionSheetItem] = []
|
var items: [ActionSheetItem] = []
|
||||||
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_CreateTheme, color: .accent, action: { [weak actionSheet] in
|
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_CreateTheme, color: .accent, action: { [weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
|
|
||||||
var randomId: Int64 = 0
|
|
||||||
arc4random_buf(&randomId, 8)
|
|
||||||
let path = NSTemporaryDirectory() + "\(randomId)"
|
|
||||||
|
|
||||||
guard let string = encodePresentationTheme(presentationData.theme), let _ = try? string.write(toFile: path, atomically: true, encoding: .utf8) else {
|
let controller = editThemeController(context: context, mode: .create, navigateToChat: { peerId in
|
||||||
return
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
}
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||||
|
|
||||||
let id = arc4random64()
|
|
||||||
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: LocalFileReferenceMediaResource(localFilePath: path, randomId: id), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "application/x-tgtheme-ios", size: nil, attributes: [.FileName(fileName: "\(presentationData.theme.name.string).tgios-theme")])
|
|
||||||
let message = EnqueueMessage.message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil)
|
|
||||||
|
|
||||||
let _ = enqueueMessages(account: context.account, peerId: context.account.peerId, messages: [message]).start()
|
|
||||||
|
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Appearance_CreateThemeInfo, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Settings_SavedMessages, action: {
|
|
||||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(context.account.peerId)))
|
|
||||||
}
|
}
|
||||||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], actionLayout: .vertical), nil)
|
})
|
||||||
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}))
|
}))
|
||||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
|
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
|
||||||
|
@ -60,7 +60,7 @@ private func themeIconImage(context: AccountContext, theme: PresentationThemeRef
|
|||||||
if case let .local(theme) = theme {
|
if case let .local(theme) = theme {
|
||||||
resource = theme.resource
|
resource = theme.resource
|
||||||
} else if case let .cloud(theme) = theme {
|
} else if case let .cloud(theme) = theme {
|
||||||
resource = theme.file?.resource
|
resource = theme.theme.file?.resource
|
||||||
}
|
}
|
||||||
if let resource = resource {
|
if let resource = resource {
|
||||||
signal = telegramThemeData(account: context.account, accountManager: context.sharedContext.accountManager, resource: resource, synchronousLoad: false)
|
signal = telegramThemeData(account: context.account, accountManager: context.sharedContext.accountManager, resource: resource, synchronousLoad: false)
|
||||||
|
@ -104,7 +104,7 @@ final class WallpaperColorPanelNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
|
|
||||||
self.textFieldNode.textField.font = Font.regular(17.0)
|
self.textFieldNode.textField.font = Font.regular(17.0)
|
||||||
self.textFieldNode.textField.textColor = self.theme.chat.inputPanel.inputTextColor
|
self.textFieldNode.textField.textColor = self.theme.chat.inputPanel.inputTextColor
|
||||||
self.textFieldNode.textField.keyboardAppearance = self.theme.chat.inputPanel.keyboardColor.keyboardAppearance
|
self.textFieldNode.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textFieldNode.textField.autocorrectionType = .no
|
self.textFieldNode.textField.autocorrectionType = .no
|
||||||
self.textFieldNode.textField.autocapitalizationType = .allCharacters
|
self.textFieldNode.textField.autocapitalizationType = .allCharacters
|
||||||
self.textFieldNode.textField.keyboardType = .asciiCapable
|
self.textFieldNode.textField.keyboardType = .asciiCapable
|
||||||
@ -123,7 +123,7 @@ final class WallpaperColorPanelNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
self.textBackgroundNode.image = textInputBackgroundImage(fieldColor: self.theme.chat.inputPanel.inputBackgroundColor, strokeColor: self.theme.chat.inputPanel.inputStrokeColor, diameter: 33.0)
|
self.textBackgroundNode.image = textInputBackgroundImage(fieldColor: self.theme.chat.inputPanel.inputBackgroundColor, strokeColor: self.theme.chat.inputPanel.inputStrokeColor, diameter: 33.0)
|
||||||
|
|
||||||
self.textFieldNode.textField.textColor = self.theme.chat.inputPanel.inputTextColor
|
self.textFieldNode.textField.textColor = self.theme.chat.inputPanel.inputTextColor
|
||||||
self.textFieldNode.textField.keyboardAppearance = self.theme.chat.inputPanel.keyboardColor.keyboardAppearance
|
self.textFieldNode.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textFieldNode.textField.tintColor = self.theme.list.itemAccentColor
|
self.textFieldNode.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ private enum UsernameSetupEntry: ItemListNodeEntry {
|
|||||||
func item(_ arguments: UsernameSetupControllerArguments) -> ListViewItem {
|
func item(_ arguments: UsernameSetupControllerArguments) -> ListViewItem {
|
||||||
switch self {
|
switch self {
|
||||||
case let .editablePublicLink(theme, strings, prefix, currentText, text):
|
case let .editablePublicLink(theme, strings, prefix, currentText, text):
|
||||||
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .username, spacing: 10.0, clearButton: true, tag: UsernameEntryTag.username, sectionId: self.section, textUpdated: { updatedText in
|
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .username, spacing: 10.0, clearType: .always, tag: UsernameEntryTag.username, sectionId: self.section, textUpdated: { updatedText in
|
||||||
arguments.updatePublicLinkText(currentText, updatedText)
|
arguments.updatePublicLinkText(currentText, updatedText)
|
||||||
}, action: {
|
}, action: {
|
||||||
})
|
})
|
||||||
|
@ -50,7 +50,7 @@ final class ShareInputFieldNodeTheme: Equatable {
|
|||||||
|
|
||||||
extension ShareInputFieldNodeTheme {
|
extension ShareInputFieldNodeTheme {
|
||||||
convenience init(presentationTheme theme: PresentationTheme) {
|
convenience init(presentationTheme theme: PresentationTheme) {
|
||||||
self.init(backgroundColor: theme.actionSheet.inputBackgroundColor, textColor: theme.actionSheet.inputTextColor, placeholderColor: theme.actionSheet.inputPlaceholderColor, clearButtonColor: theme.actionSheet.inputClearButtonColor, accentColor: theme.actionSheet.controlAccentColor, keyboard: theme.chatList.searchBarKeyboardColor)
|
self.init(backgroundColor: theme.actionSheet.inputBackgroundColor, textColor: theme.actionSheet.inputTextColor, placeholderColor: theme.actionSheet.inputPlaceholderColor, clearButtonColor: theme.actionSheet.inputClearButtonColor, accentColor: theme.actionSheet.controlAccentColor, keyboard: theme.rootController.keyboardColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ final class ShareSearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0)
|
self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0)
|
||||||
self.textInputNode.textField.keyboardAppearance = keyboardAppearance
|
self.textInputNode.textField.keyboardAppearance = keyboardAppearance
|
||||||
self.textInputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(16.0), textColor: theme.actionSheet.inputPlaceholderColor)
|
self.textInputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(16.0), textColor: theme.actionSheet.inputPlaceholderColor)
|
||||||
self.textInputNode.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textInputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textInputNode.textField.tintColor = theme.actionSheet.controlAccentColor
|
self.textInputNode.textField.tintColor = theme.actionSheet.controlAccentColor
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
@ -130,6 +130,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(CachedStickerQueryResult.self, f: { CachedStickerQueryResult(decoder: $0) })
|
declareEncodable(CachedStickerQueryResult.self, f: { CachedStickerQueryResult(decoder: $0) })
|
||||||
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
|
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
|
||||||
declareEncodable(TelegramTheme.self, f: { TelegramTheme(decoder: $0) })
|
declareEncodable(TelegramTheme.self, f: { TelegramTheme(decoder: $0) })
|
||||||
|
declareEncodable(ThemeSettings.self, f: { ThemeSettings(decoder: $0) })
|
||||||
declareEncodable(SynchronizeMarkAllUnseenPersonalMessagesOperation.self, f: { SynchronizeMarkAllUnseenPersonalMessagesOperation(decoder: $0) })
|
declareEncodable(SynchronizeMarkAllUnseenPersonalMessagesOperation.self, f: { SynchronizeMarkAllUnseenPersonalMessagesOperation(decoder: $0) })
|
||||||
declareEncodable(SynchronizeAppLogEventsOperation.self, f: { SynchronizeAppLogEventsOperation(decoder: $0) })
|
declareEncodable(SynchronizeAppLogEventsOperation.self, f: { SynchronizeAppLogEventsOperation(decoder: $0) })
|
||||||
declareEncodable(CachedRecentPeers.self, f: { CachedRecentPeers(decoder: $0) })
|
declareEncodable(CachedRecentPeers.self, f: { CachedRecentPeers(decoder: $0) })
|
||||||
|
@ -268,6 +268,7 @@ private enum SharedDataKeyValues: Int32 {
|
|||||||
case localizationSettings = 3
|
case localizationSettings = 3
|
||||||
case proxySettings = 4
|
case proxySettings = 4
|
||||||
case autodownloadSettings = 5
|
case autodownloadSettings = 5
|
||||||
|
case themeSettings = 6
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SharedDataKeys {
|
public struct SharedDataKeys {
|
||||||
@ -300,6 +301,12 @@ public struct SharedDataKeys {
|
|||||||
key.setInt32(0, value: SharedDataKeyValues.autodownloadSettings.rawValue)
|
key.setInt32(0, value: SharedDataKeyValues.autodownloadSettings.rawValue)
|
||||||
return key
|
return key
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public static let themeSettings: ValueBoxKey = {
|
||||||
|
let key = ValueBoxKey(length: 4)
|
||||||
|
key.setInt32(0, value: SharedDataKeyValues.themeSettings.rawValue)
|
||||||
|
return key
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func applicationSpecificItemCacheCollectionId(_ value: Int8) -> Int8 {
|
public func applicationSpecificItemCacheCollectionId(_ value: Int8) -> Int8 {
|
||||||
|
@ -140,12 +140,12 @@ private func saveUnsaveTheme(account: Account, theme: TelegramTheme, unsave: Boo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func installTheme(account: Account, theme: TelegramTheme) -> Signal<Void, NoError> {
|
private func installTheme(account: Account, theme: TelegramTheme) -> Signal<Never, NoError> {
|
||||||
return account.network.request(Api.functions.account.installTheme(format: themeFormat, theme: Api.InputTheme.inputTheme(id: theme.id, accessHash: theme.accessHash)))
|
return account.network.request(Api.functions.account.installTheme(format: themeFormat, theme: Api.InputTheme.inputTheme(id: theme.id, accessHash: theme.accessHash)))
|
||||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
|> mapToSignal { _ -> Signal<Never, NoError> in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,7 +233,11 @@ public func createTheme(account: Account, resource: MediaResource, title: String
|
|||||||
|> mapError { _ in return CreateThemeError.generic }
|
|> mapError { _ in return CreateThemeError.generic }
|
||||||
|> mapToSignal { apiTheme -> Signal<CreateThemeResult, CreateThemeError> in
|
|> mapToSignal { apiTheme -> Signal<CreateThemeResult, CreateThemeError> in
|
||||||
if let theme = TelegramTheme(apiTheme: apiTheme) {
|
if let theme = TelegramTheme(apiTheme: apiTheme) {
|
||||||
return .single(.result(theme))
|
return account.postbox.transaction { transaction -> CreateThemeResult in
|
||||||
|
|
||||||
|
return .result(theme)
|
||||||
|
}
|
||||||
|
|> introduceError(CreateThemeError.self)
|
||||||
} else {
|
} else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
@ -299,3 +303,50 @@ public func updateTheme(account: Account, theme: TelegramTheme, title: String?,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class ThemeSettings: PreferencesEntry, Equatable {
|
||||||
|
public let currentTheme: TelegramTheme?
|
||||||
|
|
||||||
|
public init(currentTheme: TelegramTheme?) {
|
||||||
|
self.currentTheme = currentTheme
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: PostboxDecoder) {
|
||||||
|
self.currentTheme = decoder.decodeObjectForKey("t", decoder: { TelegramTheme(decoder: $0) }) as? TelegramTheme
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
if let currentTheme = currentTheme {
|
||||||
|
encoder.encodeObject(currentTheme, forKey: "t")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "t")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||||
|
if let to = to as? ThemeSettings {
|
||||||
|
return self == to
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: ThemeSettings, rhs: ThemeSettings) -> Bool {
|
||||||
|
return lhs.currentTheme == rhs.currentTheme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func applyTheme(accountManager: AccountManager, account: Account, theme: TelegramTheme?) -> Signal<Never, NoError> {
|
||||||
|
return accountManager.transaction { transaction -> Signal<Never, NoError> in
|
||||||
|
transaction.updateSharedData(SharedDataKeys.themeSettings, { _ in
|
||||||
|
return ThemeSettings(currentTheme: theme)
|
||||||
|
})
|
||||||
|
|
||||||
|
if let theme = theme {
|
||||||
|
return installTheme(account: account, theme: theme)
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> switchToLatest
|
||||||
|
}
|
||||||
|
@ -113,7 +113,8 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
statusBarStyle: .white,
|
statusBarStyle: .white,
|
||||||
tabBar: rootTabBar,
|
tabBar: rootTabBar,
|
||||||
navigationBar: rootNavigationBar,
|
navigationBar: rootNavigationBar,
|
||||||
navigationSearchBar: navigationSearchBar
|
navigationSearchBar: navigationSearchBar,
|
||||||
|
keyboardColor: .dark
|
||||||
)
|
)
|
||||||
|
|
||||||
let switchColors = PresentationThemeSwitch(
|
let switchColors = PresentationThemeSwitch(
|
||||||
@ -138,7 +139,7 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
itemHighlightedBackgroundColor: UIColor(rgb: 0x313135),
|
itemHighlightedBackgroundColor: UIColor(rgb: 0x313135),
|
||||||
itemBlocksSeparatorColor: UIColor(rgb: 0x3d3d40),
|
itemBlocksSeparatorColor: UIColor(rgb: 0x3d3d40),
|
||||||
itemPlainSeparatorColor: UIColor(rgb: 0x3d3d40),
|
itemPlainSeparatorColor: UIColor(rgb: 0x3d3d40),
|
||||||
disclosureArrowColor: UIColor(rgb: 0x5a5a5e),
|
disclosureArrowColor: UIColor(rgb: 0xffffff, alpha: 0.28),
|
||||||
sectionHeaderTextColor: UIColor(rgb: 0x8d8e93),
|
sectionHeaderTextColor: UIColor(rgb: 0x8d8e93),
|
||||||
freeTextColor: UIColor(rgb: 0x8d8e93),
|
freeTextColor: UIColor(rgb: 0x8d8e93),
|
||||||
freeTextErrorColor: UIColor(rgb: 0xcf3030),
|
freeTextErrorColor: UIColor(rgb: 0xcf3030),
|
||||||
@ -200,7 +201,6 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
regularSearchBarColor: UIColor(rgb: 0x272728),
|
regularSearchBarColor: UIColor(rgb: 0x272728),
|
||||||
sectionHeaderFillColor: UIColor(rgb: 0x1c1c1d),
|
sectionHeaderFillColor: UIColor(rgb: 0x1c1c1d),
|
||||||
sectionHeaderTextColor: UIColor(rgb: 0xffffff),
|
sectionHeaderTextColor: UIColor(rgb: 0xffffff),
|
||||||
searchBarKeyboardColor: .dark,
|
|
||||||
verifiedIconFillColor: accentColor,
|
verifiedIconFillColor: accentColor,
|
||||||
verifiedIconForegroundColor: badgeTextColor,
|
verifiedIconForegroundColor: badgeTextColor,
|
||||||
secretIconColor: secretColor,
|
secretIconColor: secretColor,
|
||||||
@ -258,7 +258,6 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
primaryTextColor: .white,
|
primaryTextColor: .white,
|
||||||
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5),
|
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5),
|
||||||
mediaRecordingDotColor: destructiveColor,
|
mediaRecordingDotColor: destructiveColor,
|
||||||
keyboardColor: .dark,
|
|
||||||
mediaRecordingControl: inputPanelMediaRecordingControl
|
mediaRecordingControl: inputPanelMediaRecordingControl
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,7 +81,8 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
statusBarStyle: .white,
|
statusBarStyle: .white,
|
||||||
tabBar: rootTabBar,
|
tabBar: rootTabBar,
|
||||||
navigationBar: rootNavigationBar,
|
navigationBar: rootNavigationBar,
|
||||||
navigationSearchBar: navigationSearchBar
|
navigationSearchBar: navigationSearchBar,
|
||||||
|
keyboardColor: .dark
|
||||||
)
|
)
|
||||||
|
|
||||||
let switchColors = PresentationThemeSwitch(
|
let switchColors = PresentationThemeSwitch(
|
||||||
@ -168,7 +169,6 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
regularSearchBarColor: accentColor.withMultiplied(hue: 1.029, saturation: 0.609, brightness: 0.12),
|
regularSearchBarColor: accentColor.withMultiplied(hue: 1.029, saturation: 0.609, brightness: 0.12),
|
||||||
sectionHeaderFillColor: mainBackgroundColor,
|
sectionHeaderFillColor: mainBackgroundColor,
|
||||||
sectionHeaderTextColor: mainSecondaryTextColor.withAlphaComponent(0.5),
|
sectionHeaderTextColor: mainSecondaryTextColor.withAlphaComponent(0.5),
|
||||||
searchBarKeyboardColor: .dark,
|
|
||||||
verifiedIconFillColor: accentColor,
|
verifiedIconFillColor: accentColor,
|
||||||
verifiedIconForegroundColor: .white,
|
verifiedIconForegroundColor: .white,
|
||||||
secretIconColor: secretColor,
|
secretIconColor: secretColor,
|
||||||
@ -228,7 +228,6 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
primaryTextColor: UIColor(rgb: 0xffffff),
|
primaryTextColor: UIColor(rgb: 0xffffff),
|
||||||
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5),
|
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5),
|
||||||
mediaRecordingDotColor: accentColor,
|
mediaRecordingDotColor: accentColor,
|
||||||
keyboardColor: .dark,
|
|
||||||
mediaRecordingControl: inputPanelMediaRecordingControl
|
mediaRecordingControl: inputPanelMediaRecordingControl
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -93,7 +93,8 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr
|
|||||||
statusBarStyle: .black,
|
statusBarStyle: .black,
|
||||||
tabBar: rootTabBar,
|
tabBar: rootTabBar,
|
||||||
navigationBar: rootNavigationBar,
|
navigationBar: rootNavigationBar,
|
||||||
navigationSearchBar: navigationSearchBar
|
navigationSearchBar: navigationSearchBar,
|
||||||
|
keyboardColor: .light
|
||||||
)
|
)
|
||||||
|
|
||||||
let switchColors = PresentationThemeSwitch(
|
let switchColors = PresentationThemeSwitch(
|
||||||
@ -180,7 +181,6 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr
|
|||||||
regularSearchBarColor: UIColor(rgb: 0xe9e9e9),
|
regularSearchBarColor: UIColor(rgb: 0xe9e9e9),
|
||||||
sectionHeaderFillColor: UIColor(rgb: 0xf7f7f7),
|
sectionHeaderFillColor: UIColor(rgb: 0xf7f7f7),
|
||||||
sectionHeaderTextColor: UIColor(rgb: 0x8e8e93),
|
sectionHeaderTextColor: UIColor(rgb: 0x8e8e93),
|
||||||
searchBarKeyboardColor: .light,
|
|
||||||
verifiedIconFillColor: accentColor,
|
verifiedIconFillColor: accentColor,
|
||||||
verifiedIconForegroundColor: .white,
|
verifiedIconForegroundColor: .white,
|
||||||
secretIconColor: secretColor,
|
secretIconColor: secretColor,
|
||||||
@ -264,7 +264,6 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr
|
|||||||
primaryTextColor: .black,
|
primaryTextColor: .black,
|
||||||
secondaryTextColor: UIColor(rgb: 0x8e8e93),
|
secondaryTextColor: UIColor(rgb: 0x8e8e93),
|
||||||
mediaRecordingDotColor: UIColor(rgb: 0xed2521),
|
mediaRecordingDotColor: UIColor(rgb: 0xed2521),
|
||||||
keyboardColor: .light,
|
|
||||||
mediaRecordingControl: inputPanelMediaRecordingControl
|
mediaRecordingControl: inputPanelMediaRecordingControl
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public func makePresentationTheme(mediaBox: MediaBox, themeReference: Presentati
|
|||||||
theme = makeDefaultPresentationTheme(reference: .dayClassic, accentColor: nil, serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, preview: preview)
|
theme = makeDefaultPresentationTheme(reference: .dayClassic, accentColor: nil, serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, preview: preview)
|
||||||
}
|
}
|
||||||
case let .cloud(info):
|
case let .cloud(info):
|
||||||
if let file = info.file, let path = mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data) {
|
if let file = info.theme.file, let path = mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data, resolvedWallpaper: info.resolvedWallpaper) {
|
||||||
theme = loadedTheme
|
theme = loadedTheme
|
||||||
} else {
|
} else {
|
||||||
theme = makeDefaultPresentationTheme(reference: .dayClassic, accentColor: nil, serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, preview: preview)
|
theme = makeDefaultPresentationTheme(reference: .dayClassic, accentColor: nil, serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, preview: preview)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -140,12 +140,14 @@ public final class PresentationThemeRootController {
|
|||||||
public let tabBar: PresentationThemeRootTabBar
|
public let tabBar: PresentationThemeRootTabBar
|
||||||
public let navigationBar: PresentationThemeRootNavigationBar
|
public let navigationBar: PresentationThemeRootNavigationBar
|
||||||
public let navigationSearchBar: PresentationThemeNavigationSearchBar
|
public let navigationSearchBar: PresentationThemeNavigationSearchBar
|
||||||
|
public let keyboardColor: PresentationThemeKeyboardColor
|
||||||
|
|
||||||
public init(statusBarStyle: PresentationThemeStatusBarStyle, tabBar: PresentationThemeRootTabBar, navigationBar: PresentationThemeRootNavigationBar, navigationSearchBar: PresentationThemeNavigationSearchBar) {
|
public init(statusBarStyle: PresentationThemeStatusBarStyle, tabBar: PresentationThemeRootTabBar, navigationBar: PresentationThemeRootNavigationBar, navigationSearchBar: PresentationThemeNavigationSearchBar, keyboardColor: PresentationThemeKeyboardColor) {
|
||||||
self.statusBarStyle = statusBarStyle
|
self.statusBarStyle = statusBarStyle
|
||||||
self.tabBar = tabBar
|
self.tabBar = tabBar
|
||||||
self.navigationBar = navigationBar
|
self.navigationBar = navigationBar
|
||||||
self.navigationSearchBar = navigationSearchBar
|
self.navigationSearchBar = navigationSearchBar
|
||||||
|
self.keyboardColor = keyboardColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +399,6 @@ public final class PresentationThemeChatList {
|
|||||||
public let regularSearchBarColor: UIColor
|
public let regularSearchBarColor: UIColor
|
||||||
public let sectionHeaderFillColor: UIColor
|
public let sectionHeaderFillColor: UIColor
|
||||||
public let sectionHeaderTextColor: UIColor
|
public let sectionHeaderTextColor: UIColor
|
||||||
public let searchBarKeyboardColor: PresentationThemeKeyboardColor
|
|
||||||
public let verifiedIconFillColor: UIColor
|
public let verifiedIconFillColor: UIColor
|
||||||
public let verifiedIconForegroundColor: UIColor
|
public let verifiedIconForegroundColor: UIColor
|
||||||
public let secretIconColor: UIColor
|
public let secretIconColor: UIColor
|
||||||
@ -405,7 +406,7 @@ public final class PresentationThemeChatList {
|
|||||||
public let unpinnedArchiveAvatarColor: PresentationThemeArchiveAvatarColors
|
public let unpinnedArchiveAvatarColor: PresentationThemeArchiveAvatarColors
|
||||||
public let onlineDotColor: UIColor
|
public let onlineDotColor: UIColor
|
||||||
|
|
||||||
init(backgroundColor: UIColor, itemSeparatorColor: UIColor, itemBackgroundColor: UIColor, pinnedItemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemSelectedBackgroundColor: UIColor, titleColor: UIColor, secretTitleColor: UIColor, dateTextColor: UIColor, authorNameColor: UIColor, messageTextColor: UIColor, messageDraftTextColor: UIColor, checkmarkColor: UIColor, pendingIndicatorColor: UIColor, failedFillColor: UIColor, failedForegroundColor: UIColor, muteIconColor: UIColor, unreadBadgeActiveBackgroundColor: UIColor, unreadBadgeActiveTextColor: UIColor, unreadBadgeInactiveBackgroundColor: UIColor, unreadBadgeInactiveTextColor: UIColor, pinnedBadgeColor: UIColor, pinnedSearchBarColor: UIColor, regularSearchBarColor: UIColor, sectionHeaderFillColor: UIColor, sectionHeaderTextColor: UIColor, searchBarKeyboardColor: PresentationThemeKeyboardColor, verifiedIconFillColor: UIColor, verifiedIconForegroundColor: UIColor, secretIconColor: UIColor, pinnedArchiveAvatarColor: PresentationThemeArchiveAvatarColors, unpinnedArchiveAvatarColor: PresentationThemeArchiveAvatarColors, onlineDotColor: UIColor) {
|
init(backgroundColor: UIColor, itemSeparatorColor: UIColor, itemBackgroundColor: UIColor, pinnedItemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemSelectedBackgroundColor: UIColor, titleColor: UIColor, secretTitleColor: UIColor, dateTextColor: UIColor, authorNameColor: UIColor, messageTextColor: UIColor, messageDraftTextColor: UIColor, checkmarkColor: UIColor, pendingIndicatorColor: UIColor, failedFillColor: UIColor, failedForegroundColor: UIColor, muteIconColor: UIColor, unreadBadgeActiveBackgroundColor: UIColor, unreadBadgeActiveTextColor: UIColor, unreadBadgeInactiveBackgroundColor: UIColor, unreadBadgeInactiveTextColor: UIColor, pinnedBadgeColor: UIColor, pinnedSearchBarColor: UIColor, regularSearchBarColor: UIColor, sectionHeaderFillColor: UIColor, sectionHeaderTextColor: UIColor, verifiedIconFillColor: UIColor, verifiedIconForegroundColor: UIColor, secretIconColor: UIColor, pinnedArchiveAvatarColor: PresentationThemeArchiveAvatarColors, unpinnedArchiveAvatarColor: PresentationThemeArchiveAvatarColors, onlineDotColor: UIColor) {
|
||||||
self.backgroundColor = backgroundColor
|
self.backgroundColor = backgroundColor
|
||||||
self.itemSeparatorColor = itemSeparatorColor
|
self.itemSeparatorColor = itemSeparatorColor
|
||||||
self.itemBackgroundColor = itemBackgroundColor
|
self.itemBackgroundColor = itemBackgroundColor
|
||||||
@ -432,7 +433,6 @@ public final class PresentationThemeChatList {
|
|||||||
self.regularSearchBarColor = regularSearchBarColor
|
self.regularSearchBarColor = regularSearchBarColor
|
||||||
self.sectionHeaderFillColor = sectionHeaderFillColor
|
self.sectionHeaderFillColor = sectionHeaderFillColor
|
||||||
self.sectionHeaderTextColor = sectionHeaderTextColor
|
self.sectionHeaderTextColor = sectionHeaderTextColor
|
||||||
self.searchBarKeyboardColor = searchBarKeyboardColor
|
|
||||||
self.verifiedIconFillColor = verifiedIconFillColor
|
self.verifiedIconFillColor = verifiedIconFillColor
|
||||||
self.verifiedIconForegroundColor = verifiedIconForegroundColor
|
self.verifiedIconForegroundColor = verifiedIconForegroundColor
|
||||||
self.secretIconColor = secretIconColor
|
self.secretIconColor = secretIconColor
|
||||||
@ -715,10 +715,9 @@ public final class PresentationThemeChatInputPanel {
|
|||||||
public let primaryTextColor: UIColor
|
public let primaryTextColor: UIColor
|
||||||
public let secondaryTextColor: UIColor
|
public let secondaryTextColor: UIColor
|
||||||
public let mediaRecordingDotColor: UIColor
|
public let mediaRecordingDotColor: UIColor
|
||||||
public let keyboardColor: PresentationThemeKeyboardColor
|
|
||||||
public let mediaRecordingControl: PresentationThemeChatInputPanelMediaRecordingControl
|
public let mediaRecordingControl: PresentationThemeChatInputPanelMediaRecordingControl
|
||||||
|
|
||||||
public init(panelBackgroundColor: UIColor, panelSeparatorColor: UIColor, panelControlAccentColor: UIColor, panelControlColor: UIColor, panelControlDisabledColor: UIColor, panelControlDestructiveColor: UIColor, inputBackgroundColor: UIColor, inputStrokeColor: UIColor, inputPlaceholderColor: UIColor, inputTextColor: UIColor, inputControlColor: UIColor, actionControlFillColor: UIColor, actionControlForegroundColor: UIColor, primaryTextColor: UIColor, secondaryTextColor: UIColor, mediaRecordingDotColor: UIColor, keyboardColor: PresentationThemeKeyboardColor, mediaRecordingControl: PresentationThemeChatInputPanelMediaRecordingControl) {
|
public init(panelBackgroundColor: UIColor, panelSeparatorColor: UIColor, panelControlAccentColor: UIColor, panelControlColor: UIColor, panelControlDisabledColor: UIColor, panelControlDestructiveColor: UIColor, inputBackgroundColor: UIColor, inputStrokeColor: UIColor, inputPlaceholderColor: UIColor, inputTextColor: UIColor, inputControlColor: UIColor, actionControlFillColor: UIColor, actionControlForegroundColor: UIColor, primaryTextColor: UIColor, secondaryTextColor: UIColor, mediaRecordingDotColor: UIColor, mediaRecordingControl: PresentationThemeChatInputPanelMediaRecordingControl) {
|
||||||
self.panelBackgroundColor = panelBackgroundColor
|
self.panelBackgroundColor = panelBackgroundColor
|
||||||
self.panelSeparatorColor = panelSeparatorColor
|
self.panelSeparatorColor = panelSeparatorColor
|
||||||
self.panelControlAccentColor = panelControlAccentColor
|
self.panelControlAccentColor = panelControlAccentColor
|
||||||
@ -735,7 +734,6 @@ public final class PresentationThemeChatInputPanel {
|
|||||||
self.primaryTextColor = primaryTextColor
|
self.primaryTextColor = primaryTextColor
|
||||||
self.secondaryTextColor = secondaryTextColor
|
self.secondaryTextColor = secondaryTextColor
|
||||||
self.mediaRecordingDotColor = mediaRecordingDotColor
|
self.mediaRecordingDotColor = mediaRecordingDotColor
|
||||||
self.keyboardColor = keyboardColor
|
|
||||||
self.mediaRecordingControl = mediaRecordingControl
|
self.mediaRecordingControl = mediaRecordingControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -822,6 +820,10 @@ public final class PresentationThemeChat {
|
|||||||
self.inputButtonPanel = inputButtonPanel
|
self.inputButtonPanel = inputButtonPanel
|
||||||
self.historyNavigation = historyNavigation
|
self.historyNavigation = historyNavigation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func withUpdatedDefaultWallpaper(_ defaultWallpaper: TelegramWallpaper?) -> PresentationThemeChat {
|
||||||
|
return PresentationThemeChat(defaultWallpaper: defaultWallpaper ?? self.defaultWallpaper, message: self.message, serviceMessage: self.serviceMessage, inputPanel: self.inputPanel, inputMediaPanel: self.inputMediaPanel, inputButtonPanel: self.inputButtonPanel, historyNavigation: self.historyNavigation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PresentationThemeExpandedNotificationBackgroundType: Int32 {
|
public enum PresentationThemeExpandedNotificationBackgroundType: Int32 {
|
||||||
@ -974,4 +976,21 @@ public final class PresentationTheme: Equatable {
|
|||||||
public static func ==(lhs: PresentationTheme, rhs: PresentationTheme) -> Bool {
|
public static func ==(lhs: PresentationTheme, rhs: PresentationTheme) -> Bool {
|
||||||
return lhs === rhs
|
return lhs === rhs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func withUpdated(name: String?, author: String?, defaultWallpaper: TelegramWallpaper?) -> PresentationTheme {
|
||||||
|
var defaultWallpaper = defaultWallpaper
|
||||||
|
if let wallpaper = defaultWallpaper {
|
||||||
|
switch wallpaper {
|
||||||
|
case .image:
|
||||||
|
defaultWallpaper = nil
|
||||||
|
case let .file(file):
|
||||||
|
if file.isPattern {
|
||||||
|
defaultWallpaper = nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PresentationTheme(name: name.flatMap(PresentationThemeName.custom) ?? .custom(self.name.string), author: author ?? self.author, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, baseColor: nil, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: self.list, chatList: self.chatList, chat: self.chat.withUpdatedDefaultWallpaper(defaultWallpaper), actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Postbox
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ extension TelegramWallpaper: Codable {
|
|||||||
if let color = UIColor(hexString: value) {
|
if let color = UIColor(hexString: value) {
|
||||||
self = .color(Int32(bitPattern: color.rgb))
|
self = .color(Int32(bitPattern: color.rgb))
|
||||||
} else {
|
} else {
|
||||||
throw PresentationThemeDecodingError.generic
|
self = .file(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: false, isDark: false, slug: value, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: false, motion: false, color: nil, intensity: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -50,6 +51,8 @@ extension TelegramWallpaper: Codable {
|
|||||||
try container.encode("builtin")
|
try container.encode("builtin")
|
||||||
case let .color(value):
|
case let .color(value):
|
||||||
try container.encode(String(format: "%06x", value))
|
try container.encode(String(format: "%06x", value))
|
||||||
|
case let .file(file):
|
||||||
|
try container.encode(file.slug)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -354,6 +357,7 @@ extension PresentationThemeRootController: Codable {
|
|||||||
case tabBar
|
case tabBar
|
||||||
case navBar
|
case navBar
|
||||||
case searchBar
|
case searchBar
|
||||||
|
case keyboard
|
||||||
}
|
}
|
||||||
|
|
||||||
public convenience init(from decoder: Decoder) throws {
|
public convenience init(from decoder: Decoder) throws {
|
||||||
@ -361,7 +365,8 @@ extension PresentationThemeRootController: Codable {
|
|||||||
self.init(statusBarStyle: try values.decode(PresentationThemeStatusBarStyle.self, forKey: .statusBar),
|
self.init(statusBarStyle: try values.decode(PresentationThemeStatusBarStyle.self, forKey: .statusBar),
|
||||||
tabBar: try values.decode(PresentationThemeRootTabBar.self, forKey: .tabBar),
|
tabBar: try values.decode(PresentationThemeRootTabBar.self, forKey: .tabBar),
|
||||||
navigationBar: try values.decode(PresentationThemeRootNavigationBar.self, forKey: .navBar),
|
navigationBar: try values.decode(PresentationThemeRootNavigationBar.self, forKey: .navBar),
|
||||||
navigationSearchBar: try values.decode(PresentationThemeNavigationSearchBar.self, forKey: .searchBar))
|
navigationSearchBar: try values.decode(PresentationThemeNavigationSearchBar.self, forKey: .searchBar),
|
||||||
|
keyboardColor: try values.decode(PresentationThemeKeyboardColor.self, forKey: .keyboard))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -370,6 +375,7 @@ extension PresentationThemeRootController: Codable {
|
|||||||
try values.encode(self.tabBar, forKey: .tabBar)
|
try values.encode(self.tabBar, forKey: .tabBar)
|
||||||
try values.encode(self.navigationBar, forKey: .navBar)
|
try values.encode(self.navigationBar, forKey: .navBar)
|
||||||
try values.encode(self.navigationSearchBar, forKey: .searchBar)
|
try values.encode(self.navigationSearchBar, forKey: .searchBar)
|
||||||
|
try values.encode(self.keyboardColor, forKey: .keyboard)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +727,6 @@ extension PresentationThemeChatList: Codable {
|
|||||||
case regularSearchBar
|
case regularSearchBar
|
||||||
case sectionHeaderBg
|
case sectionHeaderBg
|
||||||
case sectionHeaderText
|
case sectionHeaderText
|
||||||
case searchBarKeyboard
|
|
||||||
case verifiedIconBg
|
case verifiedIconBg
|
||||||
case verifiedIconFg
|
case verifiedIconFg
|
||||||
case secretIcon
|
case secretIcon
|
||||||
@ -758,7 +763,6 @@ extension PresentationThemeChatList: Codable {
|
|||||||
regularSearchBarColor: try decodeColor(values, .regularSearchBar),
|
regularSearchBarColor: try decodeColor(values, .regularSearchBar),
|
||||||
sectionHeaderFillColor: try decodeColor(values, .sectionHeaderBg),
|
sectionHeaderFillColor: try decodeColor(values, .sectionHeaderBg),
|
||||||
sectionHeaderTextColor: try decodeColor(values, .sectionHeaderText),
|
sectionHeaderTextColor: try decodeColor(values, .sectionHeaderText),
|
||||||
searchBarKeyboardColor: try values.decode(PresentationThemeKeyboardColor.self, forKey: .searchBarKeyboard),
|
|
||||||
verifiedIconFillColor: try decodeColor(values, .verifiedIconBg),
|
verifiedIconFillColor: try decodeColor(values, .verifiedIconBg),
|
||||||
verifiedIconForegroundColor: try decodeColor(values, .verifiedIconFg),
|
verifiedIconForegroundColor: try decodeColor(values, .verifiedIconFg),
|
||||||
secretIconColor: try decodeColor(values, .secretIcon),
|
secretIconColor: try decodeColor(values, .secretIcon),
|
||||||
@ -795,7 +799,6 @@ extension PresentationThemeChatList: Codable {
|
|||||||
try encodeColor(&values, self.regularSearchBarColor, .regularSearchBar)
|
try encodeColor(&values, self.regularSearchBarColor, .regularSearchBar)
|
||||||
try encodeColor(&values, self.sectionHeaderFillColor, .sectionHeaderBg)
|
try encodeColor(&values, self.sectionHeaderFillColor, .sectionHeaderBg)
|
||||||
try encodeColor(&values, self.sectionHeaderTextColor, .sectionHeaderText)
|
try encodeColor(&values, self.sectionHeaderTextColor, .sectionHeaderText)
|
||||||
try values.encode(self.searchBarKeyboardColor, forKey: .searchBarKeyboard)
|
|
||||||
try encodeColor(&values, self.verifiedIconFillColor, .verifiedIconBg)
|
try encodeColor(&values, self.verifiedIconFillColor, .verifiedIconBg)
|
||||||
try encodeColor(&values, self.verifiedIconForegroundColor, .verifiedIconFg)
|
try encodeColor(&values, self.verifiedIconForegroundColor, .verifiedIconFg)
|
||||||
try encodeColor(&values, self.secretIconColor, .secretIcon)
|
try encodeColor(&values, self.secretIconColor, .secretIcon)
|
||||||
@ -1143,7 +1146,6 @@ extension PresentationThemeChatInputPanel: Codable {
|
|||||||
case primaryText
|
case primaryText
|
||||||
case secondaryText
|
case secondaryText
|
||||||
case mediaRecordDot
|
case mediaRecordDot
|
||||||
case keyboard
|
|
||||||
case mediaRecordControl
|
case mediaRecordControl
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,7 +1167,6 @@ extension PresentationThemeChatInputPanel: Codable {
|
|||||||
primaryTextColor: try decodeColor(values, .primaryText),
|
primaryTextColor: try decodeColor(values, .primaryText),
|
||||||
secondaryTextColor: try decodeColor(values, .secondaryText),
|
secondaryTextColor: try decodeColor(values, .secondaryText),
|
||||||
mediaRecordingDotColor: try decodeColor(values, .mediaRecordDot),
|
mediaRecordingDotColor: try decodeColor(values, .mediaRecordDot),
|
||||||
keyboardColor: try values.decode(PresentationThemeKeyboardColor.self, forKey: .keyboard),
|
|
||||||
mediaRecordingControl: try values.decode(PresentationThemeChatInputPanelMediaRecordingControl.self, forKey: .mediaRecordControl))
|
mediaRecordingControl: try values.decode(PresentationThemeChatInputPanelMediaRecordingControl.self, forKey: .mediaRecordControl))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1187,7 +1188,6 @@ extension PresentationThemeChatInputPanel: Codable {
|
|||||||
try encodeColor(&values, self.primaryTextColor, .primaryText)
|
try encodeColor(&values, self.primaryTextColor, .primaryText)
|
||||||
try encodeColor(&values, self.secondaryTextColor, .secondaryText)
|
try encodeColor(&values, self.secondaryTextColor, .secondaryText)
|
||||||
try encodeColor(&values, self.mediaRecordingDotColor, .mediaRecordDot)
|
try encodeColor(&values, self.mediaRecordingDotColor, .mediaRecordDot)
|
||||||
try values.encode(self.keyboardColor, forKey: .keyboard)
|
|
||||||
try values.encode(self.mediaRecordingControl, forKey: .mediaRecordControl)
|
try values.encode(self.mediaRecordingControl, forKey: .mediaRecordControl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1313,7 +1313,15 @@ extension PresentationThemeChat: 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(defaultWallpaper: try values.decode(TelegramWallpaper.self, forKey: .defaultWallpaper),
|
|
||||||
|
var wallpaper = try values.decode(TelegramWallpaper.self, forKey: .defaultWallpaper)
|
||||||
|
if let decoder = decoder as? PresentationThemeDecoding {
|
||||||
|
if case .file = wallpaper, let resolvedWallpaper = decoder.resolvedWallpaper {
|
||||||
|
wallpaper = resolvedWallpaper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.init(defaultWallpaper: wallpaper,
|
||||||
message: try values.decode(PresentationThemeChatMessage.self, forKey: .message),
|
message: try values.decode(PresentationThemeChatMessage.self, forKey: .message),
|
||||||
serviceMessage: try values.decode(PresentationThemeServiceMessage.self, forKey: .serviceMessage),
|
serviceMessage: try values.decode(PresentationThemeServiceMessage.self, forKey: .serviceMessage),
|
||||||
inputPanel: try values.decode(PresentationThemeChatInputPanel.self, forKey: .inputPanel),
|
inputPanel: try values.decode(PresentationThemeChatInputPanel.self, forKey: .inputPanel),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
import TelegramCore
|
||||||
|
|
||||||
public func encodePresentationTheme(_ theme: PresentationTheme) -> String? {
|
public func encodePresentationTheme(_ theme: PresentationTheme) -> String? {
|
||||||
let encoding = PresentationThemeEncoding()
|
let encoding = PresentationThemeEncoding()
|
||||||
@ -321,7 +322,7 @@ private class PresentationThemeDecodingLevel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func makePresentationTheme(data: Data) -> PresentationTheme? {
|
public func makePresentationTheme(data: Data, resolvedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme? {
|
||||||
guard let string = String(data: data, encoding: .utf8) else {
|
guard let string = String(data: data, encoding: .utf8) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -378,6 +379,7 @@ public func makePresentationTheme(data: Data) -> PresentationTheme? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let decoder = PresentationThemeDecoding(referencing: topLevel.data)
|
let decoder = PresentationThemeDecoding(referencing: topLevel.data)
|
||||||
|
decoder.resolvedWallpaper = resolvedWallpaper
|
||||||
if let value = try? decoder.unbox(topLevel.data, as: PresentationTheme.self) {
|
if let value = try? decoder.unbox(topLevel.data, as: PresentationTheme.self) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
@ -392,10 +394,11 @@ class PresentationThemeDecoding: Decoder {
|
|||||||
public var userInfo: [CodingUserInfoKey : Any] {
|
public var userInfo: [CodingUserInfoKey : Any] {
|
||||||
return [:]
|
return [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
var referenceTheme: PresentationTheme?
|
var referenceTheme: PresentationTheme?
|
||||||
var serviceBackgroundColor: UIColor?
|
var serviceBackgroundColor: UIColor?
|
||||||
|
var resolvedWallpaper: TelegramWallpaper?
|
||||||
|
|
||||||
private var _referenceCoding: PresentationThemeEncoding?
|
private var _referenceCoding: PresentationThemeEncoding?
|
||||||
fileprivate var referenceCoding: PresentationThemeEncoding? {
|
fileprivate var referenceCoding: PresentationThemeEncoding? {
|
||||||
if let referenceCoding = self._referenceCoding {
|
if let referenceCoding = self._referenceCoding {
|
||||||
|
@ -136,7 +136,7 @@ final class AuthorizedApplicationContext {
|
|||||||
self.notificationController = NotificationContainerController(context: context)
|
self.notificationController = NotificationContainerController(context: context)
|
||||||
|
|
||||||
self.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor
|
self.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor
|
||||||
self.mainWindow.previewThemeDarkBlur = presentationData.theme.chatList.searchBarKeyboardColor == .dark
|
self.mainWindow.previewThemeDarkBlur = presentationData.theme.rootController.keyboardColor == .dark
|
||||||
self.mainWindow.setupVolumeControlStatusBarGraphics(presentationData.volumeControlStatusBarIcons.images)
|
self.mainWindow.setupVolumeControlStatusBarGraphics(presentationData.volumeControlStatusBarIcons.images)
|
||||||
|
|
||||||
self.rootController = TelegramRootController(context: context)
|
self.rootController = TelegramRootController(context: context)
|
||||||
@ -740,7 +740,7 @@ final class AuthorizedApplicationContext {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if previousTheme.swap(presentationData.theme) !== presentationData.theme {
|
if previousTheme.swap(presentationData.theme) !== presentationData.theme {
|
||||||
strongSelf.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor
|
strongSelf.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor
|
||||||
strongSelf.mainWindow.previewThemeDarkBlur = presentationData.theme.chatList.searchBarKeyboardColor == .dark
|
strongSelf.mainWindow.previewThemeDarkBlur = presentationData.theme.rootController.keyboardColor == .dark
|
||||||
strongSelf.lockedCoveringView.updateTheme(presentationData.theme)
|
strongSelf.lockedCoveringView.updateTheme(presentationData.theme)
|
||||||
strongSelf.rootController.updateTheme(NavigationControllerTheme(presentationTheme: presentationData.theme))
|
strongSelf.rootController.updateTheme(NavigationControllerTheme(presentationTheme: presentationData.theme))
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
#endif
|
#endif
|
||||||
self.codeField.textField.returnKeyType = .done
|
self.codeField.textField.returnKeyType = .done
|
||||||
self.codeField.textField.textColor = self.theme.list.itemPrimaryTextColor
|
self.codeField.textField.textColor = self.theme.list.itemPrimaryTextColor
|
||||||
self.codeField.textField.keyboardAppearance = self.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.codeField.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
||||||
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.codeField.textField.textAlignment = .natural
|
self.codeField.textField.textAlignment = .natural
|
||||||
self.codeField.textField.isSecureTextEntry = true
|
self.codeField.textField.isSecureTextEntry = true
|
||||||
self.codeField.textField.returnKeyType = .done
|
self.codeField.textField.returnKeyType = .done
|
||||||
self.codeField.textField.keyboardAppearance = self.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.codeField.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
||||||
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ final class AuthorizationSequencePasswordRecoveryControllerNode: ASDisplayNode,
|
|||||||
self.codeField.textField.textAlignment = .center
|
self.codeField.textField.textAlignment = .center
|
||||||
self.codeField.textField.attributedPlaceholder = NSAttributedString(string: self.strings.TwoStepAuth_RecoveryCode, font: Font.regular(20.0), textColor: self.theme.list.itemPlaceholderTextColor)
|
self.codeField.textField.attributedPlaceholder = NSAttributedString(string: self.strings.TwoStepAuth_RecoveryCode, font: Font.regular(20.0), textColor: self.theme.list.itemPlaceholderTextColor)
|
||||||
self.codeField.textField.returnKeyType = .done
|
self.codeField.textField.returnKeyType = .done
|
||||||
self.codeField.textField.keyboardAppearance = self.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.codeField.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
||||||
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
|
|
||||||
|
@ -103,8 +103,8 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.countryButton)
|
self.addSubnode(self.countryButton)
|
||||||
self.addSubnode(self.phoneInputNode)
|
self.addSubnode(self.phoneInputNode)
|
||||||
|
|
||||||
self.phoneInputNode.countryCodeField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneInputNode.countryCodeField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.phoneInputNode.numberField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.phoneInputNode.numberField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.phoneInputNode.countryCodeField.textField.textColor = theme.list.itemPrimaryTextColor
|
self.phoneInputNode.countryCodeField.textField.textColor = theme.list.itemPrimaryTextColor
|
||||||
self.phoneInputNode.numberField.textField.textColor = theme.list.itemPrimaryTextColor
|
self.phoneInputNode.numberField.textField.textColor = theme.list.itemPrimaryTextColor
|
||||||
self.phoneInputNode.countryCodeField.textField.tintColor = theme.list.itemAccentColor
|
self.phoneInputNode.countryCodeField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
@ -108,7 +108,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
||||||
self.firstNameField.textField.textContentType = .givenName
|
self.firstNameField.textField.textContentType = .givenName
|
||||||
}
|
}
|
||||||
self.firstNameField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.firstNameField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.firstNameField.textField.tintColor = theme.list.itemAccentColor
|
self.firstNameField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
self.lastNameField = TextFieldNode()
|
self.lastNameField = TextFieldNode()
|
||||||
@ -122,7 +122,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
||||||
self.lastNameField.textField.textContentType = .familyName
|
self.lastNameField.textField.textContentType = .familyName
|
||||||
}
|
}
|
||||||
self.lastNameField.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.lastNameField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.lastNameField.textField.tintColor = theme.list.itemAccentColor
|
self.lastNameField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
self.currentPhotoNode = ASImageNode()
|
self.currentPhotoNode = ASImageNode()
|
||||||
|
@ -2769,7 +2769,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.chatDisplayNode.updateTypingActivity = { [weak self] value in
|
self.chatDisplayNode.updateTypingActivity = { [weak self] value in
|
||||||
if let strongSelf = self, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil {
|
if let strongSelf = self, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil && !strongSelf.presentationInterfaceState.isScheduledMessages {
|
||||||
if value {
|
if value {
|
||||||
strongSelf.typingActivityPromise.set(Signal<Bool, NoError>.single(true)
|
strongSelf.typingActivityPromise.set(Signal<Bool, NoError>.single(true)
|
||||||
|> then(
|
|> then(
|
||||||
@ -5155,7 +5155,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
ActionSheetButtonItem(title: self.presentationData.strings.Conversation_FileICloudDrive, action: { [weak self, weak actionSheet] in
|
ActionSheetButtonItem(title: self.presentationData.strings.Conversation_FileICloudDrive, action: { [weak self, weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.present(legacyICloudFileController(theme: strongSelf.presentationData.theme, completion: { urls in
|
strongSelf.present(legacyICloudFilePicker(theme: strongSelf.presentationData.theme, completion: { urls in
|
||||||
if let strongSelf = self, !urls.isEmpty {
|
if let strongSelf = self, !urls.isEmpty {
|
||||||
var signals: [Signal<ICloudFileDescription?, NoError>] = []
|
var signals: [Signal<ICloudFileDescription?, NoError>] = []
|
||||||
for url in urls {
|
for url in urls {
|
||||||
|
@ -186,7 +186,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
|||||||
self.effectView = UIVisualEffectView()
|
self.effectView = UIVisualEffectView()
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
} else {
|
} else {
|
||||||
if self.presentationData.theme.chatList.searchBarKeyboardColor == .dark {
|
if self.presentationData.theme.rootController.keyboardColor == .dark {
|
||||||
self.effectView.effect = UIBlurEffect(style: .dark)
|
self.effectView.effect = UIBlurEffect(style: .dark)
|
||||||
} else {
|
} else {
|
||||||
self.effectView.effect = UIBlurEffect(style: .light)
|
self.effectView.effect = UIBlurEffect(style: .light)
|
||||||
@ -310,7 +310,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
|||||||
|
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
} else {
|
} else {
|
||||||
if self.presentationData.theme.chatList.searchBarKeyboardColor == .dark {
|
if self.presentationData.theme.rootController.keyboardColor == .dark {
|
||||||
self.effectView.effect = UIBlurEffect(style: .dark)
|
self.effectView.effect = UIBlurEffect(style: .dark)
|
||||||
} else {
|
} else {
|
||||||
self.effectView.effect = UIBlurEffect(style: .light)
|
self.effectView.effect = UIBlurEffect(style: .light)
|
||||||
|
@ -502,7 +502,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
textColor = presentationInterfaceState.theme.chat.inputPanel.inputTextColor
|
textColor = presentationInterfaceState.theme.chat.inputPanel.inputTextColor
|
||||||
tintColor = presentationInterfaceState.theme.list.itemAccentColor
|
tintColor = presentationInterfaceState.theme.list.itemAccentColor
|
||||||
baseFontSize = max(17.0, presentationInterfaceState.fontSize.baseDisplaySize)
|
baseFontSize = max(17.0, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||||
keyboardAppearance = presentationInterfaceState.theme.chat.inputPanel.keyboardColor.keyboardAppearance
|
keyboardAppearance = presentationInterfaceState.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
}
|
}
|
||||||
|
|
||||||
let paragraphStyle = NSMutableParagraphStyle()
|
let paragraphStyle = NSMutableParagraphStyle()
|
||||||
@ -691,7 +691,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyboardAppearance = interfaceState.theme.chat.inputPanel.keyboardColor.keyboardAppearance
|
let keyboardAppearance = interfaceState.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
if let textInputNode = self.textInputNode, textInputNode.keyboardAppearance != keyboardAppearance, textInputNode.isFirstResponder() {
|
if let textInputNode = self.textInputNode, textInputNode.keyboardAppearance != keyboardAppearance, textInputNode.isFirstResponder() {
|
||||||
if textInputNode.isCurrentlyEmoji() {
|
if textInputNode.isCurrentlyEmoji() {
|
||||||
textInputNode.initialPrimaryLanguage = "emoji"
|
textInputNode.initialPrimaryLanguage = "emoji"
|
||||||
|
@ -52,7 +52,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
self.textInputNode.clipsToBounds = true
|
self.textInputNode.clipsToBounds = true
|
||||||
self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0)
|
self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0)
|
||||||
self.textInputNode.textContainerInset = UIEdgeInsets(top: self.inputInsets.top, left: 0.0, bottom: self.inputInsets.bottom, right: 0.0)
|
self.textInputNode.textContainerInset = UIEdgeInsets(top: self.inputInsets.top, left: 0.0, bottom: self.inputInsets.bottom, right: 0.0)
|
||||||
self.textInputNode.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textInputNode.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textInputNode.keyboardType = .URL
|
self.textInputNode.keyboardType = .URL
|
||||||
self.textInputNode.autocapitalizationType = .none
|
self.textInputNode.autocapitalizationType = .none
|
||||||
self.textInputNode.returnKeyType = .done
|
self.textInputNode.returnKeyType = .done
|
||||||
@ -77,7 +77,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 33.0, color: self.theme.actionSheet.inputHollowBackgroundColor, strokeColor: self.theme.actionSheet.inputBorderColor, strokeWidth: 1.0)
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 33.0, color: self.theme.actionSheet.inputHollowBackgroundColor, strokeColor: self.theme.actionSheet.inputBorderColor, strokeWidth: 1.0)
|
||||||
self.textInputNode.keyboardAppearance = self.theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textInputNode.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.placeholderNode.attributedText = NSAttributedString(string: self.placeholderNode.attributedText?.string ?? "", font: Font.regular(17.0), textColor: self.theme.actionSheet.inputPlaceholderColor)
|
self.placeholderNode.attributedText = NSAttributedString(string: self.placeholderNode.attributedText?.string ?? "", font: Font.regular(17.0), textColor: self.theme.actionSheet.inputPlaceholderColor)
|
||||||
self.textInputNode.tintColor = self.theme.actionSheet.controlAccentColor
|
self.textInputNode.tintColor = self.theme.actionSheet.controlAccentColor
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.contactListNode = ContactListNode(context: context, presentation: .single(.natural(options: options, includeChatList: includeChatList)), filters: filters, selectionState: ContactListNodeGroupSelectionState())
|
self.contactListNode = ContactListNode(context: context, presentation: .single(.natural(options: options, includeChatList: includeChatList)), filters: filters, selectionState: ContactListNodeGroupSelectionState())
|
||||||
self.tokenListNode = EditableTokenListNode(theme: EditableTokenListNodeTheme(backgroundColor: self.presentationData.theme.rootController.navigationBar.backgroundColor, separatorColor: self.presentationData.theme.rootController.navigationBar.separatorColor, placeholderTextColor: self.presentationData.theme.list.itemPlaceholderTextColor, primaryTextColor: self.presentationData.theme.list.itemPrimaryTextColor, selectedTextColor: self.presentationData.theme.list.itemAccentColor, accentColor: self.presentationData.theme.list.itemAccentColor, keyboardColor: self.presentationData.theme.chatList.searchBarKeyboardColor), placeholder: placeholder)
|
self.tokenListNode = EditableTokenListNode(theme: EditableTokenListNodeTheme(backgroundColor: self.presentationData.theme.rootController.navigationBar.backgroundColor, separatorColor: self.presentationData.theme.rootController.navigationBar.separatorColor, placeholderTextColor: self.presentationData.theme.list.itemPlaceholderTextColor, primaryTextColor: self.presentationData.theme.list.itemPrimaryTextColor, selectedTextColor: self.presentationData.theme.list.itemAccentColor, accentColor: self.presentationData.theme.list.itemAccentColor, keyboardColor: self.presentationData.theme.rootController.keyboardColor), placeholder: placeholder)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ class PaneSearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
self.iconNode.image = generateLoupeIcon(color: theme.chat.inputMediaPanel.stickersSearchControlColor)
|
self.iconNode.image = generateLoupeIcon(color: theme.chat.inputMediaPanel.stickersSearchControlColor)
|
||||||
self.clearButton.setImage(generateClearIcon(color: theme.chat.inputMediaPanel.stickersSearchControlColor), for: [])
|
self.clearButton.setImage(generateClearIcon(color: theme.chat.inputMediaPanel.stickersSearchControlColor), for: [])
|
||||||
self.cancelButton.setAttributedTitle(NSAttributedString(string: strings.Common_Cancel, font: Font.regular(17.0), textColor: theme.chat.inputPanel.panelControlAccentColor), for: [])
|
self.cancelButton.setAttributedTitle(NSAttributedString(string: strings.Common_Cancel, font: Font.regular(17.0), textColor: theme.chat.inputPanel.panelControlAccentColor), for: [])
|
||||||
self.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
self.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textField.tintColor = theme.list.itemAccentColor
|
self.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
|
||||||
if let (boundingSize, leftInset, rightInset) = self.validLayout {
|
if let (boundingSize, leftInset, rightInset) = self.validLayout {
|
||||||
|
Binary file not shown.
@ -62,7 +62,6 @@
|
|||||||
09FFBCD72281BB2D00C33B4B /* ChatTextLinkEditController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09FFBCD62281BB2D00C33B4B /* ChatTextLinkEditController.swift */; };
|
09FFBCD72281BB2D00C33B4B /* ChatTextLinkEditController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09FFBCD62281BB2D00C33B4B /* ChatTextLinkEditController.swift */; };
|
||||||
D000CABC21F158AD0011B15D /* PrepareSecretThumbnailData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D000CABB21F158AD0011B15D /* PrepareSecretThumbnailData.swift */; };
|
D000CABC21F158AD0011B15D /* PrepareSecretThumbnailData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D000CABB21F158AD0011B15D /* PrepareSecretThumbnailData.swift */; };
|
||||||
D0068FA821760FA300D1B315 /* StoreDownloadedMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0068FA721760FA300D1B315 /* StoreDownloadedMedia.swift */; };
|
D0068FA821760FA300D1B315 /* StoreDownloadedMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0068FA721760FA300D1B315 /* StoreDownloadedMedia.swift */; };
|
||||||
D007019C2029E8F2006B9E34 /* LegacyICloudFileController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D007019B2029E8F2006B9E34 /* LegacyICloudFileController.swift */; };
|
|
||||||
D007019E2029EFDD006B9E34 /* ICloudResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = D007019D2029EFDD006B9E34 /* ICloudResources.swift */; };
|
D007019E2029EFDD006B9E34 /* ICloudResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = D007019D2029EFDD006B9E34 /* ICloudResources.swift */; };
|
||||||
D008178222B47464008A895F /* NotificationContentContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D008178122B47464008A895F /* NotificationContentContext.swift */; };
|
D008178222B47464008A895F /* NotificationContentContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D008178122B47464008A895F /* NotificationContentContext.swift */; };
|
||||||
D00817D022B47A14008A895F /* WakeupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00817B622B47A12008A895F /* WakeupManager.swift */; };
|
D00817D022B47A14008A895F /* WakeupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00817B622B47A12008A895F /* WakeupManager.swift */; };
|
||||||
@ -634,7 +633,6 @@
|
|||||||
D002A0DA1E9C190700A81812 /* SoftwareVideoThumbnailLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SoftwareVideoThumbnailLayer.swift; sourceTree = "<group>"; };
|
D002A0DA1E9C190700A81812 /* SoftwareVideoThumbnailLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SoftwareVideoThumbnailLayer.swift; sourceTree = "<group>"; };
|
||||||
D002A0DC1E9CD52A00A81812 /* ChatMediaInputRecentGifsItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMediaInputRecentGifsItem.swift; sourceTree = "<group>"; };
|
D002A0DC1E9CD52A00A81812 /* ChatMediaInputRecentGifsItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMediaInputRecentGifsItem.swift; sourceTree = "<group>"; };
|
||||||
D0068FA721760FA300D1B315 /* StoreDownloadedMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreDownloadedMedia.swift; sourceTree = "<group>"; };
|
D0068FA721760FA300D1B315 /* StoreDownloadedMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreDownloadedMedia.swift; sourceTree = "<group>"; };
|
||||||
D007019B2029E8F2006B9E34 /* LegacyICloudFileController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyICloudFileController.swift; sourceTree = "<group>"; };
|
|
||||||
D007019D2029EFDD006B9E34 /* ICloudResources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudResources.swift; sourceTree = "<group>"; };
|
D007019D2029EFDD006B9E34 /* ICloudResources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudResources.swift; sourceTree = "<group>"; };
|
||||||
D008178122B47464008A895F /* NotificationContentContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContentContext.swift; sourceTree = "<group>"; };
|
D008178122B47464008A895F /* NotificationContentContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContentContext.swift; sourceTree = "<group>"; };
|
||||||
D00817B622B47A12008A895F /* WakeupManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WakeupManager.swift; sourceTree = "<group>"; };
|
D00817B622B47A12008A895F /* WakeupManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WakeupManager.swift; sourceTree = "<group>"; };
|
||||||
@ -1740,7 +1738,6 @@
|
|||||||
children = (
|
children = (
|
||||||
D00E15251DDBD4E700ACF65C /* LegacyCamera.swift */,
|
D00E15251DDBD4E700ACF65C /* LegacyCamera.swift */,
|
||||||
D06BB8811F58994B0084FC30 /* LegacyInstantVideoController.swift */,
|
D06BB8811F58994B0084FC30 /* LegacyInstantVideoController.swift */,
|
||||||
D007019B2029E8F2006B9E34 /* LegacyICloudFileController.swift */,
|
|
||||||
D0380DAC204ED434000414AB /* LegacyLiveUploadInterface.swift */,
|
D0380DAC204ED434000414AB /* LegacyLiveUploadInterface.swift */,
|
||||||
D0B21B1E22156D92003F741D /* LegacyCache.swift */,
|
D0B21B1E22156D92003F741D /* LegacyCache.swift */,
|
||||||
);
|
);
|
||||||
@ -3064,7 +3061,6 @@
|
|||||||
090B48C82200BCA8005083FA /* WallpaperUploadManager.swift in Sources */,
|
090B48C82200BCA8005083FA /* WallpaperUploadManager.swift in Sources */,
|
||||||
09F2158D225CF5BC00AEDF6D /* Pasteboard.swift in Sources */,
|
09F2158D225CF5BC00AEDF6D /* Pasteboard.swift in Sources */,
|
||||||
D0C26D571FDF2388004ABF18 /* OpenChatMessage.swift in Sources */,
|
D0C26D571FDF2388004ABF18 /* OpenChatMessage.swift in Sources */,
|
||||||
D007019C2029E8F2006B9E34 /* LegacyICloudFileController.swift in Sources */,
|
|
||||||
D000CABC21F158AD0011B15D /* PrepareSecretThumbnailData.swift in Sources */,
|
D000CABC21F158AD0011B15D /* PrepareSecretThumbnailData.swift in Sources */,
|
||||||
D08BDF641FA37BEA009D08E1 /* ChatRecordingPreviewInputPanelNode.swift in Sources */,
|
D08BDF641FA37BEA009D08E1 /* ChatRecordingPreviewInputPanelNode.swift in Sources */,
|
||||||
D0943B071FDEC529001522CC /* InstantVideoRadialStatusNode.swift in Sources */,
|
D0943B071FDEC529001522CC /* InstantVideoRadialStatusNode.swift in Sources */,
|
||||||
|
@ -56,10 +56,42 @@ public struct PresentationLocalTheme: PostboxCoding, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct PresentationCloudTheme: PostboxCoding, Equatable {
|
||||||
|
public let theme: TelegramTheme
|
||||||
|
public let resolvedWallpaper: TelegramWallpaper?
|
||||||
|
|
||||||
|
public init(theme: TelegramTheme, resolvedWallpaper: TelegramWallpaper?) {
|
||||||
|
self.theme = theme
|
||||||
|
self.resolvedWallpaper = resolvedWallpaper
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: PostboxDecoder) {
|
||||||
|
self.theme = decoder.decodeObjectForKey("theme", decoder: { TelegramTheme(decoder: $0) }) as! TelegramTheme
|
||||||
|
self.resolvedWallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeObject(self.theme, forKey: "theme")
|
||||||
|
if let resolvedWallpaper = self.resolvedWallpaper {
|
||||||
|
encoder.encodeObject(resolvedWallpaper, forKey: "wallpaper")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: PresentationCloudTheme, rhs: PresentationCloudTheme) -> Bool {
|
||||||
|
if lhs.theme != rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.resolvedWallpaper != rhs.resolvedWallpaper {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum PresentationThemeReference: PostboxCoding, Equatable {
|
public enum PresentationThemeReference: PostboxCoding, Equatable {
|
||||||
case builtin(PresentationBuiltinThemeReference)
|
case builtin(PresentationBuiltinThemeReference)
|
||||||
case local(PresentationLocalTheme)
|
case local(PresentationLocalTheme)
|
||||||
case cloud(TelegramTheme)
|
case cloud(PresentationCloudTheme)
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
switch decoder.decodeInt32ForKey("v", orElse: 0) {
|
switch decoder.decodeInt32ForKey("v", orElse: 0) {
|
||||||
@ -68,7 +100,7 @@ public enum PresentationThemeReference: PostboxCoding, Equatable {
|
|||||||
case 1:
|
case 1:
|
||||||
self = .local(decoder.decodeObjectForKey("localTheme", decoder: { PresentationLocalTheme(decoder: $0) }) as! PresentationLocalTheme)
|
self = .local(decoder.decodeObjectForKey("localTheme", decoder: { PresentationLocalTheme(decoder: $0) }) as! PresentationLocalTheme)
|
||||||
case 2:
|
case 2:
|
||||||
self = .cloud(decoder.decodeObjectForKey("theme", decoder: { TelegramTheme(decoder: $0) }) as! TelegramTheme)
|
self = .cloud(decoder.decodeObjectForKey("cloudTheme", decoder: { PresentationCloudTheme(decoder: $0) }) as! PresentationCloudTheme)
|
||||||
default:
|
default:
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
self = .builtin(.dayClassic)
|
self = .builtin(.dayClassic)
|
||||||
@ -85,7 +117,7 @@ public enum PresentationThemeReference: PostboxCoding, Equatable {
|
|||||||
encoder.encodeObject(theme, forKey: "localTheme")
|
encoder.encodeObject(theme, forKey: "localTheme")
|
||||||
case let .cloud(theme):
|
case let .cloud(theme):
|
||||||
encoder.encodeInt32(2, forKey: "v")
|
encoder.encodeInt32(2, forKey: "v")
|
||||||
encoder.encodeObject(theme, forKey: "theme")
|
encoder.encodeObject(theme, forKey: "cloudTheme")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +167,7 @@ public enum PresentationThemeReference: PostboxCoding, Equatable {
|
|||||||
id = themeId(for: theme.resource.fileId)
|
id = themeId(for: theme.resource.fileId)
|
||||||
case let .cloud(theme):
|
case let .cloud(theme):
|
||||||
namespace = 2
|
namespace = 2
|
||||||
id = themeId(for: theme.id)
|
id = themeId(for: theme.theme.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Int64(namespace) << 32) | Int64(bitPattern: UInt64(UInt32(bitPattern: id)))
|
return (Int64(namespace) << 32) | Int64(bitPattern: UInt64(UInt32(bitPattern: id)))
|
||||||
@ -379,9 +411,12 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
|||||||
case let .local(theme):
|
case let .local(theme):
|
||||||
resources.append(theme.resource.id)
|
resources.append(theme.resource.id)
|
||||||
case let .cloud(theme):
|
case let .cloud(theme):
|
||||||
if let file = theme.file {
|
if let file = theme.theme.file {
|
||||||
resources.append(file.resource.id)
|
resources.append(file.resource.id)
|
||||||
}
|
}
|
||||||
|
if let chatWallpaper = theme.resolvedWallpaper {
|
||||||
|
resources.append(contentsOf: wallpaperResources(chatWallpaper))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return resources
|
return resources
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user