mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-06 17:00:13 +00:00
Animation updates
This commit is contained in:
parent
e170f2fe5a
commit
904b048a34
@ -6573,3 +6573,12 @@ Sorry for the inconvenience.";
|
||||
|
||||
"PlaybackSpeed.Title" = "Playback Speed";
|
||||
"PlaybackSpeed.Normal" = "Normal";
|
||||
|
||||
"Chat.NextChannelSameLocationSwipeProgress" = "Swipe up to go to the next unread channel";
|
||||
"Chat.NextChannelSameLocationSwipeAction" = "Release to go to the next unread channel";
|
||||
"Chat.NextChannelFolderSwipeProgress" = "Swipe up to go to the %@ folder";
|
||||
"Chat.NextChannelFolderSwipeAction" = "Release to go to the %@ folder";
|
||||
"Chat.NextChannelArchivedSwipeProgress" = "Swipe up to go to archived channels";
|
||||
"Chat.NextChannelArchivedSwipeAction" = "Release to go to archived channels";
|
||||
"Chat.NextChannelUnarchivedSwipeProgress" = "Swipe up to go to unarchived channels";
|
||||
"Chat.NextChannelUnarchivedSwipeAction" = "Release to go to unarchived channels";
|
||||
|
||||
@ -289,10 +289,10 @@ public final class NavigateToChatControllerParams {
|
||||
public let animated: Bool
|
||||
public let options: NavigationAnimationOptions
|
||||
public let parentGroupId: PeerGroupId?
|
||||
public let chatListFilter: ChatListFilterData?
|
||||
public let chatListFilter: Int32?
|
||||
public let completion: (ChatController) -> Void
|
||||
|
||||
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: ChatListFilterData? = nil, completion: @escaping (ChatController) -> Void = { _ in }) {
|
||||
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, completion: @escaping (ChatController) -> Void = { _ in }) {
|
||||
self.navigationController = navigationController
|
||||
self.chatController = chatController
|
||||
self.chatLocationContextHolder = chatLocationContextHolder
|
||||
|
||||
@ -46,6 +46,8 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco
|
||||
|
||||
private let hierarchyTrackingNode: HierarchyTrackingNode
|
||||
private var isCurrentlyInHierarchy = true
|
||||
|
||||
public var isManuallyInHierarchy: Bool?
|
||||
|
||||
private var audioLevel: CGFloat = 0
|
||||
public var presentationAudioLevel: CGFloat = 0
|
||||
@ -136,6 +138,9 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco
|
||||
}
|
||||
|
||||
public func setColor(_ color: UIColor, animated: Bool) {
|
||||
if let isManuallyInHierarchy = self.isManuallyInHierarchy, !isManuallyInHierarchy {
|
||||
return
|
||||
}
|
||||
smallBlob.setColor(color, animated: animated)
|
||||
mediumBlob.setColor(color.withAlphaComponent(0.3), animated: animated)
|
||||
bigBlob.setColor(color.withAlphaComponent(0.15), animated: animated)
|
||||
|
||||
@ -612,7 +612,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
scrollToEndIfExists = true
|
||||
}
|
||||
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), activateInput: activateInput && !peer.isDeleted, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [], parentGroupId: strongSelf.groupId, chatListFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter?.data, completion: { [weak self] controller in
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), activateInput: activateInput && !peer.isDeleted, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [], parentGroupId: strongSelf.groupId, chatListFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter?.id, completion: { [weak self] controller in
|
||||
self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
||||
if let promoInfo = promoInfo {
|
||||
switch promoInfo {
|
||||
|
||||
@ -175,6 +175,8 @@ public final class _UpdatedChildComponent {
|
||||
var _removed: Bool = false
|
||||
var _position: CGPoint?
|
||||
var _opacity: CGFloat?
|
||||
var _cornerRadius: CGFloat?
|
||||
var _clipsToBounds: Bool?
|
||||
|
||||
fileprivate var transitionAppear: Transition.Appear?
|
||||
fileprivate var transitionAppearWithGuide: (Transition.AppearWithGuide, _AnyChildComponent.Id)?
|
||||
@ -241,6 +243,16 @@ public final class _UpdatedChildComponent {
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult public func cornerRadius(_ cornerRadius: CGFloat) -> _UpdatedChildComponent {
|
||||
self._cornerRadius = cornerRadius
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult public func clipsToBounds(_ clipsToBounds: Bool) -> _UpdatedChildComponent {
|
||||
self._clipsToBounds = clipsToBounds
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult public func gesture(_ gesture: Gesture) -> _UpdatedChildComponent {
|
||||
self.gestures.append(gesture)
|
||||
return self
|
||||
@ -672,6 +684,8 @@ public extension CombinedComponent {
|
||||
|
||||
updatedChild.view.frame = updatedChild.size.centered(around: updatedChild._position ?? CGPoint())
|
||||
updatedChild.view.alpha = updatedChild._opacity ?? 1.0
|
||||
updatedChild.view.clipsToBounds = updatedChild._clipsToBounds ?? false
|
||||
updatedChild.view.layer.cornerRadius = updatedChild._cornerRadius ?? 0.0
|
||||
updatedChild.view.context(typeErasedComponent: updatedChild.component).erasedState._updated = { [weak viewContext] transition in
|
||||
guard let viewContext = viewContext else {
|
||||
return
|
||||
|
||||
@ -300,18 +300,23 @@ public func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> U
|
||||
context.scaleBy(x: 1.0, y: -1.0)
|
||||
context.translateBy(x: -imageRect.midX, y: -imageRect.midY)
|
||||
context.clip(to: imageRect, mask: image.cgImage!)
|
||||
|
||||
let gradientColors = colors.map { $0.cgColor } as CFArray
|
||||
let delta: CGFloat = 1.0 / (CGFloat(colors.count) - 1.0)
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< colors.count {
|
||||
locations.append(delta * CGFloat(i))
|
||||
|
||||
if colors.count >= 2 {
|
||||
let gradientColors = colors.map { $0.cgColor } as CFArray
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< colors.count {
|
||||
let t = CGFloat(i) / CGFloat(colors.count - 1)
|
||||
locations.append(t)
|
||||
}
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
|
||||
} else if !colors.isEmpty {
|
||||
context.setFillColor(colors[0].cgColor)
|
||||
context.fill(imageRect)
|
||||
}
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
|
||||
|
||||
context.restoreGState()
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
let baseColor: UIColor
|
||||
let lightness = color.lightness
|
||||
if lightness < 0.1 || lightness > 0.9 {
|
||||
baseColor = self.theme.chat.message.outgoing.bubble.withoutWallpaper.fill
|
||||
baseColor = self.theme.chat.message.outgoing.bubble.withoutWallpaper.fill[0]
|
||||
} else{
|
||||
baseColor = color
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import TelegramUIPreferences
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import WallpaperBackgroundNode
|
||||
|
||||
class ForwardPrivacyChatPreviewItem: ListViewItem, ItemListItem {
|
||||
let context: AccountContext
|
||||
@ -75,7 +76,7 @@ class ForwardPrivacyChatPreviewItem: ListViewItem, ItemListItem {
|
||||
}
|
||||
|
||||
class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
private let backgroundNode: ASImageNode
|
||||
private var backgroundNode: WallpaperBackgroundNode?
|
||||
private let topStripeNode: ASDisplayNode
|
||||
private let bottomStripeNode: ASDisplayNode
|
||||
private let maskNode: ASImageNode
|
||||
@ -91,12 +92,6 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
private var item: ForwardPrivacyChatPreviewItem?
|
||||
|
||||
init() {
|
||||
self.backgroundNode = ASImageNode()
|
||||
self.backgroundNode.isLayerBacked = true
|
||||
self.backgroundNode.displaysAsynchronously = false
|
||||
self.backgroundNode.displayWithoutProcessing = true
|
||||
self.backgroundNode.contentMode = .scaleAspectFill
|
||||
|
||||
self.topStripeNode = ASDisplayNode()
|
||||
self.topStripeNode.isLayerBacked = true
|
||||
|
||||
@ -130,21 +125,17 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: ForwardPrivacyChatPreviewItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||
let currentItem = self.item
|
||||
|
||||
let currentNode = self.messageNode
|
||||
let makeTextLayout = TextNode.asyncLayout(self.measureTextNode)
|
||||
|
||||
var currentBackgroundNode = self.backgroundNode
|
||||
|
||||
return { item, params, neighbors in
|
||||
var updatedBackgroundImage: UIImage?
|
||||
var backgroundImageContentMode = UIView.ContentMode.scaleAspectFill
|
||||
if currentItem?.wallpaper != item.wallpaper {
|
||||
updatedBackgroundImage = chatControllerBackgroundImage(theme: item.theme, wallpaper: item.wallpaper, mediaBox: item.context.sharedContext.accountManager.mediaBox, knockoutMode: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper)
|
||||
|
||||
if case .gradient = item.wallpaper {
|
||||
backgroundImageContentMode = .scaleToFill
|
||||
}
|
||||
if currentBackgroundNode == nil {
|
||||
currentBackgroundNode = WallpaperBackgroundNode(context: item.context)
|
||||
}
|
||||
currentBackgroundNode?.update(wallpaper: item.wallpaper)
|
||||
currentBackgroundNode?.updateBubbleTheme(bubbleTheme: item.theme, bubbleCorners: item.chatBubbleCorners)
|
||||
|
||||
let insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
@ -158,7 +149,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
|
||||
let forwardInfo = MessageForwardInfo(author: item.linkEnabled ? peers[peerId] : nil, source: nil, sourceMessageId: nil, date: 0, authorSignature: item.linkEnabled ? nil : item.peerName, psaType: nil, flags: [])
|
||||
|
||||
let messageItem = item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: forwardInfo, author: nil, text: item.strings.Privacy_Forwards_PreviewMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [])], theme: item.theme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: nil)
|
||||
let messageItem = item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: forwardInfo, author: nil, text: item.strings.Privacy_Forwards_PreviewMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [])], theme: item.theme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode)
|
||||
|
||||
var node: ListViewItemNode?
|
||||
if let current = currentNode {
|
||||
@ -227,17 +218,15 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
node.updateFrame(CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node.frame.size), within: layout.contentSize)
|
||||
topOffset += node.frame.size.height
|
||||
}
|
||||
|
||||
if let updatedBackgroundImage = updatedBackgroundImage {
|
||||
strongSelf.backgroundNode.image = updatedBackgroundImage
|
||||
strongSelf.backgroundNode.contentMode = backgroundImageContentMode
|
||||
}
|
||||
|
||||
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
if strongSelf.backgroundNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
|
||||
|
||||
if let currentBackgroundNode = currentBackgroundNode, strongSelf.backgroundNode !== currentBackgroundNode {
|
||||
strongSelf.backgroundNode = currentBackgroundNode
|
||||
strongSelf.insertSubnode(currentBackgroundNode, at: 0)
|
||||
}
|
||||
|
||||
if strongSelf.topStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
|
||||
}
|
||||
@ -273,7 +262,14 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.backgroundNode.frame = backgroundFrame.insetBy(dx: 0.0, dy: -100.0)
|
||||
|
||||
if let backgroundNode = strongSelf.backgroundNode {
|
||||
backgroundNode.frame = backgroundFrame.insetBy(dx: 0.0, dy: -100.0)
|
||||
backgroundNode.update(wallpaper: item.wallpaper)
|
||||
backgroundNode.updateBubbleTheme(bubbleTheme: item.theme, bubbleCorners: item.chatBubbleCorners)
|
||||
backgroundNode.updateLayout(size: backgroundNode.bounds.size, transition: .immediate)
|
||||
}
|
||||
|
||||
strongSelf.maskNode.frame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
|
||||
@ -14,12 +14,8 @@ import MediaResources
|
||||
private let randomBackgroundColors: [Int32] = [0x007aff, 0x00c2ed, 0x29b327, 0xeb6ca4, 0xf08200, 0x9472ee, 0xd33213, 0xedb400, 0x6d839e]
|
||||
|
||||
extension TelegramThemeSettings {
|
||||
convenience init(baseTheme: TelegramBaseTheme, accentColor: UIColor, messageColors: (top: UIColor, bottom: UIColor?)?, wallpaper: TelegramWallpaper?) {
|
||||
var messageColorsValues: (UInt32, UInt32)?
|
||||
if let colors = messageColors {
|
||||
messageColorsValues = (colors.0.argb, colors.1?.argb ?? colors.0.argb)
|
||||
}
|
||||
self.init(baseTheme: baseTheme, accentColor: accentColor.argb, messageColors: messageColorsValues, wallpaper: wallpaper)
|
||||
convenience init(baseTheme: TelegramBaseTheme, accentColor: UIColor, messageColors: [UInt32], wallpaper: TelegramWallpaper?) {
|
||||
self.init(baseTheme: baseTheme, accentColor: accentColor.argb, messageColors: messageColors, wallpaper: wallpaper)
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,7 +375,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
var backgroundColors: [UInt32] = []
|
||||
var patternWallpaper: TelegramWallpaper?
|
||||
var patternIntensity: Int32 = 50
|
||||
let messageColors: (UIColor, UIColor?)?
|
||||
let messageColors: [UInt32]
|
||||
let defaultMessagesColor: UIColor? = nil
|
||||
var rotation: Int32 = 0
|
||||
|
||||
@ -459,19 +455,15 @@ final class ThemeAccentColorController: ViewController {
|
||||
extractWallpaperParameters(wallpaper)
|
||||
}
|
||||
|
||||
if let bubbleColors = settings.themeSpecificAccentColors[themeReference.index]?.customBubbleColors {
|
||||
if let bottomColor = bubbleColors.1 {
|
||||
messageColors = (bubbleColors.0, bottomColor)
|
||||
} else {
|
||||
messageColors = (bubbleColors.0, nil)
|
||||
}
|
||||
if let bubbleColors = settings.themeSpecificAccentColors[themeReference.index]?.customBubbleColors, !bubbleColors.isEmpty {
|
||||
messageColors = bubbleColors
|
||||
} else {
|
||||
if let themeReference = strongSelf.mode.themeReference, themeReference == .builtin(.dayClassic), settings.themeSpecificAccentColors[themeReference.index] == nil {
|
||||
messageColors = (UIColor(rgb: 0xe1ffc7), nil)
|
||||
messageColors = [UIColor(rgb: 0xe1ffc7).rgb]
|
||||
} else if let referenceTheme = referenceTheme {
|
||||
messageColors = (referenceTheme.chat.message.outgoing.bubble.withoutWallpaper.fill, referenceTheme.chat.message.outgoing.bubble.withoutWallpaper.gradientFill)
|
||||
messageColors = referenceTheme.chat.message.outgoing.bubble.withoutWallpaper.fill.map(\.rgb)
|
||||
} else {
|
||||
messageColors = nil
|
||||
messageColors = []
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -489,16 +481,10 @@ final class ThemeAccentColorController: ViewController {
|
||||
initialWallpaper = wallpaper
|
||||
}
|
||||
|
||||
if let colors = themeSettings.messageColors {
|
||||
let topMessageColor = UIColor(argb: colors.top)
|
||||
let bottomMessageColor = UIColor(argb: colors.bottom)
|
||||
if topMessageColor.argb == bottomMessageColor.argb {
|
||||
messageColors = (topMessageColor, nil)
|
||||
} else {
|
||||
messageColors = (topMessageColor, bottomMessageColor)
|
||||
}
|
||||
if !themeSettings.messageColors.isEmpty {
|
||||
messageColors = themeSettings.messageColors
|
||||
} else {
|
||||
messageColors = nil
|
||||
messageColors = []
|
||||
}
|
||||
} else if case .builtin = themeReference {
|
||||
let themeSpecificAccentColor = settings.themeSpecificAccentColors[themeReference.index]
|
||||
@ -525,17 +511,13 @@ final class ThemeAccentColorController: ViewController {
|
||||
extractWallpaperParameters(wallpaper)
|
||||
}
|
||||
|
||||
if let bubbleColors = settings.themeSpecificAccentColors[themeReference.index]?.customBubbleColors {
|
||||
if let bottomColor = bubbleColors.1 {
|
||||
messageColors = (bubbleColors.0, bottomColor)
|
||||
} else {
|
||||
messageColors = (bubbleColors.0, nil)
|
||||
}
|
||||
if let bubbleColors = settings.themeSpecificAccentColors[themeReference.index]?.customBubbleColors, !bubbleColors.isEmpty {
|
||||
messageColors = bubbleColors
|
||||
} else {
|
||||
if let themeReference = strongSelf.mode.themeReference, themeReference == .builtin(.dayClassic), settings.themeSpecificAccentColors[themeReference.index] == nil {
|
||||
messageColors = (UIColor(rgb: 0xe1ffc7), nil)
|
||||
messageColors = [UIColor(rgb: 0xe1ffc7).rgb]
|
||||
} else {
|
||||
messageColors = nil
|
||||
messageColors = []
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -550,14 +532,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
initialWallpaper = wallpaper
|
||||
}
|
||||
|
||||
let topMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.fill
|
||||
let bottomMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.gradientFill
|
||||
|
||||
if topMessageColor.argb == bottomMessageColor.argb {
|
||||
messageColors = (topMessageColor, nil)
|
||||
} else {
|
||||
messageColors = (topMessageColor, bottomMessageColor)
|
||||
}
|
||||
messageColors = theme.chat.message.outgoing.bubble.withWallpaper.fill.map(\.rgb)
|
||||
}
|
||||
}
|
||||
} else if case let .edit(theme, wallpaper, _, _, _, _) = strongSelf.mode {
|
||||
@ -570,18 +545,11 @@ final class ThemeAccentColorController: ViewController {
|
||||
initialWallpaper = wallpaper
|
||||
}
|
||||
|
||||
let topMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.fill
|
||||
let bottomMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.gradientFill
|
||||
|
||||
if topMessageColor.argb == bottomMessageColor.argb {
|
||||
messageColors = (topMessageColor, nil)
|
||||
} else {
|
||||
messageColors = (topMessageColor, bottomMessageColor)
|
||||
}
|
||||
messageColors = theme.chat.message.outgoing.bubble.withWallpaper.fill.map(\.rgb)
|
||||
} else {
|
||||
accentColor = defaultDayAccentColor
|
||||
backgroundColors = []
|
||||
messageColors = nil
|
||||
messageColors = []
|
||||
}
|
||||
|
||||
let initialState = ThemeColorState(section: strongSelf.section, accentColor: accentColor, initialWallpaper: initialWallpaper, backgroundColors: backgroundColors, patternWallpaper: patternWallpaper, patternIntensity: patternIntensity, defaultMessagesColor: defaultMessagesColor, messagesColors: messageColors, rotation: rotation)
|
||||
|
||||
@ -49,7 +49,7 @@ struct ThemeColorState {
|
||||
var patternIntensity: Int32
|
||||
|
||||
var defaultMessagesColor: UIColor?
|
||||
var messagesColors: (UIColor, UIColor?)?
|
||||
var messagesColors: [UInt32]
|
||||
|
||||
var rotation: Int32
|
||||
|
||||
@ -65,11 +65,11 @@ struct ThemeColorState {
|
||||
self.patternWallpaper = nil
|
||||
self.patternIntensity = 50
|
||||
self.defaultMessagesColor = nil
|
||||
self.messagesColors = nil
|
||||
self.messagesColors = []
|
||||
self.rotation = 0
|
||||
}
|
||||
|
||||
init(section: ThemeColorSection, accentColor: UIColor, initialWallpaper: TelegramWallpaper?, backgroundColors: [UInt32], patternWallpaper: TelegramWallpaper?, patternIntensity: Int32, defaultMessagesColor: UIColor?, messagesColors: (UIColor, UIColor?)?, rotation: Int32 = 0) {
|
||||
init(section: ThemeColorSection, accentColor: UIColor, initialWallpaper: TelegramWallpaper?, backgroundColors: [UInt32], patternWallpaper: TelegramWallpaper?, patternIntensity: Int32, defaultMessagesColor: UIColor?, messagesColors: [UInt32], rotation: Int32 = 0) {
|
||||
self.section = section
|
||||
self.colorPanelCollapsed = false
|
||||
self.displayPatternPanel = false
|
||||
@ -105,20 +105,10 @@ struct ThemeColorState {
|
||||
return false
|
||||
}
|
||||
|
||||
if let lhsMessagesColors = self.messagesColors, let rhsMessagesColors = otherState.messagesColors {
|
||||
if lhsMessagesColors.0 != rhsMessagesColors.0 {
|
||||
return false
|
||||
}
|
||||
if let lhsSecondColor = lhsMessagesColors.1, let rhsSecondColor = rhsMessagesColors.1 {
|
||||
if lhsSecondColor != rhsSecondColor {
|
||||
return false
|
||||
}
|
||||
} else if (lhsMessagesColors.1 == nil) != (rhsMessagesColors.1 == nil) {
|
||||
return false
|
||||
}
|
||||
} else if (self.messagesColors == nil) != (otherState.messagesColors == nil) {
|
||||
if self.messagesColors != otherState.messagesColors {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -347,11 +337,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
case .background:
|
||||
updated.backgroundColors = colors
|
||||
case .messages:
|
||||
if colors.count >= 1 {
|
||||
updated.messagesColors = (UIColor(rgb: colors[0]), colors.count >= 2 ? UIColor(rgb: colors[1]) : nil)
|
||||
} else {
|
||||
updated.messagesColors = nil
|
||||
}
|
||||
updated.messagesColors = colors
|
||||
}
|
||||
return updated
|
||||
})
|
||||
@ -662,12 +648,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
} else {
|
||||
defaultColor = self.state.accentColor
|
||||
}
|
||||
if let messagesColors = self.state.messagesColors {
|
||||
if let second = messagesColors.1 {
|
||||
colors = [messagesColors.0.rgb, second.rgb]
|
||||
} else {
|
||||
colors = [messagesColors.0.rgb]
|
||||
}
|
||||
if !self.state.messagesColors.isEmpty {
|
||||
colors = self.state.messagesColors
|
||||
} else {
|
||||
colors = []
|
||||
}
|
||||
@ -684,7 +666,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
case .background:
|
||||
maximumNumberOfColors = 4
|
||||
case .messages:
|
||||
maximumNumberOfColors = 2
|
||||
maximumNumberOfColors = 4
|
||||
default:
|
||||
maximumNumberOfColors = 1
|
||||
}
|
||||
@ -900,10 +882,10 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
}
|
||||
strongSelf.updateState({ state in
|
||||
var state = state
|
||||
if state.section == .background {
|
||||
//if state.section == .background {
|
||||
state.colorPanelCollapsed = true
|
||||
state.displayPatternPanel = false
|
||||
}
|
||||
//}
|
||||
return state
|
||||
}, animated: true)
|
||||
/*if message.flags.contains(.Incoming) {
|
||||
|
||||
@ -10,37 +10,37 @@ private func patternWallpaper(data: BuiltinWallpaperData, colors: [UInt32], inte
|
||||
|
||||
var dayClassicColorPresets: [PresentationThemeAccentColor] = [
|
||||
// Pink with Blue
|
||||
PresentationThemeAccentColor(index: 106, baseColor: .preset, accentColor: 0xfff55783, bubbleColors: (0xffd6f5ff, 0xffc9fdfe), wallpaper: patternWallpaper(data: .default, colors: [0x8dc0eb, 0xb9d1ea, 0xc6b1ef, 0xebd7ef], intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 106, baseColor: .preset, accentColor: 0xfff55783, bubbleColors: [0xffd6f5ff, 0xffc9fdfe], wallpaper: patternWallpaper(data: .default, colors: [0x8dc0eb, 0xb9d1ea, 0xc6b1ef, 0xebd7ef], intensity: 50, rotation: nil)),
|
||||
|
||||
// Pink with Gold
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0xFFFF5FA9, bubbleColors: (0xFFFFF4D7, nil), wallpaper: patternWallpaper(data: .variant12, colors: [0xeaa36e, 0xf0e486, 0xf29ebf, 0xe8c06e], intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0xFFFF5FA9, bubbleColors: [0xFFFFF4D7], wallpaper: patternWallpaper(data: .variant12, colors: [0xeaa36e, 0xf0e486, 0xf29ebf, 0xe8c06e], intensity: 50, rotation: nil)),
|
||||
|
||||
// Green
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xFF5A9E29, bubbleColors: (0xffFFF8DF, nil), wallpaper: patternWallpaper(data: .variant13, colors: [0x7fc289, 0xe4d573, 0xafd677, 0xf0c07a], intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xFF5A9E29, bubbleColors: [0xffFFF8DF], wallpaper: patternWallpaper(data: .variant13, colors: [0x7fc289, 0xe4d573, 0xafd677, 0xf0c07a], intensity: 50, rotation: nil)),
|
||||
|
||||
// Purple
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0xFF7E5FE5, bubbleColors: (0xFFF5e2FF, nil), wallpaper: patternWallpaper(data: .variant14, colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0xFF7E5FE5, bubbleColors: [0xFFF5e2FF], wallpaper: patternWallpaper(data: .variant14, colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: 50, rotation: nil)),
|
||||
|
||||
// Light Blue
|
||||
PresentationThemeAccentColor(index: 107, baseColor: .preset, accentColor: 0xFF2CB9ED, bubbleColors: (0xFFADF7B5, 0xFFFCFF8B), wallpaper: patternWallpaper(data: .variant3, colors: [0x1a2e1a, 0x47623c, 0x222e24, 0x314429], intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 107, baseColor: .preset, accentColor: 0xFF2CB9ED, bubbleColors: [0xFFADF7B5, 0xFFFCFF8B], wallpaper: patternWallpaper(data: .variant3, colors: [0x1a2e1a, 0x47623c, 0x222e24, 0x314429], intensity: 50, rotation: nil)),
|
||||
|
||||
// Mint
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xFF199972, bubbleColors: (0xFFFFFEC7, nil), wallpaper: patternWallpaper(data: .variant3, colors: [0xdceb92, 0x8fe1d6, 0x67a3f2, 0x85d685], intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xFF199972, bubbleColors: [0xFFFFFEC7], wallpaper: patternWallpaper(data: .variant3, colors: [0xdceb92, 0x8fe1d6, 0x67a3f2, 0x85d685], intensity: 50, rotation: nil)),
|
||||
|
||||
// Pink with Green
|
||||
PresentationThemeAccentColor(index: 105, baseColor: .preset, accentColor: 0xFFDA90D9, bubbleColors: (0xFF94FFF9, 0xFFCCFFC7), wallpaper: patternWallpaper(data: .variant9, colors: [0xffc3b2, 0xe2c0ff, 0xffe7b2], intensity: 50, rotation: nil))
|
||||
PresentationThemeAccentColor(index: 105, baseColor: .preset, accentColor: 0xFFDA90D9, bubbleColors: [0xFF94FFF9, 0xFFCCFFC7], wallpaper: patternWallpaper(data: .variant9, colors: [0xffc3b2, 0xe2c0ff, 0xffe7b2], intensity: 50, rotation: nil))
|
||||
]
|
||||
|
||||
var dayColorPresets: [PresentationThemeAccentColor] = [
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0x007aff, bubbleColors: (0x007aff, 0xff53f4), wallpaper: nil),
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0x00b09b, bubbleColors: (0xaee946, 0x00b09b), wallpaper: nil),
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xd33213, bubbleColors: (0xf9db00, 0xd33213), wallpaper: nil),
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xea8ced, bubbleColors: (0xea8ced, 0x00c2ed), wallpaper: nil)
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0x007aff, bubbleColors: [0x007aff, 0xff53f4], wallpaper: nil),
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0x00b09b, bubbleColors: [0xaee946, 0x00b09b], wallpaper: nil),
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xd33213, bubbleColors: [0xf9db00, 0xd33213], wallpaper: nil),
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xea8ced, bubbleColors: [0xea8ced, 0x00c2ed], wallpaper: nil)
|
||||
]
|
||||
|
||||
var nightColorPresets: [PresentationThemeAccentColor] = [
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0x007aff, bubbleColors: (0x007aff, 0xff53f4), wallpaper: patternWallpaper(data: .variant4, colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: -35, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0x00b09b, bubbleColors: (0xaee946, 0x00b09b), wallpaper: patternWallpaper(data: .variant9, colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: -35, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xd33213, bubbleColors: (0xf9db00, 0xd33213), wallpaper: patternWallpaper(data: .variant2, colors: [0xfec496, 0xdd6cb9, 0x962fbf, 0x4f5bd5], intensity: -40, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xea8ced, bubbleColors: (0xea8ced, 0x00c2ed), wallpaper: patternWallpaper(data: .variant6, colors: [0x8adbf2, 0x888dec, 0xe39fea, 0x679ced], intensity: -30, rotation: nil))
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0x007aff, bubbleColors: [0x007aff, 0xff53f4], wallpaper: patternWallpaper(data: .variant4, colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: -35, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0x00b09b, bubbleColors: [0xaee946, 0x00b09b], wallpaper: patternWallpaper(data: .variant9, colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: -35, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xd33213, bubbleColors: [0xf9db00, 0xd33213], wallpaper: patternWallpaper(data: .variant2, colors: [0xfec496, 0xdd6cb9, 0x962fbf, 0x4f5bd5], intensity: -40, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xea8ced, bubbleColors: [0xea8ced, 0x00c2ed], wallpaper: patternWallpaper(data: .variant6, colors: [0x8adbf2, 0x888dec, 0xe39fea, 0x679ced], intensity: -30, rotation: nil))
|
||||
]
|
||||
|
||||
@ -110,34 +110,28 @@ enum ThemeSettingsColorOption: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
var plainBubbleColors: (UIColor, UIColor)? {
|
||||
var plainBubbleColors: [UInt32] {
|
||||
switch self {
|
||||
case let .accentColor(color):
|
||||
return color.plainBubbleColors
|
||||
case let .theme(reference):
|
||||
if case let .cloud(theme) = reference, let settings = theme.theme.settings, let messageColors = settings.messageColors {
|
||||
return (UIColor(argb: messageColors.top), UIColor(argb: messageColors.bottom))
|
||||
if case let .cloud(theme) = reference, let settings = theme.theme.settings, !settings.messageColors.isEmpty {
|
||||
return settings.messageColors
|
||||
} else {
|
||||
return nil
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var customBubbleColors: (UIColor, UIColor?)? {
|
||||
var customBubbleColors: [UInt32] {
|
||||
switch self {
|
||||
case let .accentColor(color):
|
||||
return color.customBubbleColors
|
||||
case let .theme(reference):
|
||||
if case let .cloud(theme) = reference, let settings = theme.theme.settings, let messageColors = settings.messageColors {
|
||||
let topColor = UIColor(argb: messageColors.top)
|
||||
let bottomColor = UIColor(argb: messageColors.bottom)
|
||||
if topColor.argb != bottomColor.argb {
|
||||
return (topColor, bottomColor)
|
||||
} else {
|
||||
return (topColor, nil)
|
||||
}
|
||||
if case let .cloud(theme) = reference, let settings = theme.theme.settings, !settings.messageColors.isEmpty {
|
||||
return settings.messageColors
|
||||
} else {
|
||||
return nil
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -381,9 +375,9 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode {
|
||||
var topColor: UIColor?
|
||||
var bottomColor: UIColor?
|
||||
|
||||
if let colors = item.color?.plainBubbleColors {
|
||||
topColor = colors.0
|
||||
bottomColor = colors.1
|
||||
if let colors = item.color?.plainBubbleColors, !colors.isEmpty {
|
||||
topColor = UIColor(rgb: colors[0])
|
||||
bottomColor = UIColor(rgb: colors.last ?? colors[0])
|
||||
} else if case .builtin(.dayClassic) = item.themeReference {
|
||||
if let accentColor = item.color?.accentColor {
|
||||
let hsb = accentColor.hsb
|
||||
|
||||
@ -225,25 +225,6 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode {
|
||||
strongSelf.insertSubnode(currentBackgroundNode, at: 0)
|
||||
}
|
||||
|
||||
/*if let updatedBackgroundSignal = updatedBackgroundSignal {
|
||||
strongSelf.disposable.set((updatedBackgroundSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] image in
|
||||
if let strongSelf = self, let (image, final) = image, let backgroundNode = strongSelf.backgroundNode {
|
||||
if final && !strongSelf.finalImage {
|
||||
let tempLayer = CALayer()
|
||||
tempLayer.frame = backgroundNode.bounds
|
||||
tempLayer.contentsGravity = backgroundNode.layer.contentsGravity
|
||||
tempLayer.contents = strongSelf.contents
|
||||
strongSelf.layer.addSublayer(tempLayer)
|
||||
tempLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak tempLayer] _ in
|
||||
tempLayer?.removeFromSuperlayer()
|
||||
})
|
||||
}
|
||||
backgroundNode.image = image
|
||||
strongSelf.finalImage = final
|
||||
}
|
||||
}))
|
||||
}*/
|
||||
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
|
||||
@ -647,7 +647,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
if let wallpaper = wallpaper {
|
||||
effectiveWallpaper = wallpaper
|
||||
} else {
|
||||
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors, wallpaper: accentColor?.wallpaper)
|
||||
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors ?? [], wallpaper: accentColor?.wallpaper)
|
||||
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
|
||||
}
|
||||
return (accentColor, effectiveWallpaper)
|
||||
@ -669,7 +669,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
|> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, TelegramWallpaper?), NoError> in
|
||||
return chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: context.sharedContext.accountManager.mediaBox)
|
||||
|> map { serviceBackgroundColor in
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors, serviceBackgroundColor: serviceBackgroundColor), wallpaper)
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors ?? [], serviceBackgroundColor: serviceBackgroundColor), wallpaper)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { theme, wallpaper in
|
||||
@ -854,7 +854,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
default:
|
||||
break
|
||||
}
|
||||
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors, wallpaper: accentColor?.wallpaper, baseColor: baseColor)
|
||||
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors ?? [], wallpaper: accentColor?.wallpaper, baseColor: baseColor)
|
||||
}
|
||||
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
|
||||
}
|
||||
@ -880,7 +880,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, serviceBackgroundColor: serviceBackgroundColor), effectiveThemeReference, wallpaper)
|
||||
} else {
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors, serviceBackgroundColor: serviceBackgroundColor), effectiveThemeReference, wallpaper)
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors ?? [], serviceBackgroundColor: serviceBackgroundColor), effectiveThemeReference, wallpaper)
|
||||
}
|
||||
}
|
||||
|> mapToSignal { theme, reference, wallpaper in
|
||||
|
||||
@ -207,6 +207,7 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode {
|
||||
didSet {
|
||||
if self.isCurrentlyInHierarchy != oldValue {
|
||||
self.highlightNode.isCurrentlyInHierarchy = self.isCurrentlyInHierarchy
|
||||
self.audioLevelView?.isManuallyInHierarchy = self.isCurrentlyInHierarchy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,9 +47,9 @@ extension TelegramThemeSettings {
|
||||
convenience init?(apiThemeSettings: Api.ThemeSettings) {
|
||||
switch apiThemeSettings {
|
||||
case let .themeSettings(_, baseTheme, accentColor, messageTopColor, messageBottomColor, wallpaper):
|
||||
var messageColors: (UInt32, UInt32)?
|
||||
var messageColors: [UInt32] = []
|
||||
if let messageTopColor = messageTopColor, let messageBottomColor = messageBottomColor {
|
||||
messageColors = (UInt32(bitPattern: messageTopColor), UInt32(bitPattern: messageBottomColor))
|
||||
messageColors = [UInt32(bitPattern: messageTopColor), UInt32(bitPattern: messageBottomColor)]
|
||||
}
|
||||
self.init(baseTheme: TelegramBaseTheme(apiBaseTheme: baseTheme), accentColor: UInt32(bitPattern: accentColor), messageColors: messageColors, wallpaper: wallpaper.flatMap(TelegramWallpaper.init(apiWallpaper:)))
|
||||
}
|
||||
@ -57,7 +57,7 @@ extension TelegramThemeSettings {
|
||||
|
||||
var apiInputThemeSettings: Api.InputThemeSettings {
|
||||
var flags: Int32 = 0
|
||||
if let _ = self.messageColors {
|
||||
if !self.messageColors.isEmpty {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
|
||||
@ -71,11 +71,12 @@ extension TelegramThemeSettings {
|
||||
|
||||
var messageTopColor: Int32?
|
||||
var messageBottomColor: Int32?
|
||||
if let color = self.messageColors?.0 {
|
||||
messageTopColor = Int32(bitPattern: color)
|
||||
if self.messageColors.count > 0 {
|
||||
messageTopColor = Int32(bitPattern: self.messageColors[0])
|
||||
messageBottomColor = messageTopColor
|
||||
}
|
||||
if let color = self.messageColors?.1 {
|
||||
messageBottomColor = Int32(bitPattern: color)
|
||||
if self.messageColors.count > 1 {
|
||||
messageBottomColor = Int32(bitPattern: self.messageColors[1])
|
||||
}
|
||||
|
||||
return .inputThemeSettings(flags: flags, baseTheme: self.baseTheme.apiBaseTheme, accentColor: Int32(bitPattern: self.accentColor), messageTopColor: messageTopColor, messageBottomColor: messageBottomColor, wallpaper: inputWallpaper, wallpaperSettings: inputWallpaperSettings)
|
||||
|
||||
@ -21,7 +21,7 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
if lhs.accentColor != rhs.accentColor {
|
||||
return false
|
||||
}
|
||||
if lhs.messageColors?.0 != rhs.messageColors?.0 || lhs.messageColors?.1 != rhs.messageColors?.1 {
|
||||
if lhs.messageColors != rhs.messageColors {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaper != rhs.wallpaper {
|
||||
@ -32,10 +32,10 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
|
||||
public let baseTheme: TelegramBaseTheme
|
||||
public let accentColor: UInt32
|
||||
public let messageColors: (top: UInt32, bottom: UInt32)?
|
||||
public let messageColors: [UInt32]
|
||||
public let wallpaper: TelegramWallpaper?
|
||||
|
||||
public init(baseTheme: TelegramBaseTheme, accentColor: UInt32, messageColors: (top: UInt32, bottom: UInt32)?, wallpaper: TelegramWallpaper?) {
|
||||
public init(baseTheme: TelegramBaseTheme, accentColor: UInt32, messageColors: [UInt32], wallpaper: TelegramWallpaper?) {
|
||||
self.baseTheme = baseTheme
|
||||
self.accentColor = accentColor
|
||||
self.messageColors = messageColors
|
||||
@ -45,10 +45,15 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.baseTheme = TelegramBaseTheme(rawValue: decoder.decodeInt32ForKey("baseTheme", orElse: 0)) ?? .classic
|
||||
self.accentColor = UInt32(bitPattern: decoder.decodeInt32ForKey("accent", orElse: 0))
|
||||
if let topMessageColor = decoder.decodeOptionalInt32ForKey("topMessage"), let bottomMessageColor = decoder.decodeOptionalInt32ForKey("bottomMessage") {
|
||||
self.messageColors = (UInt32(bitPattern: topMessageColor), UInt32(bitPattern: bottomMessageColor))
|
||||
let messageColors = decoder.decodeInt32ArrayForKey("messageColors")
|
||||
if !messageColors.isEmpty {
|
||||
self.messageColors = messageColors.map(UInt32.init(bitPattern:))
|
||||
} else {
|
||||
self.messageColors = nil
|
||||
if let topMessageColor = decoder.decodeOptionalInt32ForKey("topMessage"), let bottomMessageColor = decoder.decodeOptionalInt32ForKey("bottomMessage") {
|
||||
self.messageColors = [UInt32(bitPattern: topMessageColor), UInt32(bitPattern: bottomMessageColor)]
|
||||
} else {
|
||||
self.messageColors = []
|
||||
}
|
||||
}
|
||||
self.wallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
|
||||
}
|
||||
@ -56,13 +61,7 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.baseTheme.rawValue, forKey: "baseTheme")
|
||||
encoder.encodeInt32(Int32(bitPattern: self.accentColor), forKey: "accent")
|
||||
if let (topMessageColor, bottomMessageColor) = self.messageColors {
|
||||
encoder.encodeInt32(Int32(bitPattern: topMessageColor), forKey: "topMessage")
|
||||
encoder.encodeInt32(Int32(bitPattern: bottomMessageColor), forKey: "bottomMessage")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "topMessage")
|
||||
encoder.encodeNil(forKey: "bottomMessage")
|
||||
}
|
||||
encoder.encodeInt32Array(self.messageColors.map(Int32.init(bitPattern:)), forKey: "messageColors")
|
||||
if let wallpaper = self.wallpaper {
|
||||
encoder.encodeObject(wallpaper, forKey: "wallpaper")
|
||||
} else {
|
||||
|
||||
@ -860,6 +860,11 @@ func _internal_currentChatListFilters(postbox: Postbox) -> Signal<[ChatListFilte
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_currentChatListFilters(transaction: Transaction) -> [ChatListFilter] {
|
||||
let settings = transaction.getPreferencesEntry(key: PreferencesKeys.chatListFilters) as? ChatListFiltersState ?? ChatListFiltersState.default
|
||||
return settings.filters
|
||||
}
|
||||
|
||||
func updateChatListFiltersState(transaction: Transaction, _ f: (ChatListFiltersState) -> ChatListFiltersState) -> ChatListFiltersState {
|
||||
var result: ChatListFiltersState?
|
||||
transaction.updatePreferencesEntry(key: PreferencesKeys.chatListFilters, { entry in
|
||||
|
||||
@ -25,6 +25,13 @@ public final class OpaqueChatInterfaceState {
|
||||
}
|
||||
|
||||
public extension TelegramEngine {
|
||||
enum NextUnreadChannelLocation: Equatable {
|
||||
case same
|
||||
case archived
|
||||
case unarchived
|
||||
case folder(id: Int32, title: String)
|
||||
}
|
||||
|
||||
final class Peers {
|
||||
private let account: Account
|
||||
|
||||
@ -495,40 +502,90 @@ public extension TelegramEngine {
|
||||
return _internal_updatePeerDescription(account: self.account, peerId: peerId, description: description)
|
||||
}
|
||||
|
||||
public func getNextUnreadChannel(peerId: PeerId, filter: ChatListFilterPredicate?) -> Signal<(peer: EnginePeer, unreadCount: Int)?, NoError> {
|
||||
return self.account.postbox.transaction { transaction -> (peer: EnginePeer, unreadCount: Int)? in
|
||||
var results: [(EnginePeer, Int32)] = []
|
||||
|
||||
var peerIds: [PeerId] = []
|
||||
peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: filter))
|
||||
peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: filter))
|
||||
|
||||
for listId in peerIds {
|
||||
guard let peer = transaction.getPeer(listId) else {
|
||||
continue
|
||||
}
|
||||
guard let channel = peer as? TelegramChannel, case .broadcast = channel.info else {
|
||||
continue
|
||||
}
|
||||
if channel.id == peerId {
|
||||
continue
|
||||
}
|
||||
guard let readState = transaction.getCombinedPeerReadState(channel.id), readState.count != 0 else {
|
||||
continue
|
||||
}
|
||||
guard let topMessageIndex = transaction.getTopPeerMessageIndex(peerId: channel.id) else {
|
||||
continue
|
||||
public func getNextUnreadChannel(peerId: PeerId, chatListFilterId: Int32?, getFilterPredicate: @escaping (ChatListFilterData) -> ChatListFilterPredicate) -> Signal<(peer: EnginePeer, unreadCount: Int, location: NextUnreadChannelLocation)?, NoError> {
|
||||
return self.account.postbox.transaction { transaction -> (peer: EnginePeer, unreadCount: Int, location: NextUnreadChannelLocation)? in
|
||||
func getForFilter(predicate: ChatListFilterPredicate?, isArchived: Bool) -> (peer: EnginePeer, unreadCount: Int)? {
|
||||
var peerIds: [PeerId] = []
|
||||
if predicate != nil {
|
||||
peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: predicate))
|
||||
peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: predicate))
|
||||
} else {
|
||||
if isArchived {
|
||||
peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: nil))
|
||||
} else {
|
||||
peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: nil))
|
||||
}
|
||||
}
|
||||
|
||||
results.append((EnginePeer(channel), topMessageIndex.timestamp))
|
||||
var results: [(EnginePeer, Int32)] = []
|
||||
|
||||
for listId in peerIds {
|
||||
guard let peer = transaction.getPeer(listId) else {
|
||||
continue
|
||||
}
|
||||
guard let channel = peer as? TelegramChannel, case .broadcast = channel.info else {
|
||||
continue
|
||||
}
|
||||
if channel.id == peerId {
|
||||
continue
|
||||
}
|
||||
guard let readState = transaction.getCombinedPeerReadState(channel.id), readState.count != 0 else {
|
||||
continue
|
||||
}
|
||||
guard let topMessageIndex = transaction.getTopPeerMessageIndex(peerId: channel.id) else {
|
||||
continue
|
||||
}
|
||||
|
||||
results.append((EnginePeer(channel), topMessageIndex.timestamp))
|
||||
}
|
||||
|
||||
results.sort(by: { $0.1 > $1.1 })
|
||||
|
||||
if let peer = results.first?.0 {
|
||||
let unreadCount: Int32 = transaction.getCombinedPeerReadState(peer.id)?.count ?? 0
|
||||
return (peer: peer, unreadCount: Int(unreadCount))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
results.sort(by: { $0.1 > $1.1 })
|
||||
guard let peerGroupId = transaction.getPeerChatListIndex(peerId)?.0 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let peer = results.first?.0 {
|
||||
let unreadCount: Int32 = transaction.getCombinedPeerReadState(peer.id)?.count ?? 0
|
||||
return (peer: peer, unreadCount: Int(unreadCount))
|
||||
if let filterId = chatListFilterId {
|
||||
let filters = _internal_currentChatListFilters(transaction: transaction)
|
||||
guard let index = filters.firstIndex(where: { $0.id == filterId }) else {
|
||||
return nil
|
||||
}
|
||||
var sortedFilters: [ChatListFilter] = []
|
||||
sortedFilters.append(contentsOf: filters[index...])
|
||||
sortedFilters.append(contentsOf: filters[0 ..< index])
|
||||
for i in 0 ..< sortedFilters.count {
|
||||
if let value = getForFilter(predicate: getFilterPredicate(sortedFilters[i].data), isArchived: false) {
|
||||
return (peer: value.peer, unreadCount: value.unreadCount, location: i == 0 ? .same : .folder(id: sortedFilters[i].id, title: sortedFilters[i].title))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
let folderOrder: [(PeerGroupId, NextUnreadChannelLocation)]
|
||||
if peerGroupId == .root {
|
||||
folderOrder = [
|
||||
(.root, .same),
|
||||
(Namespaces.PeerGroup.archive, .archived),
|
||||
]
|
||||
} else {
|
||||
folderOrder = [
|
||||
(Namespaces.PeerGroup.archive, .same),
|
||||
(.root, .unarchived),
|
||||
]
|
||||
}
|
||||
|
||||
for (groupId, location) in folderOrder {
|
||||
if let value = getForFilter(predicate: nil, isArchived: groupId != .root) {
|
||||
return (peer: value.peer, unreadCount: value.unreadCount, location: location)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +348,9 @@ public func createTheme(account: Account, title: String, resource: MediaResource
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { apiTheme -> Signal<CreateThemeResult, CreateThemeError> in
|
||||
if let theme = TelegramTheme(apiTheme: apiTheme) {
|
||||
if var theme = TelegramTheme(apiTheme: apiTheme) {
|
||||
theme = TelegramTheme(id: theme.id, accessHash: theme.accessHash, slug: theme.slug, title: theme.title, file: theme.file, settings: settings, isCreator: theme.isCreator, isDefault: theme.isDefault, installCount: theme.installCount)
|
||||
|
||||
return account.postbox.transaction { transaction -> CreateThemeResult in
|
||||
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
|
||||
var items = entries.map { $0.contents as! TelegramTheme }
|
||||
@ -427,7 +429,9 @@ public func updateTheme(account: Account, accountManager: AccountManager, theme:
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { apiTheme -> Signal<CreateThemeResult, CreateThemeError> in
|
||||
if let updatedTheme = TelegramTheme(apiTheme: apiTheme) {
|
||||
if let theme = TelegramTheme(apiTheme: apiTheme) {
|
||||
let updatedTheme = TelegramTheme(id: theme.id, accessHash: theme.accessHash, slug: theme.slug, title: theme.title, file: theme.file, settings: settings, isCreator: theme.isCreator, isDefault: theme.isDefault, installCount: theme.installCount)
|
||||
|
||||
let _ = accountManager.transaction { transaction in
|
||||
transaction.updateSharedData(SharedDataKeys.themeSettings, { current in
|
||||
var updated = current as? ThemeSettings ?? ThemeSettings(currentTheme: nil)
|
||||
|
||||
@ -4,25 +4,9 @@ import TelegramCore
|
||||
import TelegramUIPreferences
|
||||
|
||||
public let defaultDarkPresentationTheme = makeDefaultDarkPresentationTheme(preview: false)
|
||||
public let defaultDarkColorPresentationTheme = customizeDefaultDarkPresentationTheme(theme: defaultDarkPresentationTheme, editing: false, title: nil, accentColor: UIColor(rgb: 0x007aff), backgroundColors: [], bubbleColors: nil, wallpaper: nil, baseColor: nil)
|
||||
public let defaultDarkColorPresentationTheme = customizeDefaultDarkPresentationTheme(theme: defaultDarkPresentationTheme, editing: false, title: nil, accentColor: UIColor(rgb: 0x007aff), backgroundColors: [], bubbleColors: [], wallpaper: nil, baseColor: nil)
|
||||
|
||||
private extension PresentationThemeBaseColor {
|
||||
/*
|
||||
|
||||
Оранжевая с красным
|
||||
https://t.me/bg/9LW_RcoOSVACAAAAFTk3DTyXN-M?bg_color=fec496~dd6cb9~962fbf~4f5bd5&intensity=-40
|
||||
|
||||
Голубая с розовым
|
||||
https://t.me/bg/9iklpvIPQVABAAAAORQXKur_Eyc?bg_color=8adbf2~888dec~e39fea~679ced&intensity=-30
|
||||
|
||||
Мятная
|
||||
https://t.me/bg/CJNyxPMgSVAEAAAAvW9sMwc51cw?bg_color=7fa381~fff5c5~336f55~fbe37d&intensity=-20
|
||||
|
||||
Синяя с розовым
|
||||
https://t.me/bg/9LW_RcoOSVACAAAAFTk3DTyXN-M?bg_color=fec496~dd6cb9~962fbf~4f5bd5&intensity=-40
|
||||
|
||||
*/
|
||||
|
||||
var colorWallpaper: (BuiltinWallpaperData, Int32, [UInt32])? {
|
||||
switch self {
|
||||
case .blue:
|
||||
@ -53,7 +37,7 @@ private extension PresentationThemeBaseColor {
|
||||
}
|
||||
}
|
||||
|
||||
public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], wallpaper forcedWallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
if (theme.referenceTheme != .night) {
|
||||
return theme
|
||||
}
|
||||
@ -67,13 +51,13 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
|
||||
var bubbleColors = bubbleColors
|
||||
var monochrome = false
|
||||
if bubbleColors == nil, editing {
|
||||
if bubbleColors.isEmpty, editing {
|
||||
let accentColor = accentColor ?? UIColor(rgb: 0xffffff)
|
||||
if accentColor.rgb == 0xffffff {
|
||||
monochrome = true
|
||||
bubbleColors = (UIColor(rgb: 0x313131), UIColor(rgb: 0x313131))
|
||||
bubbleColors = [UIColor(rgb: 0x313131).rgb, UIColor(rgb: 0x313131).rgb]
|
||||
} else {
|
||||
bubbleColors = (accentColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98), accentColor)
|
||||
bubbleColors = [accentColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98).rgb, accentColor.rgb]
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,17 +122,16 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
}
|
||||
}
|
||||
|
||||
var outgoingBubbleFillColor: UIColor?
|
||||
var outgoingBubbleFillGradientColor: UIColor?
|
||||
var outgoingBubbleFillColors: [UIColor]?
|
||||
var outgoingPrimaryTextColor: UIColor?
|
||||
var outgoingSecondaryTextColor: UIColor?
|
||||
var outgoingLinkTextColor: UIColor?
|
||||
var outgoingScamColor: UIColor?
|
||||
var outgoingCheckColor: UIColor?
|
||||
|
||||
if let bubbleColors = bubbleColors {
|
||||
var topBubbleColor = bubbleColors.0
|
||||
var bottomBubbleColor = bubbleColors.1 ?? bubbleColors.0
|
||||
if !bubbleColors.isEmpty {
|
||||
var topBubbleColor = UIColor(rgb: bubbleColors[0])
|
||||
var bottomBubbleColor = UIColor(rgb: bubbleColors.last ?? bubbleColors[0])
|
||||
|
||||
if topBubbleColor.rgb != bottomBubbleColor.rgb {
|
||||
let topBubbleColorLightness = topBubbleColor.lightness
|
||||
@ -162,8 +145,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
}
|
||||
}
|
||||
|
||||
outgoingBubbleFillColor = topBubbleColor
|
||||
outgoingBubbleFillGradientColor = bottomBubbleColor
|
||||
outgoingBubbleFillColors = bubbleColors.map(UIColor.init(rgb:))
|
||||
|
||||
let lightnessColor = topBubbleColor.mixedWith(bottomBubbleColor, alpha: 0.5)
|
||||
if lightnessColor.lightness > 0.7 {
|
||||
@ -210,15 +192,13 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
outgoing: chat.message.outgoing.withUpdated(
|
||||
bubble: chat.message.outgoing.bubble.withUpdated(
|
||||
withWallpaper: chat.message.outgoing.bubble.withWallpaper.withUpdated(
|
||||
fill: outgoingBubbleFillColor,
|
||||
gradientFill: outgoingBubbleFillGradientColor,
|
||||
highlightedFill: outgoingBubbleFillColor?.withMultipliedBrightnessBy(1.421),
|
||||
fill: outgoingBubbleFillColors,
|
||||
highlightedFill: outgoingBubbleFillColors?.first?.withMultipliedBrightnessBy(1.421),
|
||||
stroke: .clear
|
||||
),
|
||||
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
|
||||
fill: outgoingBubbleFillColor,
|
||||
gradientFill: outgoingBubbleFillGradientColor,
|
||||
highlightedFill: outgoingBubbleFillColor?.withMultipliedBrightnessBy(1.421),
|
||||
fill: outgoingBubbleFillColors,
|
||||
highlightedFill: outgoingBubbleFillColors?.first?.withMultipliedBrightnessBy(1.421),
|
||||
stroke: .clear
|
||||
)
|
||||
),
|
||||
@ -230,7 +210,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
accentControlColor: outgoingPrimaryTextColor,
|
||||
mediaActiveControlColor: outgoingPrimaryTextColor,
|
||||
mediaInactiveControlColor: outgoingSecondaryTextColor,
|
||||
mediaControlInnerBackgroundColor: outgoingBubbleFillColor,
|
||||
mediaControlInnerBackgroundColor: outgoingBubbleFillColors?.first,
|
||||
pendingActivityColor: outgoingSecondaryTextColor,
|
||||
fileTitleColor: outgoingPrimaryTextColor,
|
||||
fileDescriptionColor: outgoingSecondaryTextColor,
|
||||
@ -455,9 +435,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
|
||||
let incomingBubbleAlpha: CGFloat = 0.9
|
||||
|
||||
let message = PresentationThemeChatMessage(
|
||||
incoming: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x1D1D1D, alpha: incomingBubbleAlpha), highlightedFill: UIColor(rgb: 0x353539), stroke: UIColor(rgb: 0x262628), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x1D1D1D, alpha: incomingBubbleAlpha), highlightedFill: UIColor(rgb: 0x353539), stroke: UIColor(rgb: 0x262628), shadow: nil)), primaryTextColor: UIColor(rgb: 0xffffff), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), linkTextColor: UIColor(rgb: 0xffffff), linkHighlightColor: UIColor(rgb: 0xffffff, alpha: 0.5), scamColor: UIColor(rgb: 0xeb5545), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: UIColor(rgb: 0xffffff), accentControlColor: UIColor(rgb: 0xffffff), accentControlDisabledColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaActiveControlColor: UIColor(rgb: 0xffffff), mediaInactiveControlColor: UIColor(rgb: 0xffffff, alpha: 0.4), mediaControlInnerBackgroundColor: UIColor(rgb: 0x262628), pendingActivityColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileTitleColor: UIColor(rgb: 0xffffff), fileDescriptionColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileDurationColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaPlaceholderColor: UIColor(rgb: 0x1f1f1f).mixedWith(UIColor(rgb: 0xffffff), alpha: 0.05), polls: PresentationThemeChatBubblePolls(radioButton: UIColor(rgb: 0x737373), radioProgress: UIColor(rgb: 0xffffff), highlight: UIColor(rgb: 0xffffff, alpha: 0.12), separator: UIColor(rgb: 0x000000), bar: UIColor(rgb: 0xffffff), barIconForeground: .clear, barPositive: UIColor(rgb: 0x00A700), barNegative: UIColor(rgb: 0xFE3824)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0x000000, alpha: 0.5), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xb2b2b2, alpha: 0.18)), actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0xffffff)),
|
||||
outgoing: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x61BCF9), gradientFill: UIColor(rgb: 0x007AFF), highlightedFill: UIColor(rgb: 0x61BCF9), stroke: .clear, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x61BCF9), gradientFill: UIColor(rgb: 0x007AFF), highlightedFill: UIColor(rgb: 0x61BCF9), stroke: .clear, shadow: nil)), primaryTextColor: UIColor(rgb: 0xffffff), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), linkTextColor: UIColor(rgb: 0xffffff), linkHighlightColor: UIColor(rgb: 0xffffff, alpha: 0.5), scamColor: UIColor(rgb: 0xeb5545), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: UIColor(rgb: 0xffffff), accentControlColor: UIColor(rgb: 0xffffff), accentControlDisabledColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaActiveControlColor: UIColor(rgb: 0xffffff), mediaInactiveControlColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaControlInnerBackgroundColor: UIColor(rgb: 0x313131), pendingActivityColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileTitleColor: UIColor(rgb: 0xffffff), fileDescriptionColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileDurationColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaPlaceholderColor: UIColor(rgb: 0x313131).mixedWith(UIColor(rgb: 0xffffff), alpha: 0.05), polls: PresentationThemeChatBubblePolls(radioButton: UIColor(rgb: 0xffffff), radioProgress: UIColor(rgb: 0xffffff), highlight: UIColor(rgb: 0xffffff).withAlphaComponent(0.12), separator: UIColor(rgb: 0xffffff, alpha: 0.5), bar: UIColor(rgb: 0xffffff), barIconForeground: .clear, barPositive: UIColor(rgb: 0xffffff), barNegative: UIColor(rgb: 0xffffff)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0x000000, alpha: 0.5), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xb2b2b2, alpha: 0.18)), actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0xffffff)),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x1f1f1f), highlightedFill: UIColor(rgb: 0x2a2a2a), stroke: UIColor(rgb: 0x1f1f1f), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x1f1f1f), highlightedFill: UIColor(rgb: 0x2a2a2a), stroke: UIColor(rgb: 0x1f1f1f), shadow: nil)),
|
||||
incoming: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x1D1D1D, alpha: incomingBubbleAlpha)], highlightedFill: UIColor(rgb: 0x353539), stroke: UIColor(rgb: 0x262628), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x1D1D1D, alpha: incomingBubbleAlpha)], highlightedFill: UIColor(rgb: 0x353539), stroke: UIColor(rgb: 0x262628), shadow: nil)), primaryTextColor: UIColor(rgb: 0xffffff), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), linkTextColor: UIColor(rgb: 0xffffff), linkHighlightColor: UIColor(rgb: 0xffffff, alpha: 0.5), scamColor: UIColor(rgb: 0xeb5545), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: UIColor(rgb: 0xffffff), accentControlColor: UIColor(rgb: 0xffffff), accentControlDisabledColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaActiveControlColor: UIColor(rgb: 0xffffff), mediaInactiveControlColor: UIColor(rgb: 0xffffff, alpha: 0.4), mediaControlInnerBackgroundColor: UIColor(rgb: 0x262628), pendingActivityColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileTitleColor: UIColor(rgb: 0xffffff), fileDescriptionColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileDurationColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaPlaceholderColor: UIColor(rgb: 0x1f1f1f).mixedWith(UIColor(rgb: 0xffffff), alpha: 0.05), polls: PresentationThemeChatBubblePolls(radioButton: UIColor(rgb: 0x737373), radioProgress: UIColor(rgb: 0xffffff), highlight: UIColor(rgb: 0xffffff, alpha: 0.12), separator: UIColor(rgb: 0x000000), bar: UIColor(rgb: 0xffffff), barIconForeground: .clear, barPositive: UIColor(rgb: 0x00A700), barNegative: UIColor(rgb: 0xFE3824)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0x000000, alpha: 0.5), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xb2b2b2, alpha: 0.18)), actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0xffffff)),
|
||||
outgoing: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x61BCF9), UIColor(rgb: 0x007AFF)], highlightedFill: UIColor(rgb: 0x61BCF9), stroke: .clear, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x61BCF9), UIColor(rgb: 0x007AFF)], highlightedFill: UIColor(rgb: 0x61BCF9), stroke: .clear, shadow: nil)), primaryTextColor: UIColor(rgb: 0xffffff), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), linkTextColor: UIColor(rgb: 0xffffff), linkHighlightColor: UIColor(rgb: 0xffffff, alpha: 0.5), scamColor: UIColor(rgb: 0xeb5545), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: UIColor(rgb: 0xffffff), accentControlColor: UIColor(rgb: 0xffffff), accentControlDisabledColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaActiveControlColor: UIColor(rgb: 0xffffff), mediaInactiveControlColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaControlInnerBackgroundColor: UIColor(rgb: 0x313131), pendingActivityColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileTitleColor: UIColor(rgb: 0xffffff), fileDescriptionColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileDurationColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaPlaceholderColor: UIColor(rgb: 0x313131).mixedWith(UIColor(rgb: 0xffffff), alpha: 0.05), polls: PresentationThemeChatBubblePolls(radioButton: UIColor(rgb: 0xffffff), radioProgress: UIColor(rgb: 0xffffff), highlight: UIColor(rgb: 0xffffff).withAlphaComponent(0.12), separator: UIColor(rgb: 0xffffff, alpha: 0.5), bar: UIColor(rgb: 0xffffff), barIconForeground: .clear, barPositive: UIColor(rgb: 0xffffff), barNegative: UIColor(rgb: 0xffffff)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0x000000, alpha: 0.5), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xb2b2b2, alpha: 0.18)), actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0xffffff)),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x1f1f1f)], highlightedFill: UIColor(rgb: 0x2a2a2a), stroke: UIColor(rgb: 0x1f1f1f), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x1f1f1f)], highlightedFill: UIColor(rgb: 0x2a2a2a), stroke: UIColor(rgb: 0x1f1f1f), shadow: nil)),
|
||||
infoPrimaryTextColor: UIColor(rgb: 0xffffff),
|
||||
infoLinkTextColor: UIColor(rgb: 0xffffff),
|
||||
outgoingCheckColor: UIColor(rgb: 0xffffff),
|
||||
|
||||
@ -38,7 +38,7 @@ private extension PresentationThemeBaseColor {
|
||||
}
|
||||
}
|
||||
|
||||
public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], wallpaper forcedWallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
if (theme.referenceTheme != .nightAccent) {
|
||||
return theme
|
||||
}
|
||||
@ -75,7 +75,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
var suggestedWallpaper: TelegramWallpaper?
|
||||
|
||||
var bubbleColors = bubbleColors
|
||||
if bubbleColors == nil, editing {
|
||||
if bubbleColors.isEmpty, editing {
|
||||
if let accentColor = accentColor {
|
||||
if let baseColor = baseColor, let (variant, intensity, colors) = baseColor.colorWallpaper, !colors.isEmpty {
|
||||
suggestedWallpaper = defaultBuiltinWallpaper(data: variant, colors: colors, intensity: intensity)
|
||||
@ -88,7 +88,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
let accentColor = accentColor ?? defaultDarkTintedAccentColor
|
||||
let bottomColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.731, brightness: 0.59)
|
||||
let topColor = bottomColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98)
|
||||
bubbleColors = (topColor, bottomColor)
|
||||
bubbleColors = [topColor.rgb, bottomColor.rgb]
|
||||
}
|
||||
|
||||
if let initialAccentColor = accentColor {
|
||||
@ -268,8 +268,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
defaultWallpaper = forcedWallpaper
|
||||
}
|
||||
|
||||
var outgoingBubbleFillColor: UIColor?
|
||||
var outgoingBubbleFillGradientColor: UIColor?
|
||||
var outgoingBubbleFillColors: [UIColor]?
|
||||
var outgoingPrimaryTextColor: UIColor?
|
||||
var outgoingSecondaryTextColor: UIColor?
|
||||
var outgoingLinkTextColor: UIColor?
|
||||
@ -278,11 +277,10 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
var highlightedIncomingBubbleColor: UIColor?
|
||||
var highlightedOutgoingBubbleColor: UIColor?
|
||||
|
||||
if let bubbleColors = bubbleColors {
|
||||
outgoingBubbleFillColor = bubbleColors.0
|
||||
outgoingBubbleFillGradientColor = bubbleColors.1 ?? bubbleColors.0
|
||||
if !bubbleColors.isEmpty {
|
||||
outgoingBubbleFillColors = bubbleColors.map(UIColor.init(rgb:))
|
||||
|
||||
let lightnessColor = bubbleColors.0.mixedWith(bubbleColors.1 ?? bubbleColors.0, alpha: 0.5)
|
||||
let lightnessColor = UIColor(rgb: bubbleColors[0]).mixedWith(UIColor(rgb: bubbleColors.last ?? bubbleColors[0]), alpha: 0.5)
|
||||
if lightnessColor.lightness > 0.7 {
|
||||
outgoingPrimaryTextColor = UIColor(rgb: 0x000000)
|
||||
outgoingSecondaryTextColor = UIColor(rgb: 0x000000, alpha: 0.5)
|
||||
@ -298,7 +296,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
}
|
||||
|
||||
highlightedIncomingBubbleColor = accentColor?.withMultiplied(hue: 1.03, saturation: 0.463, brightness: 0.29)
|
||||
highlightedOutgoingBubbleColor = outgoingBubbleFillColor?.withMultiplied(hue: 1.019, saturation: 0.609, brightness: 0.63)
|
||||
highlightedOutgoingBubbleColor = outgoingBubbleFillColors?.first?.withMultiplied(hue: 1.019, saturation: 0.609, brightness: 0.63)
|
||||
}
|
||||
|
||||
let incomingFillColor = mainBackgroundColor?.withMultipliedAlpha(0.9)
|
||||
@ -309,14 +307,12 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
incoming: chat.message.incoming.withUpdated(
|
||||
bubble: chat.message.incoming.bubble.withUpdated(
|
||||
withWallpaper: chat.message.outgoing.bubble.withWallpaper.withUpdated(
|
||||
fill: incomingFillColor,
|
||||
gradientFill: incomingFillColor,
|
||||
fill: incomingFillColor.flatMap({ [$0] }),
|
||||
highlightedFill: highlightedIncomingBubbleColor,
|
||||
stroke: mainBackgroundColor
|
||||
),
|
||||
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
|
||||
fill: incomingFillColor,
|
||||
gradientFill: incomingFillColor,
|
||||
fill: incomingFillColor.flatMap({ [$0] }),
|
||||
highlightedFill: highlightedIncomingBubbleColor,
|
||||
stroke: mainBackgroundColor
|
||||
)
|
||||
@ -352,14 +348,12 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
outgoing: chat.message.outgoing.withUpdated(
|
||||
bubble: chat.message.outgoing.bubble.withUpdated(
|
||||
withWallpaper: chat.message.outgoing.bubble.withWallpaper.withUpdated(
|
||||
fill: outgoingBubbleFillColor,
|
||||
gradientFill: outgoingBubbleFillGradientColor,
|
||||
fill: outgoingBubbleFillColors,
|
||||
highlightedFill: highlightedOutgoingBubbleColor,
|
||||
stroke: .clear
|
||||
),
|
||||
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
|
||||
fill: outgoingBubbleFillColor,
|
||||
gradientFill: outgoingBubbleFillGradientColor,
|
||||
fill: outgoingBubbleFillColors,
|
||||
highlightedFill: highlightedOutgoingBubbleColor,
|
||||
stroke: .clear
|
||||
)
|
||||
@ -372,7 +366,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
accentControlColor: outgoingPrimaryTextColor,
|
||||
mediaActiveControlColor: outgoingPrimaryTextColor,
|
||||
mediaInactiveControlColor: outgoingSecondaryTextColor,
|
||||
mediaControlInnerBackgroundColor: outgoingBubbleFillColor,
|
||||
mediaControlInnerBackgroundColor: outgoingBubbleFillColors?.first,
|
||||
pendingActivityColor: outgoingSecondaryTextColor,
|
||||
fileTitleColor: outgoingPrimaryTextColor,
|
||||
fileDescriptionColor: outgoingSecondaryTextColor,
|
||||
@ -384,11 +378,11 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
),
|
||||
freeform: chat.message.freeform.withUpdated(
|
||||
withWallpaper: chat.message.freeform.withWallpaper.withUpdated(
|
||||
fill: mainBackgroundColor,
|
||||
fill: mainBackgroundColor.flatMap({ [$0] }),
|
||||
highlightedFill: highlightedIncomingBubbleColor,
|
||||
stroke: mainBackgroundColor
|
||||
), withoutWallpaper: chat.message.freeform.withoutWallpaper.withUpdated(
|
||||
fill: mainBackgroundColor,
|
||||
fill: mainBackgroundColor.flatMap({ [$0] }),
|
||||
highlightedFill: highlightedIncomingBubbleColor,
|
||||
stroke: mainBackgroundColor
|
||||
)
|
||||
@ -509,7 +503,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
|
||||
let mainFreeTextColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.097, brightness: 0.56)
|
||||
|
||||
let outgoingBubbleFillGradientColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.731, brightness: 0.59)
|
||||
let outgoingBubbleFillColor = outgoingBubbleFillGradientColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98)
|
||||
|
||||
let outgoingBubbleFillColors: [UIColor] = [outgoingBubbleFillGradientColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98), outgoingBubbleFillGradientColor]
|
||||
|
||||
let outgoingScamColor = UIColor(rgb: 0xffffff)
|
||||
let outgoingPrimaryTextColor = UIColor(rgb: 0xffffff)
|
||||
let outgoingSecondaryTextColor = UIColor(rgb: 0xffffff, alpha: 0.5)
|
||||
@ -700,9 +696,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
|
||||
let incomingFillColor = mainBackgroundColor.withMultipliedAlpha(0.9)
|
||||
|
||||
let message = PresentationThemeChatMessage(
|
||||
incoming: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: incomingFillColor, highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: incomingFillColor, highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil)), primaryTextColor: .white, secondaryTextColor: mainSecondaryTextColor.withAlphaComponent(0.5), linkTextColor: accentColor, linkHighlightColor: accentColor.withAlphaComponent(0.5), scamColor: UIColor(rgb: 0xff6767), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: accentColor, accentControlColor: accentColor, accentControlDisabledColor: mainSecondaryTextColor.withAlphaComponent(0.5), mediaActiveControlColor: accentColor, mediaInactiveControlColor: accentColor.withAlphaComponent(0.5), mediaControlInnerBackgroundColor: mainBackgroundColor, pendingActivityColor: mainSecondaryTextColor.withAlphaComponent(0.5), fileTitleColor: accentColor, fileDescriptionColor: mainSecondaryTextColor.withAlphaComponent(0.5), fileDurationColor: mainSecondaryTextColor.withAlphaComponent(0.5), mediaPlaceholderColor: accentColor.withMultiplied(hue: 1.019, saturation: 0.585, brightness: 0.23), polls: PresentationThemeChatBubblePolls(radioButton: accentColor.withMultiplied(hue: 0.995, saturation: 0.317, brightness: 0.51), radioProgress: accentColor, highlight: accentColor.withAlphaComponent(0.12), separator: mainSeparatorColor, bar: accentColor, barIconForeground: .white, barPositive: UIColor(rgb: 0x00A700), barNegative: UIColor(rgb: 0xFE3824)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: additionalBackgroundColor.withAlphaComponent(0.5), withoutWallpaper: additionalBackgroundColor.withAlphaComponent(0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: buttonStrokeColor), actionButtonsTextColor: PresentationThemeVariableColor(color: .white), textSelectionColor: accentColor.withAlphaComponent(0.2), textSelectionKnobColor: accentColor),
|
||||
outgoing: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: outgoingBubbleFillColor, gradientFill: outgoingBubbleFillGradientColor, highlightedFill: highlightedOutgoingBubbleColor, stroke: outgoingBubbleFillColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: outgoingBubbleFillColor, gradientFill: outgoingBubbleFillGradientColor, highlightedFill: highlightedOutgoingBubbleColor, stroke: outgoingBubbleFillColor, shadow: nil)), primaryTextColor: outgoingPrimaryTextColor, secondaryTextColor: outgoingSecondaryTextColor, linkTextColor: outgoingLinkTextColor, linkHighlightColor: UIColor.white.withAlphaComponent(0.5), scamColor: outgoingScamColor, textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: outgoingPrimaryTextColor, accentControlColor: outgoingPrimaryTextColor, accentControlDisabledColor: mainSecondaryTextColor.withAlphaComponent(0.5), mediaActiveControlColor: outgoingPrimaryTextColor, mediaInactiveControlColor: outgoingSecondaryTextColor, mediaControlInnerBackgroundColor: outgoingBubbleFillColor, pendingActivityColor: outgoingSecondaryTextColor, fileTitleColor: outgoingPrimaryTextColor, fileDescriptionColor: outgoingSecondaryTextColor, fileDurationColor: outgoingSecondaryTextColor, mediaPlaceholderColor: accentColor.withMultiplied(hue: 1.019, saturation: 0.804, brightness: 0.51), polls: PresentationThemeChatBubblePolls(radioButton: outgoingPrimaryTextColor, radioProgress: accentColor.withMultiplied(hue: 0.99, saturation: 0.56, brightness: 1.0), highlight: accentColor.withMultiplied(hue: 0.99, saturation: 0.56, brightness: 1.0).withAlphaComponent(0.12), separator: mainSeparatorColor, bar: outgoingPrimaryTextColor, barIconForeground: .clear, barPositive: outgoingPrimaryTextColor, barNegative: outgoingPrimaryTextColor), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: additionalBackgroundColor.withAlphaComponent(0.5), withoutWallpaper: additionalBackgroundColor.withAlphaComponent(0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: buttonStrokeColor), actionButtonsTextColor: PresentationThemeVariableColor(color: .white), textSelectionColor: UIColor.white.withAlphaComponent(0.2), textSelectionKnobColor: UIColor.white),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: mainBackgroundColor, highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: mainBackgroundColor, highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil)),
|
||||
incoming: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [incomingFillColor], highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [incomingFillColor], highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil)), primaryTextColor: .white, secondaryTextColor: mainSecondaryTextColor.withAlphaComponent(0.5), linkTextColor: accentColor, linkHighlightColor: accentColor.withAlphaComponent(0.5), scamColor: UIColor(rgb: 0xff6767), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: accentColor, accentControlColor: accentColor, accentControlDisabledColor: mainSecondaryTextColor.withAlphaComponent(0.5), mediaActiveControlColor: accentColor, mediaInactiveControlColor: accentColor.withAlphaComponent(0.5), mediaControlInnerBackgroundColor: mainBackgroundColor, pendingActivityColor: mainSecondaryTextColor.withAlphaComponent(0.5), fileTitleColor: accentColor, fileDescriptionColor: mainSecondaryTextColor.withAlphaComponent(0.5), fileDurationColor: mainSecondaryTextColor.withAlphaComponent(0.5), mediaPlaceholderColor: accentColor.withMultiplied(hue: 1.019, saturation: 0.585, brightness: 0.23), polls: PresentationThemeChatBubblePolls(radioButton: accentColor.withMultiplied(hue: 0.995, saturation: 0.317, brightness: 0.51), radioProgress: accentColor, highlight: accentColor.withAlphaComponent(0.12), separator: mainSeparatorColor, bar: accentColor, barIconForeground: .white, barPositive: UIColor(rgb: 0x00A700), barNegative: UIColor(rgb: 0xFE3824)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: additionalBackgroundColor.withAlphaComponent(0.5), withoutWallpaper: additionalBackgroundColor.withAlphaComponent(0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: buttonStrokeColor), actionButtonsTextColor: PresentationThemeVariableColor(color: .white), textSelectionColor: accentColor.withAlphaComponent(0.2), textSelectionKnobColor: accentColor),
|
||||
outgoing: PresentationThemePartedColors(bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: outgoingBubbleFillColors, highlightedFill: highlightedOutgoingBubbleColor, stroke: outgoingBubbleFillColors[0], shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: outgoingBubbleFillColors, highlightedFill: highlightedOutgoingBubbleColor, stroke: outgoingBubbleFillColors[0], shadow: nil)), primaryTextColor: outgoingPrimaryTextColor, secondaryTextColor: outgoingSecondaryTextColor, linkTextColor: outgoingLinkTextColor, linkHighlightColor: UIColor.white.withAlphaComponent(0.5), scamColor: outgoingScamColor, textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: outgoingPrimaryTextColor, accentControlColor: outgoingPrimaryTextColor, accentControlDisabledColor: mainSecondaryTextColor.withAlphaComponent(0.5), mediaActiveControlColor: outgoingPrimaryTextColor, mediaInactiveControlColor: outgoingSecondaryTextColor, mediaControlInnerBackgroundColor: outgoingBubbleFillColors[0], pendingActivityColor: outgoingSecondaryTextColor, fileTitleColor: outgoingPrimaryTextColor, fileDescriptionColor: outgoingSecondaryTextColor, fileDurationColor: outgoingSecondaryTextColor, mediaPlaceholderColor: accentColor.withMultiplied(hue: 1.019, saturation: 0.804, brightness: 0.51), polls: PresentationThemeChatBubblePolls(radioButton: outgoingPrimaryTextColor, radioProgress: accentColor.withMultiplied(hue: 0.99, saturation: 0.56, brightness: 1.0), highlight: accentColor.withMultiplied(hue: 0.99, saturation: 0.56, brightness: 1.0).withAlphaComponent(0.12), separator: mainSeparatorColor, bar: outgoingPrimaryTextColor, barIconForeground: .clear, barPositive: outgoingPrimaryTextColor, barNegative: outgoingPrimaryTextColor), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: additionalBackgroundColor.withAlphaComponent(0.5), withoutWallpaper: additionalBackgroundColor.withAlphaComponent(0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: buttonStrokeColor), actionButtonsTextColor: PresentationThemeVariableColor(color: .white), textSelectionColor: UIColor.white.withAlphaComponent(0.2), textSelectionKnobColor: UIColor.white),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [mainBackgroundColor], highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [mainBackgroundColor], highlightedFill: highlightedIncomingBubbleColor, stroke: mainBackgroundColor, shadow: nil)),
|
||||
infoPrimaryTextColor: UIColor(rgb: 0xffffff),
|
||||
infoLinkTextColor: accentColor,
|
||||
outgoingCheckColor: outgoingCheckColor,
|
||||
|
||||
@ -35,7 +35,7 @@ public let defaultServiceBackgroundColor = UIColor(rgb: 0x000000, alpha: 0.2)
|
||||
public let defaultPresentationTheme = makeDefaultDayPresentationTheme(serviceBackgroundColor: defaultServiceBackgroundColor, day: false, preview: false)
|
||||
public let defaultDayAccentColor = UIColor(rgb: 0x007ee5)
|
||||
|
||||
public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme {
|
||||
public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme {
|
||||
if (theme.referenceTheme != .day && theme.referenceTheme != .dayClassic) {
|
||||
return theme
|
||||
}
|
||||
@ -52,14 +52,14 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
var suggestedWallpaper: TelegramWallpaper?
|
||||
|
||||
var bubbleColors = bubbleColors
|
||||
if bubbleColors == nil, editing {
|
||||
if bubbleColors.isEmpty, editing {
|
||||
if day {
|
||||
let accentColor = accentColor ?? defaultDayAccentColor
|
||||
bubbleColors = (accentColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98), accentColor)
|
||||
bubbleColors = [accentColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98).rgb, accentColor.rgb]
|
||||
} else {
|
||||
if let accentColor = accentColor, !accentColor.alpha.isZero {
|
||||
let hsb = accentColor.hsb
|
||||
bubbleColors = (UIColor(hue: hsb.0, saturation: (hsb.1 > 0.0 && hsb.2 > 0.0) ? 0.14 : 0.0, brightness: 0.79 + hsb.2 * 0.21, alpha: 1.0), nil)
|
||||
bubbleColors = [UIColor(hue: hsb.0, saturation: (hsb.1 > 0.0 && hsb.2 > 0.0) ? 0.14 : 0.0, brightness: 0.79 + hsb.2 * 0.21, alpha: 1.0).rgb]
|
||||
if accentColor.lightness > 0.705 {
|
||||
outgoingAccent = UIColor(hue: hsb.0, saturation: min(1.0, hsb.1 * 1.1), brightness: min(hsb.2, 0.6), alpha: 1.0)
|
||||
} else {
|
||||
@ -68,7 +68,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
|
||||
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings()))
|
||||
} else {
|
||||
bubbleColors = (UIColor(rgb: 0xe1ffc7), nil)
|
||||
bubbleColors = [UIColor(rgb: 0xe1ffc7).rgb]
|
||||
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings()))
|
||||
}
|
||||
}
|
||||
@ -105,8 +105,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
}
|
||||
|
||||
var incomingBubbleStrokeColor: UIColor?
|
||||
var outgoingBubbleFillColor: UIColor?
|
||||
var outgoingBubbleFillGradientColor: UIColor?
|
||||
var outgoingBubbleFillColors: [UIColor]?
|
||||
var outgoingBubbleHighlightedFill: UIColor?
|
||||
var outgoingBubbleStrokeColor: UIColor?
|
||||
var outgoingPrimaryTextColor: UIColor?
|
||||
@ -133,11 +132,11 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
outgoingBubbleStrokeColor = bubbleStrokeColor
|
||||
}
|
||||
|
||||
if let bubbleColors = bubbleColors {
|
||||
var topBubbleColor = bubbleColors.0
|
||||
var bottomBubbleColor = bubbleColors.1 ?? bubbleColors.0
|
||||
if !bubbleColors.isEmpty {
|
||||
//var topBubbleColor = UIColor(rgb: bubbleColors[0])
|
||||
//var bottomBubbleColor = UIColor(rgb: bubbleColors.last ?? bubbleColors[0])
|
||||
|
||||
if topBubbleColor.rgb != bottomBubbleColor.rgb {
|
||||
/*if topBubbleColor.rgb != bottomBubbleColor.rgb {
|
||||
let topBubbleColorLightness = topBubbleColor.lightness
|
||||
let bottomBubbleColorLightness = bottomBubbleColor.lightness
|
||||
if abs(topBubbleColorLightness - bottomBubbleColorLightness) > 0.7 {
|
||||
@ -147,23 +146,22 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
bottomBubbleColor = bottomBubbleColor.withMultiplied(hue: 1.0, saturation: 1.0, brightness: 0.85)
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
outgoingBubbleFillColor = topBubbleColor
|
||||
outgoingBubbleFillGradientColor = bottomBubbleColor
|
||||
outgoingBubbleFillColors = bubbleColors.map(UIColor.init(rgb:))
|
||||
|
||||
if day {
|
||||
outgoingBubbleStrokeColor = .clear
|
||||
}
|
||||
|
||||
outgoingBubbleHighlightedFill = outgoingBubbleFillColor?.withMultiplied(hue: 1.054, saturation: 1.589, brightness: 0.96)
|
||||
outgoingBubbleHighlightedFill = outgoingBubbleFillColors?.first?.withMultiplied(hue: 1.054, saturation: 1.589, brightness: 0.96)
|
||||
|
||||
let lightnessColor = bubbleColors.0.mixedWith(bubbleColors.1 ?? bubbleColors.0, alpha: 0.5)
|
||||
let lightnessColor = UIColor.average(of: bubbleColors.map(UIColor.init(rgb:)))
|
||||
if lightnessColor.lightness > 0.705 {
|
||||
let hueFactor: CGFloat = 0.75
|
||||
let saturationFactor: CGFloat = 1.1
|
||||
outgoingPrimaryTextColor = UIColor(rgb: 0x000000)
|
||||
outgoingSecondaryTextColor = outgoingBubbleFillColor?.withMultiplied(hue: 1.344 * hueFactor, saturation: 4.554 * saturationFactor, brightness: 0.549).withAlphaComponent(0.8)
|
||||
outgoingSecondaryTextColor = outgoingBubbleFillColors?.first?.withMultiplied(hue: 1.344 * hueFactor, saturation: 4.554 * saturationFactor, brightness: 0.549).withAlphaComponent(0.8)
|
||||
|
||||
if let outgoingAccent = outgoingAccent {
|
||||
outgoingAccentTextColor = outgoingAccent
|
||||
@ -192,13 +190,13 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
}
|
||||
outgoingPendingActivityColor = outgoingCheckColor
|
||||
|
||||
outgoingFileDescriptionColor = outgoingBubbleFillColor?.withMultiplied(hue: 1.257 * hueFactor, saturation: 1.842, brightness: 0.698)
|
||||
outgoingFileDurationColor = outgoingBubbleFillColor?.withMultiplied(hue: 1.344 * hueFactor, saturation: 4.554, brightness: 0.549).withAlphaComponent(0.8)
|
||||
outgoingMediaPlaceholderColor = outgoingBubbleFillColor?.withMultiplied(hue: 0.998, saturation: 1.129, brightness: 0.949)
|
||||
outgoingPollsButtonColor = outgoingBubbleFillColor?.withMultiplied(hue: 1.207 * hueFactor, saturation: 1.721, brightness: 0.851)
|
||||
outgoingFileDescriptionColor = outgoingBubbleFillColors?.first?.withMultiplied(hue: 1.257 * hueFactor, saturation: 1.842, brightness: 0.698)
|
||||
outgoingFileDurationColor = outgoingBubbleFillColors?.first?.withMultiplied(hue: 1.344 * hueFactor, saturation: 4.554, brightness: 0.549).withAlphaComponent(0.8)
|
||||
outgoingMediaPlaceholderColor = outgoingBubbleFillColors?.first?.withMultiplied(hue: 0.998, saturation: 1.129, brightness: 0.949)
|
||||
outgoingPollsButtonColor = outgoingBubbleFillColors?.first?.withMultiplied(hue: 1.207 * hueFactor, saturation: 1.721, brightness: 0.851)
|
||||
|
||||
if day {
|
||||
if let distance = outgoingBubbleFillColor?.distance(to: UIColor(rgb: 0xffffff)), distance < 200 {
|
||||
if let distance = outgoingBubbleFillColors?.first?.distance(to: UIColor(rgb: 0xffffff)), distance < 200 {
|
||||
outgoingBubbleStrokeColor = UIColor(rgb: 0xc8c7cc)
|
||||
}
|
||||
}
|
||||
@ -214,7 +212,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
outgoingFileTitleColor = outgoingPrimaryTextColor
|
||||
outgoingFileDescriptionColor = outgoingSecondaryTextColor
|
||||
outgoingFileDurationColor = outgoingSecondaryTextColor
|
||||
outgoingMediaPlaceholderColor = outgoingBubbleFillColor?.withMultipliedBrightnessBy(0.95)
|
||||
outgoingMediaPlaceholderColor = outgoingBubbleFillColors?.first?.withMultipliedBrightnessBy(0.95)
|
||||
outgoingPollsButtonColor = outgoingSecondaryTextColor
|
||||
outgoingPollsProgressColor = outgoingPrimaryTextColor
|
||||
outgoingSelectionBaseColor = UIColor(rgb: 0xffffff)
|
||||
@ -268,14 +266,12 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
outgoing: chat.message.outgoing.withUpdated(
|
||||
bubble: chat.message.outgoing.bubble.withUpdated(
|
||||
withWallpaper: chat.message.outgoing.bubble.withWallpaper.withUpdated(
|
||||
fill: outgoingBubbleFillColor,
|
||||
gradientFill: outgoingBubbleFillGradientColor,
|
||||
fill: outgoingBubbleFillColors,
|
||||
highlightedFill: outgoingBubbleHighlightedFill,
|
||||
stroke: outgoingBubbleStrokeColor
|
||||
),
|
||||
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
|
||||
fill: outgoingBubbleFillColor,
|
||||
gradientFill: outgoingBubbleFillGradientColor,
|
||||
fill: outgoingBubbleFillColors,
|
||||
highlightedFill: outgoingBubbleHighlightedFill,
|
||||
stroke: outgoingBubbleStrokeColor
|
||||
)
|
||||
@ -532,7 +528,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
|
||||
let message = PresentationThemeChatMessage(
|
||||
incoming: PresentationThemePartedColors(
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xffffff), highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: bubbleStrokeColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xffffff), highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: bubbleStrokeColor, shadow: nil)),
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xffffff)], highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: bubbleStrokeColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xffffff)], highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: bubbleStrokeColor, shadow: nil)),
|
||||
primaryTextColor: UIColor(rgb: 0x000000),
|
||||
secondaryTextColor: UIColor(rgb: 0x525252, alpha: 0.6),
|
||||
linkTextColor: UIColor(rgb: 0x004bad),
|
||||
@ -554,7 +550,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: serviceBackgroundColor, withoutWallpaper: UIColor(rgb: 0x596e89, alpha: 0.35)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: .clear),
|
||||
actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0x007ee5, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0x007ee5)),
|
||||
outgoing: PresentationThemePartedColors(
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xe1ffc7), highlightedFill: UIColor(rgb: 0xc8ffa6), stroke: bubbleStrokeColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xe1ffc7), highlightedFill: UIColor(rgb: 0xc8ffa6), stroke: bubbleStrokeColor, shadow: nil)),
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xe1ffc7)], highlightedFill: UIColor(rgb: 0xc8ffa6), stroke: bubbleStrokeColor, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xe1ffc7)], highlightedFill: UIColor(rgb: 0xc8ffa6), stroke: bubbleStrokeColor, shadow: nil)),
|
||||
primaryTextColor: UIColor(rgb: 0x000000),
|
||||
secondaryTextColor: UIColor(rgb: 0x008c09, alpha: 0.8),
|
||||
linkTextColor: UIColor(rgb: 0x004bad),
|
||||
@ -578,7 +574,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)),
|
||||
textSelectionColor: UIColor(rgb: 0xbbde9f),
|
||||
textSelectionKnobColor: UIColor(rgb: 0x3fc33b)),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xffffff), highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: UIColor(rgb: 0x86a9c9, alpha: 0.5), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xffffff), highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: UIColor(rgb: 0x86a9c9, alpha: 0.5), shadow: nil)),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xffffff)], highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: UIColor(rgb: 0x86a9c9, alpha: 0.5), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xffffff)], highlightedFill: UIColor(rgb: 0xd9f4ff), stroke: UIColor(rgb: 0x86a9c9, alpha: 0.5), shadow: nil)),
|
||||
infoPrimaryTextColor: UIColor(rgb: 0x000000),
|
||||
infoLinkTextColor: UIColor(rgb: 0x004bad),
|
||||
outgoingCheckColor: UIColor(rgb: 0x19c700),
|
||||
@ -597,7 +593,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
|
||||
let messageDay = PresentationThemeChatMessage(
|
||||
incoming: PresentationThemePartedColors(
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xffffff), highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xffffff), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xf1f1f4), highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xf1f1f4), shadow: nil)),
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xffffff)], highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xffffff), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xf1f1f4)], highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xf1f1f4), shadow: nil)),
|
||||
primaryTextColor: UIColor(rgb: 0x000000),
|
||||
secondaryTextColor: UIColor(rgb: 0x525252, alpha: 0.6),
|
||||
linkTextColor: UIColor(rgb: 0x004bad),
|
||||
@ -622,7 +618,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
textSelectionColor: UIColor(rgb: 0x007ee5, alpha: 0.3),
|
||||
textSelectionKnobColor: UIColor(rgb: 0x007ee5)),
|
||||
outgoing: PresentationThemePartedColors(
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x57b2e0), gradientFill: UIColor(rgb: 0x007ee5), highlightedFill: UIColor(rgb: 0x57b2e0).withMultipliedBrightnessBy(0.7), stroke: .clear, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0x57b2e0), gradientFill: UIColor(rgb: 0x007ee5), highlightedFill: UIColor(rgb: 0x57b2e0).withMultipliedBrightnessBy(0.7), stroke: .clear, shadow: nil)),
|
||||
bubble: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x57b2e0), UIColor(rgb: 0x007ee5)], highlightedFill: UIColor(rgb: 0x57b2e0).withMultipliedBrightnessBy(0.7), stroke: .clear, shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0x57b2e0), UIColor(rgb: 0x007ee5)], highlightedFill: UIColor(rgb: 0x57b2e0).withMultipliedBrightnessBy(0.7), stroke: .clear, shadow: nil)),
|
||||
primaryTextColor: UIColor(rgb: 0xffffff),
|
||||
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.65),
|
||||
linkTextColor: UIColor(rgb: 0xffffff),
|
||||
@ -646,7 +642,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
actionButtonsTextColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0xffffff), withoutWallpaper: UIColor(rgb: 0x007ee5)),
|
||||
textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2),
|
||||
textSelectionKnobColor: UIColor(rgb: 0xffffff)),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xe5e5ea), highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xe5e5ea), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: UIColor(rgb: 0xe5e5ea), highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xe5e5ea), shadow: nil)),
|
||||
freeform: PresentationThemeBubbleColor(withWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xe5e5ea)], highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xe5e5ea), shadow: nil), withoutWallpaper: PresentationThemeBubbleColorComponents(fill: [UIColor(rgb: 0xe5e5ea)], highlightedFill: UIColor(rgb: 0xdadade), stroke: UIColor(rgb: 0xe5e5ea), shadow: nil)),
|
||||
infoPrimaryTextColor: UIColor(rgb: 0x000000),
|
||||
infoLinkTextColor: UIColor(rgb: 0x004bad),
|
||||
outgoingCheckColor: UIColor(rgb: 0xffffff),
|
||||
|
||||
@ -19,8 +19,8 @@ public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeRefe
|
||||
return theme
|
||||
}
|
||||
|
||||
public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, title: String? = nil, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: (UIColor, UIColor?)?, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
if accentColor == nil && bubbleColors == nil && backgroundColors.isEmpty && wallpaper == nil {
|
||||
public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, title: String? = nil, accentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
if accentColor == nil && bubbleColors.isEmpty && backgroundColors.isEmpty && wallpaper == nil {
|
||||
return theme
|
||||
}
|
||||
switch theme.referenceTheme {
|
||||
@ -35,10 +35,10 @@ public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool
|
||||
|
||||
public func makePresentationTheme(settings: TelegramThemeSettings, title: String? = nil, serviceBackgroundColor: UIColor? = nil) -> PresentationTheme? {
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference(baseTheme: settings.baseTheme), extendingThemeReference: nil, serviceBackgroundColor: serviceBackgroundColor, preview: false)
|
||||
return customizePresentationTheme(defaultTheme, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: settings.wallpaper)
|
||||
return customizePresentationTheme(defaultTheme, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors, wallpaper: settings.wallpaper)
|
||||
}
|
||||
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, backgroundColors: [UInt32] = [], bubbleColors: (UIColor, UIColor?)? = nil, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? {
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, backgroundColors: [UInt32] = [], bubbleColors: [UInt32] = [], wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? {
|
||||
let theme: PresentationTheme
|
||||
switch themeReference {
|
||||
case let .builtin(reference):
|
||||
@ -52,7 +52,7 @@ public func makePresentationTheme(mediaBox: MediaBox, themeReference: Presentati
|
||||
}
|
||||
case let .cloud(info):
|
||||
if let settings = info.theme.settings {
|
||||
if let loadedTheme = makePresentationTheme(mediaBox: mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), extendingThemeReference: themeReference, accentColor: accentColor ?? UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: bubbleColors ?? settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: wallpaper ?? settings.wallpaper, serviceBackgroundColor: serviceBackgroundColor, preview: preview) {
|
||||
if let loadedTheme = makePresentationTheme(mediaBox: mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), extendingThemeReference: themeReference, accentColor: accentColor ?? UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: bubbleColors.isEmpty ? settings.messageColors : bubbleColors, wallpaper: wallpaper ?? settings.wallpaper, serviceBackgroundColor: serviceBackgroundColor, preview: preview) {
|
||||
theme = loadedTheme
|
||||
} else {
|
||||
return nil
|
||||
|
||||
@ -292,7 +292,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager, s
|
||||
}
|
||||
|
||||
let effectiveColors = themeSettings.themeSpecificAccentColors[effectiveTheme.index]
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: effectiveTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors, baseColor: effectiveColors?.baseColor) ?? defaultPresentationTheme
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: effectiveTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors ?? [], baseColor: effectiveColors?.baseColor) ?? defaultPresentationTheme
|
||||
|
||||
|
||||
let effectiveChatWallpaper: TelegramWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: effectiveTheme, accentColor: effectiveColors)] ?? themeSettings.themeSpecificChatWallpapers[effectiveTheme.index]) ?? theme.chat.defaultWallpaper
|
||||
@ -583,7 +583,7 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI
|
||||
if let themeSpecificWallpaper = themeSpecificWallpaper {
|
||||
currentWallpaper = themeSpecificWallpaper
|
||||
} else {
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: themeSettings.theme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors, wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor) ?? defaultPresentationTheme
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: themeSettings.theme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor) ?? defaultPresentationTheme
|
||||
currentWallpaper = theme.chat.defaultWallpaper
|
||||
}
|
||||
|
||||
@ -619,7 +619,7 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI
|
||||
effectiveColors = nil
|
||||
}
|
||||
|
||||
let themeValue = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: effectiveTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors, wallpaper: effectiveColors?.wallpaper, baseColor: effectiveColors?.baseColor, serviceBackgroundColor: serviceBackgroundColor) ?? defaultPresentationTheme
|
||||
let themeValue = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: effectiveTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors ?? [], wallpaper: effectiveColors?.wallpaper, baseColor: effectiveColors?.baseColor, serviceBackgroundColor: serviceBackgroundColor) ?? defaultPresentationTheme
|
||||
|
||||
if autoNightModeTriggered && !switchedToNightModeWallpaper {
|
||||
switch effectiveChatWallpaper {
|
||||
|
||||
@ -635,22 +635,20 @@ public struct PresentationThemeBubbleShadow {
|
||||
}
|
||||
|
||||
public final class PresentationThemeBubbleColorComponents {
|
||||
public let fill: UIColor
|
||||
public let gradientFill: UIColor
|
||||
public let fill: [UIColor]
|
||||
public let highlightedFill: UIColor
|
||||
public let stroke: UIColor
|
||||
public let shadow: PresentationThemeBubbleShadow?
|
||||
|
||||
public init(fill: UIColor, gradientFill: UIColor? = nil, highlightedFill: UIColor, stroke: UIColor, shadow: PresentationThemeBubbleShadow?) {
|
||||
public init(fill: [UIColor], highlightedFill: UIColor, stroke: UIColor, shadow: PresentationThemeBubbleShadow?) {
|
||||
self.fill = fill
|
||||
self.gradientFill = gradientFill ?? fill
|
||||
self.highlightedFill = highlightedFill
|
||||
self.stroke = stroke
|
||||
self.shadow = shadow
|
||||
}
|
||||
|
||||
public func withUpdated(fill: UIColor? = nil, gradientFill: UIColor? = nil, highlightedFill: UIColor? = nil, stroke: UIColor? = nil) -> PresentationThemeBubbleColorComponents {
|
||||
return PresentationThemeBubbleColorComponents(fill: fill ?? self.fill, gradientFill: gradientFill ?? self.gradientFill, highlightedFill: highlightedFill ?? self.highlightedFill, stroke: stroke ?? self.stroke, shadow: self.shadow)
|
||||
public func withUpdated(fill: [UIColor]? = nil, highlightedFill: UIColor? = nil, stroke: UIColor? = nil) -> PresentationThemeBubbleColorComponents {
|
||||
return PresentationThemeBubbleColorComponents(fill: fill ?? self.fill, highlightedFill: highlightedFill ?? self.highlightedFill, stroke: stroke ?? self.stroke, shadow: self.shadow)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,37 @@ private func encodeColor<Key>(_ values: inout KeyedEncodingContainer<Key>, _ val
|
||||
}
|
||||
}
|
||||
|
||||
private func decodeColorList<Key>(_ values: KeyedDecodingContainer<Key>, _ key: Key) throws -> [UIColor] {
|
||||
let colorValues = try values.decode([String].self, forKey: key)
|
||||
|
||||
var result: [UIColor] = []
|
||||
for value in colorValues {
|
||||
if value.lowercased() == "clear" {
|
||||
result.append(UIColor.clear)
|
||||
} else if let color = UIColor(hexString: value) {
|
||||
result.append(color)
|
||||
} else {
|
||||
throw PresentationThemeDecodingError.generic
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private func encodeColorList<Key>(_ values: inout KeyedEncodingContainer<Key>, _ colors: [UIColor], _ key: Key) throws {
|
||||
var stringList: [String] = []
|
||||
for value in colors {
|
||||
if value == UIColor.clear {
|
||||
stringList.append("clear")
|
||||
} else if value.alpha < 1.0 {
|
||||
stringList.append(String(format: "%08x", value.argb))
|
||||
} else {
|
||||
stringList.append(String(format: "%06x", value.rgb))
|
||||
}
|
||||
}
|
||||
try values.encode(stringList, forKey: key)
|
||||
}
|
||||
|
||||
extension TelegramWallpaper: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.singleValueContainer()
|
||||
@ -1070,22 +1101,30 @@ extension PresentationThemeBubbleColorComponents: Codable {
|
||||
case highlightedBg
|
||||
case stroke
|
||||
case shadow
|
||||
case bgList
|
||||
}
|
||||
|
||||
public convenience init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let codingPath = decoder.codingPath.map { $0.stringValue }.joined(separator: ".")
|
||||
|
||||
var fillColor = try decodeColor(values, .bg)
|
||||
var gradientColor = try decodeColor(values, .gradientBg, decoder: decoder, fallbackKey: "\(codingPath).bg")
|
||||
if gradientColor.rgb != fillColor.rgb {
|
||||
fillColor = fillColor.withAlphaComponent(1.0)
|
||||
gradientColor = gradientColor.withAlphaComponent(1.0)
|
||||
|
||||
let fill: [UIColor]
|
||||
|
||||
if let bgList = try? decodeColorList(values, .bgList) {
|
||||
fill = bgList
|
||||
} else {
|
||||
var fillColor = try decodeColor(values, .bg)
|
||||
var gradientColor = try decodeColor(values, .gradientBg, decoder: decoder, fallbackKey: "\(codingPath).bg")
|
||||
if gradientColor.rgb != fillColor.rgb {
|
||||
fillColor = fillColor.withAlphaComponent(1.0)
|
||||
gradientColor = gradientColor.withAlphaComponent(1.0)
|
||||
}
|
||||
|
||||
fill = [fillColor, gradientColor]
|
||||
}
|
||||
|
||||
|
||||
self.init(
|
||||
fill: fillColor,
|
||||
gradientFill: gradientColor,
|
||||
fill: fill,
|
||||
highlightedFill: try decodeColor(values, .highlightedBg),
|
||||
stroke: try decodeColor(values, .stroke),
|
||||
shadow: try? values.decode(PresentationThemeBubbleShadow.self, forKey: .shadow)
|
||||
@ -1094,8 +1133,17 @@ extension PresentationThemeBubbleColorComponents: Codable {
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var values = encoder.container(keyedBy: CodingKeys.self)
|
||||
try encodeColor(&values, self.fill, .bg)
|
||||
try encodeColor(&values, self.gradientFill, .gradientBg)
|
||||
if self.fill.count <= 2 {
|
||||
if self.fill.count > 1 {
|
||||
try encodeColor(&values, self.fill[0], .bg)
|
||||
try encodeColor(&values, self.fill[1], .gradientBg)
|
||||
} else {
|
||||
try encodeColor(&values, self.fill[0], .bg)
|
||||
try encodeColor(&values, self.fill[0], .gradientBg)
|
||||
}
|
||||
} else {
|
||||
try encodeColorList(&values, self.fill, .bgList)
|
||||
}
|
||||
try encodeColor(&values, self.highlightedFill, .highlightedBg)
|
||||
try encodeColor(&values, self.stroke, .stroke)
|
||||
}
|
||||
|
||||
@ -199,18 +199,23 @@ public final class PrincipalThemeEssentialGraphics {
|
||||
let incoming: PresentationThemeBubbleColorComponents = wallpaper.isEmpty ? theme.message.incoming.bubble.withoutWallpaper : theme.message.incoming.bubble.withWallpaper
|
||||
let outgoing: PresentationThemeBubbleColorComponents = wallpaper.isEmpty ? theme.message.outgoing.bubble.withoutWallpaper : theme.message.outgoing.bubble.withWallpaper
|
||||
|
||||
var incomingGradientColors: (UIColor, UIColor)?
|
||||
if incoming.fill.rgb != incoming.gradientFill.rgb {
|
||||
incomingGradientColors = (incoming.fill, incoming.gradientFill)
|
||||
var incomingGradientColors: [UIColor]?
|
||||
if Set(incoming.fill.map(\.argb)).count > 1 {
|
||||
incomingGradientColors = incoming.fill
|
||||
}
|
||||
if let incomingGradientColors = incomingGradientColors {
|
||||
self.incomingBubbleGradientImage = generateImage(CGSize(width: 1.0, height: 512.0), opaque: true, scale: 1.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
let colors = [incomingGradientColors.0.cgColor, incomingGradientColors.1.cgColor] as NSArray
|
||||
var locations: [CGFloat] = []
|
||||
var colors: [CGColor] = []
|
||||
for i in 0 ..< incomingGradientColors.count {
|
||||
let t = CGFloat(i) / CGFloat(incomingGradientColors.count - 1)
|
||||
locations.append(t)
|
||||
colors.append(incomingGradientColors[i].cgColor)
|
||||
}
|
||||
|
||||
let colorSpace = deviceColorSpace
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)!
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as NSArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
})
|
||||
@ -218,18 +223,23 @@ public final class PrincipalThemeEssentialGraphics {
|
||||
self.incomingBubbleGradientImage = nil
|
||||
}
|
||||
|
||||
var outgoingGradientColors: (UIColor, UIColor)?
|
||||
if outgoing.fill.rgb != outgoing.gradientFill.rgb {
|
||||
outgoingGradientColors = (outgoing.fill, outgoing.gradientFill)
|
||||
var outgoingGradientColors: [UIColor]?
|
||||
if Set(outgoing.fill.map(\.argb)).count > 1 {
|
||||
outgoingGradientColors = outgoing.fill
|
||||
}
|
||||
if let outgoingGradientColors = outgoingGradientColors {
|
||||
self.outgoingBubbleGradientImage = generateImage(CGSize(width: 1.0, height: 512.0), opaque: true, scale: 1.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
let colors = [outgoingGradientColors.0.cgColor, outgoingGradientColors.1.cgColor] as NSArray
|
||||
var locations: [CGFloat] = []
|
||||
var colors: [CGColor] = []
|
||||
for i in 0 ..< outgoingGradientColors.count {
|
||||
let t = CGFloat(i) / CGFloat(outgoingGradientColors.count - 1)
|
||||
locations.append(t)
|
||||
colors.append(outgoingGradientColors[i].cgColor)
|
||||
}
|
||||
|
||||
let colorSpace = deviceColorSpace
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)!
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as NSArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
})
|
||||
@ -249,73 +259,73 @@ public final class PrincipalThemeEssentialGraphics {
|
||||
if preview {
|
||||
self.chatMessageBackgroundIncomingMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .none, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingExtractedMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: UIColor.black, strokeColor: UIColor.clear, neighbors: .extracted, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .none, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .extracted, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.checkBubbleFullImage = generateCheckImage(partial: false, color: theme.message.outgoingCheckColor, width: 11.0)!
|
||||
self.checkBubblePartialImage = generateCheckImage(partial: true, color: theme.message.outgoingCheckColor, width: 11.0)!
|
||||
self.chatMessageBackgroundIncomingHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundIncomingMergedTopMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .top(side: false), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundIncomingMergedTopSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .top(side: true), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundIncomingMergedBottomMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .bottom, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundIncomingMergedBothMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .both, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
|
||||
self.chatMessageBackgroundIncomingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundIncomingMergedSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .side, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
|
||||
self.chatMessageBackgroundIncomingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .side, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundOutgoingHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundOutgoingMergedTopMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .top(side: false), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .top(side: true), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundOutgoingMergedBottomMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .bottom, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundOutgoingMergedBothMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .both, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothHighlightedImage = emptyImage
|
||||
self.chatMessageBackgroundOutgoingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideHighlightedImage = emptyImage
|
||||
self.checkMediaFullImage = emptyImage
|
||||
self.checkMediaPartialImage = emptyImage
|
||||
@ -361,70 +371,70 @@ public final class PrincipalThemeEssentialGraphics {
|
||||
} else {
|
||||
self.chatMessageBackgroundIncomingMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .none, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingExtractedMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .extracted, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .top(side: false), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .top(side: true), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedTopSideHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .bottom, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBottomHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .both, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedBothHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout, extendedEdges: true)
|
||||
|
||||
self.chatMessageBackgroundOutgoingMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .none, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .extracted, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingExtractedOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .extracted, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .top(side: false), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .top(side: true), theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedTopSideHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .bottom, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBottomHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .both, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedBothHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
|
||||
self.chatMessageBackgroundIncomingMergedSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: .black, strokeColor: .clear, neighbors: .side, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.fill[0], strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideMaskImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: .black, strokeColor: .clear, neighbors: .side, theme: theme, wallpaper: .color(0xffffff), knockout: true, mask: true, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideOutlineImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyOutline: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideShadowImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.fill[0], strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true, onlyShadow: true)
|
||||
self.chatMessageBackgroundIncomingMergedSideHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
self.chatMessageBackgroundOutgoingMergedSideHighlightedImage = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: minCornerRadius, incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout, extendedEdges: true)
|
||||
|
||||
|
||||
@ -152,14 +152,14 @@ public struct PresentationResourcesChat {
|
||||
public static func chatInstantVideoBackgroundImage(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? {
|
||||
let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatInstantVideoWithoutWallpaperBackgroundImage : PresentationResourceKey.chatInstantVideoWithWallpaperBackgroundImage
|
||||
return theme.image(key.rawValue, { theme in
|
||||
return generateInstantVideoBackground(fillColor: theme.chat.message.freeform.withWallpaper.fill, strokeColor: theme.chat.message.freeform.withWallpaper.stroke)
|
||||
return generateInstantVideoBackground(fillColor: theme.chat.message.freeform.withWallpaper.fill[0], strokeColor: theme.chat.message.freeform.withWallpaper.stroke)
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatActionPhotoBackgroundImage(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? {
|
||||
let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatActionPhotoWithoutWallpaperBackgroundImage : PresentationResourceKey.chatActionPhotoWithWallpaperBackgroundImage
|
||||
return theme.image(key.rawValue, { theme in
|
||||
return generateActionPhotoBackground(fillColor: theme.chat.message.freeform.withWallpaper.fill, strokeColor: theme.chat.message.freeform.withWallpaper.stroke)
|
||||
return generateActionPhotoBackground(fillColor: theme.chat.message.freeform.withWallpaper.fill[0], strokeColor: theme.chat.message.freeform.withWallpaper.stroke)
|
||||
})
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ public struct PresentationResourcesChat {
|
||||
|
||||
public static func chatInfoItemBackgroundImageWithoutWallpaper(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInfoItemBackgroundImageWithoutWallpaper.rawValue, { theme in
|
||||
return messageSingleBubbleLikeImage(fillColor: theme.chat.message.incoming.bubble.withoutWallpaper.fill, strokeColor: theme.chat.message.incoming.bubble.withoutWallpaper.stroke)
|
||||
return messageSingleBubbleLikeImage(fillColor: theme.chat.message.incoming.bubble.withoutWallpaper.fill[0], strokeColor: theme.chat.message.incoming.bubble.withoutWallpaper.stroke)
|
||||
})
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ public struct PresentationResourcesChat {
|
||||
let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatInfoItemBackgroundImageWithoutWallpaper : PresentationResourceKey.chatInfoItemBackgroundImageWithWallpaper
|
||||
return theme.image(key.rawValue, { theme in
|
||||
let components: PresentationThemeBubbleColorComponents = wallpaper ? theme.chat.message.incoming.bubble.withWallpaper : theme.chat.message.incoming.bubble.withoutWallpaper
|
||||
return messageSingleBubbleLikeImage(fillColor: components.fill, strokeColor: components.stroke)
|
||||
return messageSingleBubbleLikeImage(fillColor: components.fill[0], strokeColor: components.stroke)
|
||||
})
|
||||
}
|
||||
|
||||
@ -827,7 +827,7 @@ public struct PresentationResourcesChat {
|
||||
public static func chatMessageAttachedContentHighlightedButtonIconInstantIncoming(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? {
|
||||
let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantIncomingWithoutWallpaper : PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantIncomingWithWallpaper
|
||||
return theme.image(key.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: bubbleColorComponents(theme: theme, incoming: true, wallpaper: wallpaper).fill)
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: bubbleColorComponents(theme: theme, incoming: true, wallpaper: wallpaper).fill[0])
|
||||
})
|
||||
}
|
||||
|
||||
@ -840,7 +840,7 @@ public struct PresentationResourcesChat {
|
||||
public static func chatMessageAttachedContentHighlightedButtonIconInstantOutgoing(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? {
|
||||
let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantOutgoingWithoutWallpaper : PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantOutgoingWithWallpaper
|
||||
return theme.image(key.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: bubbleColorComponents(theme: theme, incoming: false, wallpaper: wallpaper).fill)
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: bubbleColorComponents(theme: theme, incoming: false, wallpaper: wallpaper).fill[0])
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
12
submodules/TelegramUI/Images.xcassets/Chat/OverscrollFolder.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/OverscrollFolder.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Folder.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
3
submodules/TelegramUI/Images.xcassets/Chat/OverscrollFolder.imageset/Folder.svg
vendored
Normal file
3
submodules/TelegramUI/Images.xcassets/Chat/OverscrollFolder.imageset/Folder.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 14.8492C0 12.2016 0 10.8779 0.20805 9.77516C1.12392 4.92093 4.92093 1.12392 9.77516 0.208051C10.8779 4.02331e-07 12.2016 0 14.8492 0H16.7574C19.4739 0 22.0791 1.07913 24 3C25.9209 4.92087 28.5261 6 31.2426 6H36.8C43.5206 6 46.8809 6 49.4479 7.30792C51.7058 8.4584 53.5416 10.2942 54.6921 12.5521C56 15.1191 56 18.4794 56 25.2V36.8C56 43.5206 56 46.8809 54.6921 49.4479C53.5416 51.7058 51.7058 53.5416 49.4479 54.6921C46.8809 56 43.5206 56 36.8 56H19.2C12.4794 56 9.11906 56 6.55211 54.6921C4.29417 53.5416 2.4584 51.7058 1.30792 49.4479C0 46.8809 0 43.5206 0 36.8V14.8492Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 744 B |
@ -386,7 +386,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if nextType == nil {
|
||||
if MFMailComposeViewController.canSendMail(), let controller = controller {
|
||||
let formattedNumber = formatPhoneNumber(number)
|
||||
strongSelf.presentEmailComposeController(address: "sms@stel.com", subject: strongSelf.presentationData.strings.Login_EmailCodeSubject(formattedNumber).string, body: strongSelf.presentationData.strings.Login_EmailCodeBody(formattedNumber).string, from: controller)
|
||||
strongSelf.presentEmailComposeController(address: "reports@stel.com", subject: strongSelf.presentationData.strings.Login_EmailCodeSubject(formattedNumber).string, body: strongSelf.presentationData.strings.Login_EmailCodeBody(formattedNumber).string, from: controller)
|
||||
} else {
|
||||
controller?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: strongSelf.presentationData.strings.Login_EmailNotConfiguredError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
public weak var parentController: ViewController?
|
||||
|
||||
private let currentChatListFilter: ChatListFilterData?
|
||||
private let currentChatListFilter: Int32?
|
||||
|
||||
public var peekActions: ChatControllerPeekActions = .standard
|
||||
private var didSetup3dTouch: Bool = false
|
||||
@ -465,7 +465,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
private var nextChannelToReadDisposable: Disposable?
|
||||
|
||||
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: ChatListFilterData? = nil) {
|
||||
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: Int32? = nil) {
|
||||
let _ = ChatControllerCount.modify { value in
|
||||
return value + 1
|
||||
}
|
||||
@ -3314,7 +3314,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let channel = renderedPeer?.chatMainPeer as? TelegramChannel, case .broadcast = channel.info {
|
||||
if strongSelf.nextChannelToReadDisposable == nil {
|
||||
strongSelf.nextChannelToReadDisposable = (combineLatest(queue: .mainQueue(),
|
||||
strongSelf.context.engine.peers.getNextUnreadChannel(peerId: channel.id, filter: strongSelf.currentChatListFilter.flatMap(chatListFilterPredicate)),
|
||||
strongSelf.context.engine.peers.getNextUnreadChannel(peerId: channel.id, chatListFilterId: strongSelf.currentChatListFilter, getFilterPredicate: chatListFilterPredicate),
|
||||
ApplicationSpecificNotice.getNextChatSuggestionTip(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||
)
|
||||
|> then(.complete() |> delay(1.0, queue: .mainQueue()))
|
||||
@ -3324,8 +3324,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
strongSelf.chatDisplayNode.historyNode.offerNextChannelToRead = true
|
||||
strongSelf.chatDisplayNode.historyNode.nextChannelToRead = nextPeer.flatMap { nextPeer -> (peer: EnginePeer, unreadCount: Int) in
|
||||
return (peer: nextPeer.peer, unreadCount: nextPeer.unreadCount)
|
||||
strongSelf.chatDisplayNode.historyNode.nextChannelToRead = nextPeer.flatMap { nextPeer -> (peer: EnginePeer, unreadCount: Int, location: TelegramEngine.NextUnreadChannelLocation) in
|
||||
return (peer: nextPeer.peer, unreadCount: nextPeer.unreadCount, location: nextPeer.location)
|
||||
}
|
||||
strongSelf.chatDisplayNode.historyNode.nextChannelToReadDisplayName = nextChatSuggestionTip >= 3
|
||||
|
||||
@ -7075,7 +7075,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
})
|
||||
|
||||
self.chatDisplayNode.historyNode.openNextChannelToRead = { [weak self] peer in
|
||||
self.chatDisplayNode.historyNode.openNextChannelToRead = { [weak self] peer, location in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -7086,6 +7086,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
titleViewSnapshotState: strongSelf.chatTitleView?.prepareSnapshotState(),
|
||||
avatarSnapshotState: (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.prepareSnapshotState()
|
||||
)
|
||||
|
||||
var nextFolderId: Int32?
|
||||
switch location {
|
||||
case let .folder(id, _):
|
||||
nextFolderId = id
|
||||
case .same:
|
||||
nextFolderId = strongSelf.currentChatListFilter
|
||||
default:
|
||||
nextFolderId = nil
|
||||
}
|
||||
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), animated: false, chatListFilter: strongSelf.currentChatListFilter, completion: { nextController in
|
||||
(nextController as! ChatControllerImpl).animateFromPreviousController(snapshotState: snapshotState)
|
||||
}))
|
||||
|
||||
@ -549,13 +549,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
var isSelectionGestureEnabled = true
|
||||
|
||||
private var overscrollView: ComponentHostView<Empty>?
|
||||
var nextChannelToRead: (peer: EnginePeer, unreadCount: Int)?
|
||||
var nextChannelToRead: (peer: EnginePeer, unreadCount: Int, location: TelegramEngine.NextUnreadChannelLocation)?
|
||||
var offerNextChannelToRead: Bool = false
|
||||
var nextChannelToReadDisplayName: Bool = false
|
||||
private var currentOverscrollExpandProgress: CGFloat = 0.0
|
||||
private var freezeOverscrollControl: Bool = false
|
||||
private var feedback: HapticFeedback?
|
||||
var openNextChannelToRead: ((EnginePeer) -> Void)?
|
||||
var openNextChannelToRead: ((EnginePeer, TelegramEngine.NextUnreadChannelLocation) -> Void)?
|
||||
|
||||
private let clientId: Atomic<Int32>
|
||||
|
||||
@ -1171,9 +1171,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let channel = strongSelf.nextChannelToRead?.peer, strongSelf.currentOverscrollExpandProgress >= 0.99 {
|
||||
if let nextChannelToRead = strongSelf.nextChannelToRead, strongSelf.currentOverscrollExpandProgress >= 0.99 {
|
||||
strongSelf.freezeOverscrollControl = true
|
||||
strongSelf.openNextChannelToRead?(channel)
|
||||
strongSelf.openNextChannelToRead?(nextChannelToRead.peer, nextChannelToRead.location)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1239,36 +1239,59 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.currentOverscrollExpandProgress = expandProgress
|
||||
}
|
||||
|
||||
if expandProgress < 0.1 || self.nextChannelToRead == nil {
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: nil)
|
||||
} else if expandProgress >= 0.99 {
|
||||
//TODO:localize
|
||||
let text: String = "Release to go to the next unread channel"
|
||||
if chatControllerNode.inputPanelOverscrollNode?.text != text {
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode(text: text, color: self.currentPresentationData.theme.theme.rootController.navigationBar.secondaryTextColor, priority: 1))
|
||||
if let nextChannelToRead = self.nextChannelToRead {
|
||||
let swipeText: (String, [(Int, NSRange)])
|
||||
let releaseText: (String, [(Int, NSRange)])
|
||||
switch nextChannelToRead.location {
|
||||
case .same:
|
||||
swipeText = (self.currentPresentationData.strings.Chat_NextChannelSameLocationSwipeProgress, [])
|
||||
releaseText = (self.currentPresentationData.strings.Chat_NextChannelSameLocationSwipeAction, [])
|
||||
case .archived:
|
||||
swipeText = (self.currentPresentationData.strings.Chat_NextChannelArchivedSwipeProgress, [])
|
||||
releaseText = (self.currentPresentationData.strings.Chat_NextChannelArchivedSwipeAction, [])
|
||||
case .unarchived:
|
||||
swipeText = (self.currentPresentationData.strings.Chat_NextChannelUnarchivedSwipeProgress, [])
|
||||
releaseText = (self.currentPresentationData.strings.Chat_NextChannelUnarchivedSwipeAction, [])
|
||||
case let .folder(_, title):
|
||||
swipeText = self.currentPresentationData.strings.Chat_NextChannelFolderSwipeProgress(title)._tuple
|
||||
releaseText = self.currentPresentationData.strings.Chat_NextChannelFolderSwipeAction(title)._tuple
|
||||
}
|
||||
|
||||
if expandProgress < 0.1 {
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: nil)
|
||||
} else if expandProgress >= 0.99 {
|
||||
if chatControllerNode.inputPanelOverscrollNode?.text.0 != swipeText.0 {
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode(text: swipeText, color: self.currentPresentationData.theme.theme.rootController.navigationBar.secondaryTextColor, priority: 1))
|
||||
}
|
||||
} else {
|
||||
if chatControllerNode.inputPanelOverscrollNode?.text.0 != releaseText.0 {
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode(text: releaseText, color: self.currentPresentationData.theme.theme.rootController.navigationBar.secondaryTextColor, priority: 2))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//TODO:localize
|
||||
let text: String = "Swipe up to go to the next unread channel"
|
||||
if chatControllerNode.inputPanelOverscrollNode?.text != text {
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode(text: text, color: self.currentPresentationData.theme.theme.rootController.navigationBar.secondaryTextColor, priority: 2))
|
||||
}
|
||||
chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: nil)
|
||||
}
|
||||
|
||||
let overscrollSize = overscrollView.update(
|
||||
let overscrollFrame = CGRect(origin: CGPoint(x: 0.0, y: self.insets.top), size: CGSize(width: self.bounds.width, height: 94.0))
|
||||
|
||||
let _ = overscrollView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(ChatOverscrollControl(
|
||||
backgroundColor: selectDateFillStaticColor(theme: self.currentPresentationData.theme.theme, wallpaper: self.currentPresentationData.theme.wallpaper),
|
||||
foregroundColor: bubbleVariableColor(variableColor: self.currentPresentationData.theme.theme.chat.serviceMessage.dateTextColor, wallpaper: self.currentPresentationData.theme.wallpaper),
|
||||
peer: self.nextChannelToRead?.peer,
|
||||
unreadCount: self.nextChannelToRead?.unreadCount ?? 0,
|
||||
location: self.nextChannelToRead?.location ?? .same,
|
||||
context: self.context,
|
||||
expandDistance: expandDistance
|
||||
expandDistance: expandDistance,
|
||||
absoluteRect: CGRect(origin: CGPoint(x: overscrollFrame.minX, y: self.bounds.height - overscrollFrame.minY), size: overscrollFrame.size),
|
||||
absoluteSize: self.bounds.size,
|
||||
wallpaperNode: chatControllerNode.backgroundNode
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: self.bounds.width, height: 200.0)
|
||||
)
|
||||
overscrollView.frame = CGRect(origin: CGPoint(x: floor((self.bounds.width - overscrollSize.width) / 2.0), y: self.insets.top), size: overscrollSize)
|
||||
overscrollView.frame = overscrollFrame
|
||||
} else if let overscrollView = self.overscrollView {
|
||||
self.overscrollView = nil
|
||||
overscrollView.removeFromSuperview()
|
||||
|
||||
@ -731,7 +731,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
}
|
||||
titleColor = presentationData.theme.theme.chat.message.incoming.accentTextColor
|
||||
let bubbleColor = bubbleColorComponents(theme: presentationData.theme.theme, incoming: true, wallpaper: !presentationData.theme.wallpaper.isEmpty)
|
||||
titleHighlightedColor = bubbleColor.fill
|
||||
titleHighlightedColor = bubbleColor.fill[0]
|
||||
} else {
|
||||
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonOutgoing(presentationData.theme.theme)!
|
||||
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonOutgoing(presentationData.theme.theme)!
|
||||
@ -741,7 +741,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
}
|
||||
titleColor = presentationData.theme.theme.chat.message.outgoing.accentTextColor
|
||||
let bubbleColor = bubbleColorComponents(theme: presentationData.theme.theme, incoming: false, wallpaper: !presentationData.theme.wallpaper.isEmpty)
|
||||
titleHighlightedColor = bubbleColor.fill
|
||||
titleHighlightedColor = bubbleColor.fill[0]
|
||||
}
|
||||
let (buttonWidth, continueLayout) = makeButtonLayout(constrainedSize.width, buttonImage, buttonHighlightedImage, buttonIconImage, buttonHighlightedIconImage, actionTitle, titleColor, titleHighlightedColor)
|
||||
boundingSize.width = max(buttonWidth, boundingSize.width)
|
||||
|
||||
@ -77,7 +77,7 @@ func chatMessageBubbleImageContentCorners(relativeContentPosition position: Chat
|
||||
case .None:
|
||||
colors = chatPresentationData.theme.theme.chat.message.incoming.bubble.withoutWallpaper
|
||||
}
|
||||
if colors.fill == colors.stroke || colors.stroke.alpha.isZero {
|
||||
if colors.fill[0] == colors.stroke || colors.stroke.alpha.isZero {
|
||||
bubbleInsets = UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)
|
||||
} else {
|
||||
bubbleInsets = layoutConstants.bubble.strokeInsets
|
||||
@ -110,7 +110,7 @@ func chatMessageBubbleImageContentCorners(relativeContentPosition position: Chat
|
||||
if case .color = chatPresentationData.theme.wallpaper {
|
||||
let colors: PresentationThemeBubbleColorComponents
|
||||
colors = chatPresentationData.theme.theme.chat.message.incoming.bubble.withoutWallpaper
|
||||
if colors.fill == colors.stroke || colors.stroke.alpha.isZero {
|
||||
if colors.fill[0] == colors.stroke || colors.stroke.alpha.isZero {
|
||||
bubbleInsets = UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)
|
||||
} else {
|
||||
bubbleInsets = layoutConstants.bubble.strokeInsets
|
||||
@ -135,7 +135,7 @@ func chatMessageBubbleImageContentCorners(relativeContentPosition position: Chat
|
||||
if case .color = chatPresentationData.theme.wallpaper {
|
||||
let colors: PresentationThemeBubbleColorComponents
|
||||
colors = chatPresentationData.theme.theme.chat.message.outgoing.bubble.withoutWallpaper
|
||||
if colors.fill == colors.stroke || colors.stroke.alpha.isZero {
|
||||
if colors.fill[0] == colors.stroke || colors.stroke.alpha.isZero {
|
||||
bubbleInsets = UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)
|
||||
} else {
|
||||
bubbleInsets = layoutConstants.bubble.strokeInsets
|
||||
|
||||
@ -371,7 +371,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
selectionBackgroundFrame = selectionBackgroundFrame.inset(by: selectionInsets)
|
||||
|
||||
let bubbleColor = graphics.hasWallpaper ? messageTheme.bubble.withWallpaper.fill : messageTheme.bubble.withoutWallpaper.fill
|
||||
let selectionColor = bubbleColor.withAlphaComponent(1.0).mixedWith(messageTheme.accentTextColor.withAlphaComponent(1.0), alpha: 0.08)
|
||||
let selectionColor = bubbleColor[0].withAlphaComponent(1.0).mixedWith(messageTheme.accentTextColor.withAlphaComponent(1.0), alpha: 0.08)
|
||||
|
||||
self.selectionBackgroundNode?.backgroundColor = selectionColor
|
||||
self.selectionBackgroundNode?.frame = selectionBackgroundFrame
|
||||
|
||||
@ -224,7 +224,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
titleColor = item.presentationData.theme.theme.chat.message.incoming.accentTextColor
|
||||
|
||||
let bubbleColors = bubbleColorComponents(theme: item.presentationData.theme.theme, incoming: true, wallpaper: !item.presentationData.theme.wallpaper.isEmpty)
|
||||
titleHighlightedColor = bubbleColors.fill
|
||||
titleHighlightedColor = bubbleColors.fill[0]
|
||||
avatarPlaceholderColor = item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor
|
||||
} else {
|
||||
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonOutgoing(item.presentationData.theme.theme)!
|
||||
@ -232,7 +232,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
titleColor = item.presentationData.theme.theme.chat.message.outgoing.accentTextColor
|
||||
|
||||
let bubbleColors = bubbleColorComponents(theme: item.presentationData.theme.theme, incoming: false, wallpaper: !item.presentationData.theme.wallpaper.isEmpty)
|
||||
titleHighlightedColor = bubbleColors.fill
|
||||
titleHighlightedColor = bubbleColors.fill[0]
|
||||
avatarPlaceholderColor = item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor
|
||||
}
|
||||
|
||||
|
||||
@ -131,7 +131,7 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
} else {
|
||||
colors = item.presentationData.theme.theme.chat.message.outgoing.bubble.withoutWallpaper
|
||||
}
|
||||
if colors.fill == colors.stroke || colors.stroke.alpha.isZero {
|
||||
if colors.fill[0] == colors.stroke || colors.stroke.alpha.isZero {
|
||||
bubbleInsets = UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)
|
||||
} else {
|
||||
bubbleInsets = layoutConstants.bubble.strokeInsets
|
||||
|
||||
@ -48,13 +48,13 @@ final class ChatMessageUnsupportedBubbleContentNode: ChatMessageBubbleContentNod
|
||||
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonIncoming(presentationData.theme.theme)!
|
||||
titleColor = presentationData.theme.theme.chat.message.incoming.accentTextColor
|
||||
let bubbleColor = bubbleColorComponents(theme: presentationData.theme.theme, incoming: true, wallpaper: !presentationData.theme.wallpaper.isEmpty)
|
||||
titleHighlightedColor = bubbleColor.fill
|
||||
titleHighlightedColor = bubbleColor.fill[0]
|
||||
} else {
|
||||
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonOutgoing(presentationData.theme.theme)!
|
||||
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonOutgoing(presentationData.theme.theme)!
|
||||
titleColor = presentationData.theme.theme.chat.message.outgoing.accentTextColor
|
||||
let bubbleColor = bubbleColorComponents(theme: presentationData.theme.theme, incoming: false, wallpaper: !presentationData.theme.wallpaper.isEmpty)
|
||||
titleHighlightedColor = bubbleColor.fill
|
||||
titleHighlightedColor = bubbleColor.fill[0]
|
||||
}
|
||||
let (buttonWidth, continueActionButtonLayout) = makeButtonLayout(constrainedSize.width, buttonImage, buttonHighlightedImage, nil, nil, presentationData.strings.Conversation_UpdateTelegram, titleColor, titleHighlightedColor)
|
||||
|
||||
|
||||
@ -6,6 +6,9 @@ import TelegramCore
|
||||
import Postbox
|
||||
import AccountContext
|
||||
import AvatarNode
|
||||
import TextFormat
|
||||
import Markdown
|
||||
import WallpaperBackgroundNode
|
||||
|
||||
final class BlurredRoundedRectangle: Component {
|
||||
let color: UIColor
|
||||
@ -314,11 +317,24 @@ final class BadgeComponent: CombinedComponent {
|
||||
let count: Int
|
||||
let backgroundColor: UIColor
|
||||
let foregroundColor: UIColor
|
||||
let rect: CGRect
|
||||
let withinSize: CGSize
|
||||
let wallpaperNode: WallpaperBackgroundNode?
|
||||
|
||||
init(count: Int, backgroundColor: UIColor, foregroundColor: UIColor) {
|
||||
init(
|
||||
count: Int,
|
||||
backgroundColor: UIColor,
|
||||
foregroundColor: UIColor,
|
||||
rect: CGRect,
|
||||
withinSize: CGSize,
|
||||
wallpaperNode: WallpaperBackgroundNode?
|
||||
) {
|
||||
self.count = count
|
||||
self.backgroundColor = backgroundColor
|
||||
self.foregroundColor = foregroundColor
|
||||
self.rect = rect
|
||||
self.withinSize = withinSize
|
||||
self.wallpaperNode = wallpaperNode
|
||||
}
|
||||
|
||||
static func ==(lhs: BadgeComponent, rhs: BadgeComponent) -> Bool {
|
||||
@ -331,11 +347,20 @@ final class BadgeComponent: CombinedComponent {
|
||||
if !lhs.foregroundColor.isEqual(rhs.foregroundColor) {
|
||||
return false
|
||||
}
|
||||
if lhs.rect != rhs.rect {
|
||||
return false
|
||||
}
|
||||
if lhs.withinSize != rhs.withinSize {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaperNode != rhs.wallpaperNode {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
let background = Child(BlurredRoundedRectangle.self)
|
||||
let background = Child(WallpaperBlurComponent.self)
|
||||
let text = Child(Text.self)
|
||||
|
||||
return { context in
|
||||
@ -353,13 +378,20 @@ final class BadgeComponent: CombinedComponent {
|
||||
let backgroundSize = CGSize(width: max(height, text.size.width + 8.0), height: height)
|
||||
|
||||
let background = background.update(
|
||||
component: BlurredRoundedRectangle(color: context.component.backgroundColor),
|
||||
component: WallpaperBlurComponent(
|
||||
rect: CGRect(origin: context.component.rect.origin, size: backgroundSize),
|
||||
withinSize: context.component.withinSize,
|
||||
color: context.component.backgroundColor,
|
||||
wallpaperNode: context.component.wallpaperNode
|
||||
),
|
||||
availableSize: backgroundSize,
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
context.add(background
|
||||
.position(CGPoint(x: backgroundSize.width / 2.0, y: backgroundSize.height / 2.0))
|
||||
.cornerRadius(min(backgroundSize.width, backgroundSize.height) / 2.0)
|
||||
.clipsToBounds(true)
|
||||
)
|
||||
|
||||
context.add(text
|
||||
@ -400,11 +432,24 @@ final class AvatarComponent: Component {
|
||||
let context: AccountContext
|
||||
let peer: EnginePeer
|
||||
let badge: Badge?
|
||||
let rect: CGRect
|
||||
let withinSize: CGSize
|
||||
let wallpaperNode: WallpaperBackgroundNode?
|
||||
|
||||
init(context: AccountContext, peer: EnginePeer, badge: Badge?) {
|
||||
init(
|
||||
context: AccountContext,
|
||||
peer: EnginePeer,
|
||||
badge: Badge?,
|
||||
rect: CGRect,
|
||||
withinSize: CGSize,
|
||||
wallpaperNode: WallpaperBackgroundNode?
|
||||
) {
|
||||
self.context = context
|
||||
self.peer = peer
|
||||
self.badge = badge
|
||||
self.rect = rect
|
||||
self.withinSize = withinSize
|
||||
self.wallpaperNode = wallpaperNode
|
||||
}
|
||||
|
||||
static func ==(lhs: AvatarComponent, rhs: AvatarComponent) -> Bool {
|
||||
@ -417,6 +462,15 @@ final class AvatarComponent: Component {
|
||||
if lhs.badge != rhs.badge {
|
||||
return false
|
||||
}
|
||||
if lhs.rect != rhs.rect {
|
||||
return false
|
||||
}
|
||||
if lhs.withinSize != rhs.withinSize {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaperNode !== rhs.wallpaperNode {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -458,7 +512,10 @@ final class AvatarComponent: Component {
|
||||
component: AnyComponent(BadgeComponent(
|
||||
count: badge.count,
|
||||
backgroundColor: badge.backgroundColor,
|
||||
foregroundColor: badge.foregroundColor
|
||||
foregroundColor: badge.foregroundColor,
|
||||
rect: CGRect(origin: component.rect.offsetBy(dx: 0.0, dy: 0.0).origin, size: CGSize()),
|
||||
withinSize: component.withinSize,
|
||||
wallpaperNode: component.wallpaperNode
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 100.0, height: 100.0
|
||||
@ -505,13 +562,115 @@ final class AvatarComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
private final class WallpaperBlurNode: ASDisplayNode {
|
||||
private var backgroundNode: WallpaperBackgroundNode.BubbleBackgroundNode?
|
||||
private let colorNode: ASDisplayNode
|
||||
|
||||
override init() {
|
||||
self.colorNode = ASDisplayNode()
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.colorNode)
|
||||
}
|
||||
|
||||
func update(rect: CGRect, within size: CGSize, color: UIColor, wallpaperNode: WallpaperBackgroundNode?, transition: ContainedViewLayoutTransition) {
|
||||
var transition = transition
|
||||
if self.backgroundNode == nil {
|
||||
if let backgroundNode = wallpaperNode?.makeBubbleBackground(for: .free) {
|
||||
self.backgroundNode = backgroundNode
|
||||
self.insertSubnode(backgroundNode, at: 0)
|
||||
transition = .immediate
|
||||
}
|
||||
}
|
||||
|
||||
self.colorNode.backgroundColor = color
|
||||
transition.updateFrame(node: self.colorNode, frame: CGRect(origin: CGPoint(), size: rect.size))
|
||||
|
||||
if let backgroundNode = self.backgroundNode {
|
||||
transition.updateFrame(node: backgroundNode, frame: CGRect(origin: CGPoint(), size: rect.size))
|
||||
backgroundNode.update(rect: rect, within: size, transition: transition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class WallpaperBlurComponent: Component {
|
||||
let rect: CGRect
|
||||
let withinSize: CGSize
|
||||
let color: UIColor
|
||||
let wallpaperNode: WallpaperBackgroundNode?
|
||||
|
||||
init(
|
||||
rect: CGRect,
|
||||
withinSize: CGSize,
|
||||
color: UIColor,
|
||||
wallpaperNode: WallpaperBackgroundNode?
|
||||
) {
|
||||
self.rect = rect
|
||||
self.withinSize = withinSize
|
||||
self.color = color
|
||||
self.wallpaperNode = wallpaperNode
|
||||
}
|
||||
|
||||
static func ==(lhs: WallpaperBlurComponent, rhs: WallpaperBlurComponent) -> Bool {
|
||||
if lhs.rect != rhs.rect {
|
||||
return false
|
||||
}
|
||||
if lhs.withinSize != rhs.withinSize {
|
||||
return false
|
||||
}
|
||||
if !lhs.color.isEqual(rhs.color) {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaperNode !== rhs.wallpaperNode {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class View: UIView {
|
||||
private let background: WallpaperBlurNode
|
||||
|
||||
init() {
|
||||
self.background = WallpaperBlurNode()
|
||||
|
||||
super.init(frame: CGRect())
|
||||
|
||||
self.addSubview(self.background.view)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
func update(component: WallpaperBlurComponent, availableSize: CGSize, transition: Transition) -> CGSize {
|
||||
transition.setFrame(view: self.background.view, frame: CGRect(origin: CGPoint(), size: availableSize))
|
||||
self.background.update(rect: component.rect, within: component.withinSize, color: component.color, wallpaperNode: component.wallpaperNode, transition: .immediate)
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View()
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
final class OverscrollContentsComponent: Component {
|
||||
let context: AccountContext
|
||||
let backgroundColor: UIColor
|
||||
let foregroundColor: UIColor
|
||||
let peer: EnginePeer?
|
||||
let unreadCount: Int
|
||||
let location: TelegramEngine.NextUnreadChannelLocation
|
||||
let expandOffset: CGFloat
|
||||
let absoluteRect: CGRect
|
||||
let absoluteSize: CGSize
|
||||
let wallpaperNode: WallpaperBackgroundNode?
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
@ -519,14 +678,22 @@ final class OverscrollContentsComponent: Component {
|
||||
foregroundColor: UIColor,
|
||||
peer: EnginePeer?,
|
||||
unreadCount: Int,
|
||||
expandOffset: CGFloat
|
||||
location: TelegramEngine.NextUnreadChannelLocation,
|
||||
expandOffset: CGFloat,
|
||||
absoluteRect: CGRect,
|
||||
absoluteSize: CGSize,
|
||||
wallpaperNode: WallpaperBackgroundNode?
|
||||
) {
|
||||
self.context = context
|
||||
self.backgroundColor = backgroundColor
|
||||
self.foregroundColor = foregroundColor
|
||||
self.peer = peer
|
||||
self.unreadCount = unreadCount
|
||||
self.location = location
|
||||
self.expandOffset = expandOffset
|
||||
self.absoluteRect = absoluteRect
|
||||
self.absoluteSize = absoluteSize
|
||||
self.wallpaperNode = wallpaperNode
|
||||
}
|
||||
|
||||
static func ==(lhs: OverscrollContentsComponent, rhs: OverscrollContentsComponent) -> Bool {
|
||||
@ -545,15 +712,28 @@ final class OverscrollContentsComponent: Component {
|
||||
if lhs.unreadCount != rhs.unreadCount {
|
||||
return false
|
||||
}
|
||||
if lhs.location != rhs.location {
|
||||
return false
|
||||
}
|
||||
if lhs.expandOffset != rhs.expandOffset {
|
||||
return false
|
||||
}
|
||||
if lhs.absoluteRect != rhs.absoluteRect {
|
||||
return false
|
||||
}
|
||||
if lhs.absoluteSize != rhs.absoluteSize {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaperNode !== rhs.wallpaperNode {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class View: UIView {
|
||||
private let backgroundScalingContainer: ASDisplayNode
|
||||
private let backgroundNode: NavigationBackgroundNode
|
||||
private let backgroundNode: WallpaperBlurNode
|
||||
private let backgroundFolderMask: UIImageView
|
||||
private let backgroundClippingNode: ASDisplayNode
|
||||
private let avatarView = ComponentHostView<Empty>()
|
||||
private let checkView = ComponentHostView<Empty>()
|
||||
@ -564,7 +744,7 @@ final class OverscrollContentsComponent: Component {
|
||||
private let arrowOffsetContainer: ASDisplayNode
|
||||
|
||||
private let titleOffsetContainer: ASDisplayNode
|
||||
private let titleBackgroundNode: NavigationBackgroundNode
|
||||
private let titleBackgroundNode: WallpaperBlurNode
|
||||
private let titleNode: ImmediateTextNode
|
||||
|
||||
private var isFullyExpanded: Bool = false
|
||||
@ -573,8 +753,12 @@ final class OverscrollContentsComponent: Component {
|
||||
|
||||
init() {
|
||||
self.backgroundScalingContainer = ASDisplayNode()
|
||||
self.backgroundNode = NavigationBackgroundNode(color: .clear)
|
||||
self.backgroundNode = WallpaperBlurNode()
|
||||
self.backgroundNode.clipsToBounds = true
|
||||
|
||||
self.backgroundFolderMask = UIImageView()
|
||||
self.backgroundFolderMask.image = UIImage(bundleImageName: "Chat/OverscrollFolder")?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 40)
|
||||
|
||||
self.backgroundClippingNode = ASDisplayNode()
|
||||
self.backgroundClippingNode.clipsToBounds = true
|
||||
self.arrowNode = ASImageNode()
|
||||
@ -584,7 +768,8 @@ final class OverscrollContentsComponent: Component {
|
||||
self.arrowOffsetContainer = ASDisplayNode()
|
||||
|
||||
self.titleOffsetContainer = ASDisplayNode()
|
||||
self.titleBackgroundNode = NavigationBackgroundNode(color: .clear)
|
||||
self.titleBackgroundNode = WallpaperBlurNode()
|
||||
self.titleBackgroundNode.clipsToBounds = true
|
||||
self.titleNode = ImmediateTextNode()
|
||||
|
||||
super.init(frame: CGRect())
|
||||
@ -620,36 +805,53 @@ final class OverscrollContentsComponent: Component {
|
||||
self.checkView.isHidden = false
|
||||
}
|
||||
|
||||
let fullHeight: CGFloat = 90.0
|
||||
let backgroundWidth: CGFloat = 50.0
|
||||
let minBackgroundHeight: CGFloat = backgroundWidth + 34.0
|
||||
let fullHeight: CGFloat = 94.0
|
||||
let backgroundWidth: CGFloat = 56.0
|
||||
let minBackgroundHeight: CGFloat = backgroundWidth + 5.0
|
||||
let avatarInset: CGFloat = 6.0
|
||||
|
||||
let isFullyExpanded = component.expandOffset >= fullHeight
|
||||
|
||||
let backgroundHeight: CGFloat = max(minBackgroundHeight, min(fullHeight, component.expandOffset))
|
||||
let isFolderMask: Bool
|
||||
switch component.location {
|
||||
case .archived, .folder:
|
||||
isFolderMask = true
|
||||
default:
|
||||
isFolderMask = false
|
||||
}
|
||||
|
||||
let expandProgress: CGFloat = max(0.1, min(1.0, component.expandOffset / fullHeight))
|
||||
|
||||
func interpolate(from: CGFloat, to: CGFloat, value: CGFloat) -> CGFloat {
|
||||
return (1.0 - value) * from + value * to
|
||||
}
|
||||
|
||||
let backgroundHeight: CGFloat = interpolate(from: minBackgroundHeight, to: fullHeight, value: expandProgress)
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - backgroundWidth) / 2.0), y: fullHeight - backgroundHeight), size: CGSize(width: backgroundWidth, height: backgroundHeight))
|
||||
|
||||
let expandProgress: CGFloat = max(0.1, min(1.0, component.expandOffset / minBackgroundHeight))
|
||||
let alphaProgress: CGFloat = max(0.0, min(1.0, component.expandOffset / 10.0))
|
||||
|
||||
let maxAvatarScale: CGFloat = 1.0
|
||||
let avatarExpandProgress: CGFloat = max(0.01, min(maxAvatarScale, component.expandOffset / fullHeight))
|
||||
var avatarExpandProgress: CGFloat = max(0.01, min(maxAvatarScale, component.expandOffset / fullHeight))
|
||||
avatarExpandProgress *= expandProgress
|
||||
|
||||
let avatarOffsetProgress = interpolate(from: 0.1, to: 1.0, value: avatarExpandProgress)
|
||||
|
||||
transition.setAlpha(view: self.backgroundScalingContainer.view, alpha: alphaProgress)
|
||||
transition.setFrame(view: self.backgroundScalingContainer.view, frame: CGRect(origin: CGPoint(x: floor(availableSize.width / 2.0), y: fullHeight), size: CGSize(width: 0.0, height: 0.0)))
|
||||
transition.setSublayerTransform(view: self.backgroundScalingContainer.view, transform: CATransform3DMakeScale(expandProgress, expandProgress, 1.0))
|
||||
|
||||
transition.setFrame(view: self.backgroundNode.view, frame: CGRect(origin: CGPoint(x: 0.0, y: fullHeight - backgroundFrame.size.height), size: backgroundFrame.size))
|
||||
self.backgroundNode.updateColor(color: component.backgroundColor, transition: .immediate)
|
||||
self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: backgroundWidth / 2.0, transition: .immediate)
|
||||
self.backgroundNode.update(rect: backgroundFrame.offsetBy(dx: component.absoluteRect.minX, dy: component.absoluteRect.minY), within: component.absoluteSize, color: component.backgroundColor, wallpaperNode: component.wallpaperNode, transition: .immediate)
|
||||
self.backgroundFolderMask.frame = CGRect(origin: CGPoint(), size: backgroundFrame.size)
|
||||
|
||||
self.avatarView.frame = CGRect(origin: CGPoint(x: floor(-backgroundWidth / 2.0), y: floor(-backgroundWidth / 2.0)), size: CGSize(width: backgroundWidth, height: backgroundWidth))
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: floor(-backgroundWidth / 2.0), y: floor(-backgroundWidth / 2.0)), size: CGSize(width: backgroundWidth, height: backgroundWidth))
|
||||
self.avatarView.frame = avatarFrame
|
||||
|
||||
transition.setFrame(view: self.avatarOffsetContainer.view, frame: CGRect())
|
||||
transition.setFrame(view: self.avatarScalingContainer.view, frame: CGRect())
|
||||
transition.setFrame(view: self.avatarExtraScalingContainer.view, frame: CGRect(origin: CGPoint(x: availableSize.width / 2.0, y: fullHeight - backgroundWidth / 2.0), size: CGSize()).offsetBy(dx: 0.0, dy: (1.0 - avatarExpandProgress) * backgroundWidth * 0.5))
|
||||
transition.setFrame(view: self.avatarExtraScalingContainer.view, frame: CGRect(origin: CGPoint(x: availableSize.width / 2.0, y: fullHeight - backgroundWidth / 2.0), size: CGSize()).offsetBy(dx: 0.0, dy: (1.0 - avatarOffsetProgress) * backgroundWidth * 0.5))
|
||||
transition.setSublayerTransform(view: self.avatarScalingContainer.view, transform: CATransform3DMakeScale(avatarExpandProgress, avatarExpandProgress, 1.0))
|
||||
|
||||
let titleText: String
|
||||
@ -664,13 +866,14 @@ final class OverscrollContentsComponent: Component {
|
||||
let titleBackgroundSize = CGSize(width: titleSize.width + 18.0, height: titleSize.height + 8.0)
|
||||
let titleBackgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleBackgroundSize.width) / 2.0), y: fullHeight - titleBackgroundSize.height - 8.0), size: titleBackgroundSize)
|
||||
self.titleBackgroundNode.frame = titleBackgroundFrame
|
||||
self.titleBackgroundNode.updateColor(color: component.backgroundColor, transition: .immediate)
|
||||
self.titleBackgroundNode.update(size: titleBackgroundFrame.size, cornerRadius: titleBackgroundFrame.size.height / 2.0, transition: .immediate)
|
||||
self.titleBackgroundNode.update(rect: titleBackgroundFrame.offsetBy(dx: component.absoluteRect.minX, dy: component.absoluteRect.minY), within: component.absoluteSize, color: component.backgroundColor, wallpaperNode: component.wallpaperNode, transition: .immediate)
|
||||
self.titleBackgroundNode.cornerRadius = min(titleBackgroundFrame.width, titleBackgroundFrame.height) / 2.0
|
||||
self.titleNode.frame = titleSize.centered(in: titleBackgroundFrame)
|
||||
|
||||
let backgroundClippingFrame = CGRect(origin: CGPoint(x: floor(-backgroundWidth / 2.0), y: -fullHeight), size: CGSize(width: backgroundWidth, height: isFullyExpanded ? backgroundWidth : fullHeight))
|
||||
self.backgroundClippingNode.cornerRadius = backgroundWidth / 2.0
|
||||
self.backgroundNode.cornerRadius = backgroundWidth / 2.0
|
||||
self.backgroundClippingNode.cornerRadius = isFolderMask ? 10.0 : backgroundWidth / 2.0
|
||||
self.backgroundNode.cornerRadius = isFolderMask ? 0.0 : backgroundWidth / 2.0
|
||||
self.backgroundNode.view.mask = isFolderMask ? self.backgroundFolderMask : nil
|
||||
|
||||
if !(self.validForegroundColor?.isEqual(component.foregroundColor) ?? false) {
|
||||
self.validForegroundColor = component.foregroundColor
|
||||
@ -713,7 +916,7 @@ final class OverscrollContentsComponent: Component {
|
||||
transformTransition = .immediate
|
||||
}
|
||||
|
||||
let checkSize: CGFloat = 50.0
|
||||
let checkSize: CGFloat = 56.0
|
||||
self.checkView.frame = CGRect(origin: CGPoint(x: floor(-checkSize / 2.0), y: floor(-checkSize / 2.0)), size: CGSize(width: checkSize, height: checkSize))
|
||||
let _ = self.checkView.update(
|
||||
transition: Transition(animation: transformTransition.isAnimated ? .curve(duration: 0.2, curve: .easeInOut) : .none),
|
||||
@ -732,7 +935,10 @@ final class OverscrollContentsComponent: Component {
|
||||
component: AnyComponent(AvatarComponent(
|
||||
context: component.context,
|
||||
peer: peer,
|
||||
badge: isFullyExpanded ? AvatarComponent.Badge(count: component.unreadCount, backgroundColor: component.backgroundColor, foregroundColor: component.foregroundColor) : nil
|
||||
badge: isFullyExpanded ? AvatarComponent.Badge(count: component.unreadCount, backgroundColor: component.backgroundColor, foregroundColor: component.foregroundColor) : nil,
|
||||
rect: avatarFrame.offsetBy(dx: self.avatarExtraScalingContainer.frame.midX + component.absoluteRect.minX, dy: self.avatarExtraScalingContainer.frame.midY + component.absoluteRect.minY),
|
||||
withinSize: component.absoluteSize,
|
||||
wallpaperNode: component.wallpaperNode
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: self.avatarView.bounds.size
|
||||
@ -769,23 +975,35 @@ final class ChatOverscrollControl: CombinedComponent {
|
||||
let foregroundColor: UIColor
|
||||
let peer: EnginePeer?
|
||||
let unreadCount: Int
|
||||
let location: TelegramEngine.NextUnreadChannelLocation
|
||||
let context: AccountContext
|
||||
let expandDistance: CGFloat
|
||||
let absoluteRect: CGRect
|
||||
let absoluteSize: CGSize
|
||||
let wallpaperNode: WallpaperBackgroundNode?
|
||||
|
||||
init(
|
||||
backgroundColor: UIColor,
|
||||
foregroundColor: UIColor,
|
||||
peer: EnginePeer?,
|
||||
unreadCount: Int,
|
||||
location: TelegramEngine.NextUnreadChannelLocation,
|
||||
context: AccountContext,
|
||||
expandDistance: CGFloat
|
||||
expandDistance: CGFloat,
|
||||
absoluteRect: CGRect,
|
||||
absoluteSize: CGSize,
|
||||
wallpaperNode: WallpaperBackgroundNode?
|
||||
) {
|
||||
self.backgroundColor = backgroundColor
|
||||
self.foregroundColor = foregroundColor
|
||||
self.peer = peer
|
||||
self.unreadCount = unreadCount
|
||||
self.location = location
|
||||
self.context = context
|
||||
self.expandDistance = expandDistance
|
||||
self.absoluteRect = absoluteRect
|
||||
self.absoluteSize = absoluteSize
|
||||
self.wallpaperNode = wallpaperNode
|
||||
}
|
||||
|
||||
static func ==(lhs: ChatOverscrollControl, rhs: ChatOverscrollControl) -> Bool {
|
||||
@ -801,12 +1019,24 @@ final class ChatOverscrollControl: CombinedComponent {
|
||||
if lhs.unreadCount != rhs.unreadCount {
|
||||
return false
|
||||
}
|
||||
if lhs.location != rhs.location {
|
||||
return false
|
||||
}
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.expandDistance != rhs.expandDistance {
|
||||
return false
|
||||
}
|
||||
if lhs.absoluteRect != rhs.absoluteRect {
|
||||
return false
|
||||
}
|
||||
if lhs.absoluteSize != rhs.absoluteSize {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaperNode !== rhs.wallpaperNode {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -821,7 +1051,11 @@ final class ChatOverscrollControl: CombinedComponent {
|
||||
foregroundColor: context.component.foregroundColor,
|
||||
peer: context.component.peer,
|
||||
unreadCount: context.component.unreadCount,
|
||||
expandOffset: context.component.expandDistance
|
||||
location: context.component.location,
|
||||
expandOffset: context.component.expandDistance,
|
||||
absoluteRect: context.component.absoluteRect,
|
||||
absoluteSize: context.component.absoluteSize,
|
||||
wallpaperNode: context.component.wallpaperNode
|
||||
),
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
@ -839,18 +1073,22 @@ final class ChatOverscrollControl: CombinedComponent {
|
||||
}
|
||||
|
||||
final class ChatInputPanelOverscrollNode: ASDisplayNode {
|
||||
let text: String
|
||||
let text: (String, [(Int, NSRange)])
|
||||
let priority: Int
|
||||
private let titleNode: ImmediateTextNode
|
||||
|
||||
init(text: String, color: UIColor, priority: Int) {
|
||||
init(text: (String, [(Int, NSRange)]), color: UIColor, priority: Int) {
|
||||
self.text = text
|
||||
self.priority = priority
|
||||
self.titleNode = ImmediateTextNode()
|
||||
|
||||
super.init()
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: color)
|
||||
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: color)
|
||||
let bold = MarkdownAttributeSet(font: Font.bold(14.0), textColor: color)
|
||||
|
||||
self.titleNode.attributedText = addAttributesToStringWithRanges(text, body: body, argumentAttributes: [0: bold])
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
}
|
||||
|
||||
|
||||
@ -267,7 +267,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
let outgoing: PresentationThemeBubbleColorComponents = self.presentationData.chatWallpaper.isEmpty ? self.presentationData.theme.chat.message.outgoing.bubble.withoutWallpaper : self.presentationData.theme.chat.message.outgoing.bubble.withWallpaper
|
||||
|
||||
let maxCornerRadius = self.presentationData.chatBubbleCorners.mainRadius
|
||||
self.messageBackgroundNode.image = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: maxCornerRadius, incoming: false, fillColor: outgoing.gradientFill, strokeColor: outgoing.fill == outgoing.gradientFill ? outgoing.stroke : .clear, neighbors: .none, theme: self.presentationData.theme.chat, wallpaper: self.presentationData.chatWallpaper, knockout: false)
|
||||
self.messageBackgroundNode.image = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: maxCornerRadius, incoming: false, fillColor: outgoing.fill.last ?? outgoing.fill[0], strokeColor: outgoing.fill.count > 1 ? outgoing.stroke : .clear, neighbors: .none, theme: self.presentationData.theme.chat, wallpaper: self.presentationData.chatWallpaper, knockout: false)
|
||||
|
||||
self.view.addSubview(self.effectView)
|
||||
self.addSubnode(self.dimNode)
|
||||
@ -370,7 +370,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
|
||||
let outgoing: PresentationThemeBubbleColorComponents = self.presentationData.chatWallpaper.isEmpty ? self.presentationData.theme.chat.message.outgoing.bubble.withoutWallpaper : self.presentationData.theme.chat.message.outgoing.bubble.withWallpaper
|
||||
let maxCornerRadius = self.presentationData.chatBubbleCorners.mainRadius
|
||||
self.messageBackgroundNode.image = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: maxCornerRadius, incoming: false, fillColor: outgoing.gradientFill, strokeColor: outgoing.fill == outgoing.gradientFill ? outgoing.stroke : .clear, neighbors: .none, theme: self.presentationData.theme.chat, wallpaper: self.presentationData.chatWallpaper, knockout: false)
|
||||
self.messageBackgroundNode.image = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: maxCornerRadius, incoming: false, fillColor: outgoing.fill.last ?? outgoing.fill[0], strokeColor: outgoing.fill.count > 1 ? outgoing.stroke : .clear, neighbors: .none, theme: self.presentationData.theme.chat, wallpaper: self.presentationData.chatWallpaper, knockout: false)
|
||||
|
||||
for node in self.contentNodes {
|
||||
node.updateTheme(presentationData.theme)
|
||||
|
||||
@ -388,7 +388,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
navigationController?.pushViewController(previewController)
|
||||
}
|
||||
} else if let settings = dataAndTheme.1 {
|
||||
if let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: settings.wallpaper) {
|
||||
if let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors, wallpaper: settings.wallpaper) {
|
||||
let previewController = ThemePreviewController(context: context, previewTheme: theme, source: .theme(dataAndTheme.2))
|
||||
navigationController?.pushViewController(previewController)
|
||||
}
|
||||
|
||||
@ -407,13 +407,13 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
|
||||
|
||||
public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
public static func == (lhs: PresentationThemeAccentColor, rhs: PresentationThemeAccentColor) -> Bool {
|
||||
return lhs.index == rhs.index && lhs.baseColor == rhs.baseColor && lhs.accentColor == rhs.accentColor && lhs.bubbleColors?.0 == rhs.bubbleColors?.0 && lhs.bubbleColors?.1 == rhs.bubbleColors?.1
|
||||
return lhs.index == rhs.index && lhs.baseColor == rhs.baseColor && lhs.accentColor == rhs.accentColor && lhs.bubbleColors == rhs.bubbleColors
|
||||
}
|
||||
|
||||
public var index: Int32
|
||||
public var baseColor: PresentationThemeBaseColor
|
||||
public var accentColor: UInt32?
|
||||
public var bubbleColors: (UInt32, UInt32?)?
|
||||
public var bubbleColors: [UInt32]
|
||||
public var wallpaper: TelegramWallpaper?
|
||||
public var themeIndex: Int64?
|
||||
|
||||
@ -425,11 +425,11 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
}
|
||||
self.baseColor = baseColor
|
||||
self.accentColor = nil
|
||||
self.bubbleColors = nil
|
||||
self.bubbleColors = []
|
||||
self.wallpaper = nil
|
||||
}
|
||||
|
||||
public init(index: Int32, baseColor: PresentationThemeBaseColor, accentColor: UInt32? = nil, bubbleColors: (UInt32, UInt32?)? = nil, wallpaper: TelegramWallpaper? = nil) {
|
||||
public init(index: Int32, baseColor: PresentationThemeBaseColor, accentColor: UInt32? = nil, bubbleColors: [UInt32] = [], wallpaper: TelegramWallpaper? = nil) {
|
||||
self.index = index
|
||||
self.baseColor = baseColor
|
||||
self.accentColor = accentColor
|
||||
@ -441,7 +441,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
self.index = -1
|
||||
self.baseColor = .theme
|
||||
self.accentColor = nil
|
||||
self.bubbleColors = nil
|
||||
self.bubbleColors = []
|
||||
self.wallpaper = nil
|
||||
self.themeIndex = themeIndex
|
||||
}
|
||||
@ -450,15 +450,22 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
self.index = decoder.decodeInt32ForKey("i", orElse: -1)
|
||||
self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue
|
||||
self.accentColor = decoder.decodeOptionalInt32ForKey("c").flatMap { UInt32(bitPattern: $0) }
|
||||
if let bubbleTopColor = decoder.decodeOptionalInt32ForKey("bt") {
|
||||
if let bubbleBottomColor = decoder.decodeOptionalInt32ForKey("bb") {
|
||||
self.bubbleColors = (UInt32(bitPattern: bubbleTopColor), UInt32(bitPattern: bubbleBottomColor))
|
||||
} else {
|
||||
self.bubbleColors = (UInt32(bitPattern: bubbleTopColor), nil)
|
||||
}
|
||||
|
||||
let bubbleColors = decoder.decodeInt32ArrayForKey("bubbleColors")
|
||||
if !bubbleColors.isEmpty {
|
||||
self.bubbleColors = bubbleColors.map(UInt32.init(bitPattern:))
|
||||
} else {
|
||||
self.bubbleColors = nil
|
||||
if let bubbleTopColor = decoder.decodeOptionalInt32ForKey("bt") {
|
||||
if let bubbleBottomColor = decoder.decodeOptionalInt32ForKey("bb") {
|
||||
self.bubbleColors = [UInt32(bitPattern: bubbleTopColor), UInt32(bitPattern: bubbleBottomColor)]
|
||||
} else {
|
||||
self.bubbleColors = [UInt32(bitPattern: bubbleTopColor)]
|
||||
}
|
||||
} else {
|
||||
self.bubbleColors = []
|
||||
}
|
||||
}
|
||||
|
||||
self.wallpaper = decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
|
||||
self.themeIndex = decoder.decodeOptionalInt64ForKey("t")
|
||||
}
|
||||
@ -471,17 +478,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "c")
|
||||
}
|
||||
if let bubbleColors = self.bubbleColors {
|
||||
encoder.encodeInt32(Int32(bitPattern: bubbleColors.0), forKey: "bt")
|
||||
if let bubbleBottomColor = bubbleColors.1 {
|
||||
encoder.encodeInt32(Int32(bitPattern: bubbleBottomColor), forKey: "bb")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "bb")
|
||||
}
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "bt")
|
||||
encoder.encodeNil(forKey: "bb")
|
||||
}
|
||||
encoder.encodeInt32Array(self.bubbleColors.map(Int32.init(bitPattern:)), forKey: "bubbleColors")
|
||||
if let wallpaper = self.wallpaper {
|
||||
encoder.encodeObject(wallpaper, forKey: "w")
|
||||
} else {
|
||||
@ -502,28 +499,12 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public var customBubbleColors: (UIColor, UIColor?)? {
|
||||
if let bubbleColors = self.bubbleColors {
|
||||
if let bottomColor = bubbleColors.1 {
|
||||
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
|
||||
} else {
|
||||
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), nil)
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
public var customBubbleColors: [UInt32] {
|
||||
return self.bubbleColors
|
||||
}
|
||||
|
||||
public var plainBubbleColors: (UIColor, UIColor)? {
|
||||
if let bubbleColors = self.bubbleColors {
|
||||
if let bottomColor = bubbleColors.1 {
|
||||
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
|
||||
} else {
|
||||
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), UIColor(rgb: UInt32(bitPattern: bubbleColors.0)))
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
public var plainBubbleColors: [UInt32] {
|
||||
return self.bubbleColors
|
||||
}
|
||||
|
||||
public func withUpdatedWallpaper(_ wallpaper: TelegramWallpaper?) -> PresentationThemeAccentColor {
|
||||
|
||||
@ -94,19 +94,24 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
case .incoming:
|
||||
self.contentNode.image = graphics.incomingBubbleGradientImage
|
||||
if graphics.incomingBubbleGradientImage == nil {
|
||||
self.contentNode.backgroundColor = bubbleTheme.chat.message.incoming.bubble.withWallpaper.fill
|
||||
self.contentNode.backgroundColor = bubbleTheme.chat.message.incoming.bubble.withWallpaper.fill[0]
|
||||
} else {
|
||||
self.contentNode.backgroundColor = nil
|
||||
}
|
||||
needsCleanBackground = bubbleTheme.chat.message.incoming.bubble.withWallpaper.fill.alpha <= 0.99 || bubbleTheme.chat.message.incoming.bubble.withWallpaper.gradientFill.alpha <= 0.99
|
||||
needsCleanBackground = bubbleTheme.chat.message.incoming.bubble.withWallpaper.fill.contains(where: { $0.alpha <= 0.99 })
|
||||
case .outgoing:
|
||||
self.contentNode.image = graphics.outgoingBubbleGradientImage
|
||||
if graphics.outgoingBubbleGradientImage == nil {
|
||||
self.contentNode.backgroundColor = bubbleTheme.chat.message.outgoing.bubble.withWallpaper.fill
|
||||
} else {
|
||||
if backgroundNode.outgoingBubbleGradientBackgroundNode != nil {
|
||||
self.contentNode.image = nil
|
||||
self.contentNode.backgroundColor = nil
|
||||
} else {
|
||||
self.contentNode.image = graphics.outgoingBubbleGradientImage
|
||||
if graphics.outgoingBubbleGradientImage == nil {
|
||||
self.contentNode.backgroundColor = bubbleTheme.chat.message.outgoing.bubble.withWallpaper.fill[0]
|
||||
} else {
|
||||
self.contentNode.backgroundColor = nil
|
||||
}
|
||||
needsCleanBackground = bubbleTheme.chat.message.outgoing.bubble.withWallpaper.fill.contains(where: { $0.alpha <= 0.99 })
|
||||
}
|
||||
needsCleanBackground = bubbleTheme.chat.message.outgoing.bubble.withWallpaper.fill.alpha <= 0.99 || bubbleTheme.chat.message.outgoing.bubble.withWallpaper.gradientFill.alpha <= 0.99
|
||||
case .free:
|
||||
self.contentNode.image = nil
|
||||
self.contentNode.backgroundColor = nil
|
||||
@ -147,6 +152,16 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
var gradientBackgroundSource: GradientBackgroundNode? = backgroundNode.gradientBackgroundNode
|
||||
|
||||
if case .outgoing = self.bubbleType {
|
||||
if let outgoingBubbleGradientBackgroundNode = backgroundNode.outgoingBubbleGradientBackgroundNode {
|
||||
gradientBackgroundSource = outgoingBubbleGradientBackgroundNode
|
||||
needsWallpaperBackground = false
|
||||
needsGradientBackground = true
|
||||
}
|
||||
}
|
||||
|
||||
if needsWallpaperBackground {
|
||||
if self.cleanWallpaperNode == nil {
|
||||
let cleanWallpaperNode = ASImageNode()
|
||||
@ -168,7 +183,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
if needsGradientBackground, let gradientBackgroundNode = backgroundNode.gradientBackgroundNode {
|
||||
if needsGradientBackground, let gradientBackgroundNode = gradientBackgroundSource {
|
||||
if self.gradientWallpaperNode == nil {
|
||||
let gradientWallpaperNode = GradientBackgroundNode.CloneNode(parentNode: gradientBackgroundNode)
|
||||
gradientWallpaperNode.frame = self.bounds
|
||||
@ -277,6 +292,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
private var blurredBackgroundContents: UIImage?
|
||||
|
||||
private var gradientBackgroundNode: GradientBackgroundNode?
|
||||
private var outgoingBubbleGradientBackgroundNode: GradientBackgroundNode?
|
||||
private let patternImageNode: ASImageNode
|
||||
private var isGeneratingPatternImage: Bool = false
|
||||
|
||||
@ -735,6 +751,11 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
gradientBackgroundNode.updateLayout(size: size, transition: transition)
|
||||
}
|
||||
|
||||
if let outgoingBubbleGradientBackgroundNode = self.outgoingBubbleGradientBackgroundNode {
|
||||
transition.updateFrame(node: outgoingBubbleGradientBackgroundNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||
outgoingBubbleGradientBackgroundNode.updateLayout(size: size, transition: transition)
|
||||
}
|
||||
|
||||
self.loadPatternForSizeIfNeeded(size: size, transition: transition)
|
||||
|
||||
if isFirstLayout && !self.frame.isEmpty {
|
||||
@ -744,6 +765,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
|
||||
public func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool = false) {
|
||||
self.gradientBackgroundNode?.animateEvent(transition: transition, extendAnimation: extendAnimation)
|
||||
self.outgoingBubbleGradientBackgroundNode?.animateEvent(transition: transition, extendAnimation: extendAnimation)
|
||||
}
|
||||
|
||||
public func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
|
||||
@ -751,6 +773,20 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
self.bubbleTheme = bubbleTheme
|
||||
self.bubbleCorners = bubbleCorners
|
||||
|
||||
if bubbleTheme.chat.message.outgoing.bubble.withoutWallpaper.fill.count >= 3 && self.context.sharedContext.immediateExperimentalUISettings.enableDebugDataDisplay {
|
||||
if self.outgoingBubbleGradientBackgroundNode == nil {
|
||||
let outgoingBubbleGradientBackgroundNode = GradientBackgroundNode()
|
||||
if let size = self.validLayout {
|
||||
outgoingBubbleGradientBackgroundNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
outgoingBubbleGradientBackgroundNode.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
self.outgoingBubbleGradientBackgroundNode = outgoingBubbleGradientBackgroundNode
|
||||
}
|
||||
self.outgoingBubbleGradientBackgroundNode?.updateColors(colors: bubbleTheme.chat.message.outgoing.bubble.withoutWallpaper.fill)
|
||||
} else if let _ = self.outgoingBubbleGradientBackgroundNode {
|
||||
self.outgoingBubbleGradientBackgroundNode = nil
|
||||
}
|
||||
|
||||
self.updateBubbles()
|
||||
}
|
||||
}
|
||||
@ -789,14 +825,14 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
if graphics.incomingBubbleGradientImage != nil {
|
||||
return true
|
||||
}
|
||||
if bubbleTheme.chat.message.incoming.bubble.withWallpaper.fill.alpha <= 0.99 {
|
||||
if bubbleTheme.chat.message.incoming.bubble.withWallpaper.fill.contains(where: { $0.alpha <= 0.99 }) {
|
||||
return !hasPlainWallpaper
|
||||
}
|
||||
case .outgoing:
|
||||
if graphics.outgoingBubbleGradientImage != nil {
|
||||
return true
|
||||
}
|
||||
if bubbleTheme.chat.message.outgoing.bubble.withWallpaper.fill.alpha <= 0.99 {
|
||||
if bubbleTheme.chat.message.outgoing.bubble.withWallpaper.fill.contains(where: { $0.alpha <= 0.99 }) {
|
||||
return !hasPlainWallpaper
|
||||
}
|
||||
case .free:
|
||||
|
||||
@ -1001,16 +1001,22 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp
|
||||
c.translateBy(x: -114.0, y: -32.0)
|
||||
|
||||
let _ = try? drawSvgPath(c, path: "M98.0061174,0 C106.734138,0 113.82927,6.99200411 113.996965,15.6850616 L114,16 C114,24.836556 106.830179,32 98.0061174,32 L21.9938826,32 C18.2292665,32 14.7684355,30.699197 12.0362474,28.5221601 C8.56516444,32.1765452 -1.77635684e-15,31.9985981 -1.77635684e-15,31.9985981 C5.69252399,28.6991366 5.98604874,24.4421608 5.99940747,24.1573436 L6,24.1422468 L6,16 C6,7.163444 13.1698213,0 21.9938826,0 L98.0061174,0 ")
|
||||
if incoming.fill.rgb != incoming.gradientFill.rgb {
|
||||
if Set(incoming.fill.map(\.rgb)).count > 1 {
|
||||
c.clip()
|
||||
|
||||
let gradientColors = [incoming.fill.withAlphaComponent(1.0), incoming.gradientFill.withAlphaComponent(1.0)].map { $0.cgColor } as CFArray
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
|
||||
var colors: [CGColor] = []
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< incoming.fill.count {
|
||||
let t = CGFloat(i) / CGFloat(incoming.fill.count - 1)
|
||||
locations.append(t)
|
||||
colors.append(incoming.fill[i].cgColor)
|
||||
}
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as NSArray, locations: &locations)!
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: 32.0), options: CGGradientDrawingOptions())
|
||||
} else {
|
||||
c.setFillColor(incoming.fill.cgColor)
|
||||
c.setFillColor(incoming.fill[0].cgColor)
|
||||
c.setStrokeColor(incoming.stroke.cgColor)
|
||||
|
||||
c.strokePath()
|
||||
@ -1027,16 +1033,22 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp
|
||||
c.translateBy(x: 0, y: -32.0)
|
||||
|
||||
let _ = try? drawSvgPath(c, path: "M98.0061174,0 C106.734138,0 113.82927,6.99200411 113.996965,15.6850616 L114,16 C114,24.836556 106.830179,32 98.0061174,32 L21.9938826,32 C18.2292665,32 14.7684355,30.699197 12.0362474,28.5221601 C8.56516444,32.1765452 -1.77635684e-15,31.9985981 -1.77635684e-15,31.9985981 C5.69252399,28.6991366 5.98604874,24.4421608 5.99940747,24.1573436 L6,24.1422468 L6,16 C6,7.163444 13.1698213,0 21.9938826,0 L98.0061174,0 ")
|
||||
if outgoing.fill.rgb != outgoing.gradientFill.rgb {
|
||||
if Set(outgoing.fill.map(\.rgb)).count > 1 {
|
||||
c.clip()
|
||||
|
||||
let gradientColors = [outgoing.fill.withAlphaComponent(1.0), outgoing.gradientFill.withAlphaComponent(1.0)].map { $0.cgColor } as CFArray
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
|
||||
var colors: [CGColor] = []
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< outgoing.fill.count {
|
||||
let t = CGFloat(i) / CGFloat(outgoing.fill.count - 1)
|
||||
locations.append(t)
|
||||
colors.append(outgoing.fill[i].cgColor)
|
||||
}
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as NSArray, locations: &locations)!
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: 32.0), options: CGGradientDrawingOptions())
|
||||
} else {
|
||||
c.setFillColor(outgoing.fill.cgColor)
|
||||
c.setFillColor(outgoing.fill[0].cgColor)
|
||||
c.setStrokeColor(outgoing.stroke.cgColor)
|
||||
|
||||
c.strokePath()
|
||||
@ -1132,7 +1144,7 @@ public func themeImage(account: Account, accountManager: AccountManager, source:
|
||||
}
|
||||
}
|
||||
case let .settings(settings):
|
||||
theme = .single((makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false), nil))
|
||||
theme = .single((makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false), nil))
|
||||
}
|
||||
|
||||
enum WallpaperImage {
|
||||
@ -1280,7 +1292,7 @@ public func themeImage(account: Account, accountManager: AccountManager, source:
|
||||
}
|
||||
|
||||
public func themeIconImage(account: Account, accountManager: AccountManager, theme: PresentationThemeReference, color: PresentationThemeAccentColor?, wallpaper: TelegramWallpaper? = nil) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||
let colorsSignal: Signal<((UIColor, UIColor?, [UInt32]), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError>
|
||||
let colorsSignal: Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Int32?), NoError>
|
||||
|
||||
var reference: MediaResourceReference?
|
||||
if case let .local(theme) = theme {
|
||||
@ -1294,7 +1306,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
themeSignal = .single(makeDefaultPresentationTheme(reference: theme, serviceBackgroundColor: nil))
|
||||
} else if case let .cloud(theme) = theme, let settings = theme.theme.settings {
|
||||
themeSignal = Signal { subscriber in
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false)
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: [], bubbleColors: settings.messageColors, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false)
|
||||
subscriber.putNext(theme)
|
||||
subscriber.putCompletion()
|
||||
|
||||
@ -1314,13 +1326,13 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
}
|
||||
|
||||
colorsSignal = themeSignal
|
||||
|> mapToSignal { theme -> Signal<((UIColor, UIColor?, [UInt32]), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
|> mapToSignal { theme -> Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Int32?), NoError> in
|
||||
if let theme = theme {
|
||||
var wallpaperSignal: Signal<((UIColor, UIColor?, [UInt32]), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete()
|
||||
var wallpaperSignal: Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Int32?), NoError> = .complete()
|
||||
var rotation: Int32?
|
||||
var backgroundColor: (UIColor, UIColor?, [UInt32])
|
||||
let incomingColor = (theme.chat.message.incoming.bubble.withoutWallpaper.fill, theme.chat.message.incoming.bubble.withoutWallpaper.gradientFill)
|
||||
let outgoingColor = (theme.chat.message.outgoing.bubble.withoutWallpaper.fill, theme.chat.message.outgoing.bubble.withoutWallpaper.gradientFill)
|
||||
let incomingColors = theme.chat.message.incoming.bubble.withoutWallpaper.fill
|
||||
let outgoingColors = theme.chat.message.outgoing.bubble.withoutWallpaper.fill
|
||||
let wallpaper = wallpaper ?? theme.chat.defaultWallpaper
|
||||
switch wallpaper {
|
||||
case .builtin:
|
||||
@ -1364,7 +1376,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
var convertedRepresentations: [ImageRepresentationWithReference] = []
|
||||
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
|
||||
return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|
||||
|> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?, [UInt32]), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
|> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Int32?), NoError> in
|
||||
guard complete, let fullSizeData = fullSizeData else {
|
||||
return .complete()
|
||||
}
|
||||
@ -1374,9 +1386,9 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
if wallpaper.wallpaper.isPattern {
|
||||
if !file.settings.colors.isEmpty, let intensity = file.settings.intensity {
|
||||
if intensity < 0 {
|
||||
return .single(((.black, nil, []), incomingColor, outgoingColor, nil, rotation))
|
||||
return .single(((.black, nil, []), incomingColors, outgoingColors, nil, rotation))
|
||||
} else {
|
||||
return .single((effectiveBackgroundColor, incomingColor, outgoingColor, nil, rotation))
|
||||
return .single((effectiveBackgroundColor, incomingColors, outgoingColors, nil, rotation))
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
@ -1385,13 +1397,13 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true)
|
||||
|> mapToSignal { _ in
|
||||
if let image = UIImage(data: fullSizeData) {
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, image, rotation))
|
||||
return .single((backgroundColor, incomingColors, outgoingColors, image, rotation))
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
} else if let image = UIImage(data: fullSizeData) {
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, image, rotation))
|
||||
return .single((backgroundColor, incomingColors, outgoingColors, image, rotation))
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
@ -1401,7 +1413,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
}
|
||||
}
|
||||
}
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, nil, rotation))
|
||||
return .single((backgroundColor, incomingColors, outgoingColors, nil, rotation))
|
||||
|> then(wallpaperSignal)
|
||||
} else {
|
||||
return .complete()
|
||||
@ -1456,10 +1468,10 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
}
|
||||
}
|
||||
|
||||
let incomingColors = [colors.1.0, colors.1.1]
|
||||
let incomingColors = colors.1
|
||||
let incoming = generateGradientTintedImage(image: UIImage(bundleImageName: "Settings/ThemeBubble"), colors: incomingColors)
|
||||
|
||||
let outgoingColors = [colors.2.0, colors.2.1]
|
||||
let outgoingColors = colors.2
|
||||
let outgoing = generateGradientTintedImage(image: UIImage(bundleImageName: "Settings/ThemeBubble"), colors: outgoingColors)
|
||||
|
||||
c.translateBy(x: drawingRect.width / 2.0, y: drawingRect.height / 2.0)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user