Reaction improvements

This commit is contained in:
Ali 2022-09-05 21:48:49 +04:00
parent 229623491b
commit 78c9c2b15c
14 changed files with 447 additions and 64 deletions

View File

@ -287,7 +287,7 @@ public final class AvatarNode: ASDisplayNode {
self.imageNode.isHidden = true
}
public func setPeer(context: AccountContext, theme: PresentationTheme, peer: EnginePeer?, authorOfMessage: MessageReference? = nil, overrideImage: AvatarNodeImageOverride? = nil, emptyColor: UIColor? = nil, clipStyle: AvatarNodeClipStyle = .round, synchronousLoad: Bool = false, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0), storeUnrounded: Bool = false) {
public func setPeer(context genericContext: AccountContext, account: Account? = nil, theme: PresentationTheme, peer: EnginePeer?, authorOfMessage: MessageReference? = nil, overrideImage: AvatarNodeImageOverride? = nil, emptyColor: UIColor? = nil, clipStyle: AvatarNodeClipStyle = .round, synchronousLoad: Bool = false, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0), storeUnrounded: Bool = false) {
var synchronousLoad = synchronousLoad
var representation: TelegramMediaImageRepresentation?
var icon = AvatarNodeIcon.none
@ -317,7 +317,7 @@ public final class AvatarNode: ASDisplayNode {
representation = nil
icon = .phoneIcon
}
} else if peer?.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) == nil {
} else if peer?.restrictionText(platform: "ios", contentSettings: genericContext.currentContentSettings.with { $0 }) == nil {
representation = peer?.smallProfileImage
}
let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.displayLetters ?? [], representation)
@ -328,7 +328,9 @@ public final class AvatarNode: ASDisplayNode {
let parameters: AvatarNodeParameters
if let peer = peer, let signal = peerAvatarImage(account: context.account, peerReference: PeerReference(peer._asPeer()), authorOfMessage: authorOfMessage, representation: representation, displayDimensions: displayDimensions, round: clipStyle == .round, emptyColor: emptyColor, synchronousLoad: synchronousLoad, provideUnrounded: storeUnrounded) {
let account = account ?? genericContext.account
if let peer = peer, let signal = peerAvatarImage(account: account, peerReference: PeerReference(peer._asPeer()), authorOfMessage: authorOfMessage, representation: representation, displayDimensions: displayDimensions, round: clipStyle == .round, emptyColor: emptyColor, synchronousLoad: synchronousLoad, provideUnrounded: storeUnrounded) {
self.contents = nil
self.displaySuspended = true
self.imageReady.set(self.imageNode.contentReady)
@ -355,7 +357,7 @@ public final class AvatarNode: ASDisplayNode {
self.editOverlayNode?.isHidden = true
}
parameters = AvatarNodeParameters(theme: theme, accountPeerId: context.account.peerId, peerId: peer.id, letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle)
parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer.id, letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle)
} else {
self.imageReady.set(.single(true))
self.displaySuspended = false
@ -364,7 +366,7 @@ public final class AvatarNode: ASDisplayNode {
}
self.editOverlayNode?.isHidden = true
parameters = AvatarNodeParameters(theme: theme, accountPeerId: context.account.peerId, peerId: peer?.id ?? EnginePeer.Id(0), letters: peer?.displayLetters ?? [], font: self.font, icon: icon, explicitColorIndex: nil, hasImage: false, clipStyle: clipStyle)
parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer?.id ?? EnginePeer.Id(0), letters: peer?.displayLetters ?? [], font: self.font, icon: icon, explicitColorIndex: nil, hasImage: false, clipStyle: clipStyle)
}
if self.parameters == nil || self.parameters != parameters {
self.parameters = parameters

View File

@ -103,8 +103,12 @@ public final class ReactionIconView: PortalSourceView {
switch reaction {
case .builtin:
iconSize = CGSize(width: floor(size.width * 2.0), height: floor(size.height * 2.0))
animationLayer.masksToBounds = false
animationLayer.cornerRadius = 0.0
case .custom:
iconSize = CGSize(width: floor(size.width * 1.25), height: floor(size.height * 1.25))
animationLayer.masksToBounds = true
animationLayer.cornerRadius = floor(size.width * 0.2)
}
transition.updateFrame(layer: animationLayer, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize))
@ -154,6 +158,15 @@ public final class ReactionIconView: PortalSourceView {
self.animationLayer = animationLayer
self.layer.addSublayer(animationLayer)
switch reaction {
case .builtin:
animationLayer.masksToBounds = false
animationLayer.cornerRadius = 0.0
case .custom:
animationLayer.masksToBounds = true
animationLayer.cornerRadius = floor(size.width * 0.3)
}
animationLayer.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
animationLayer.isVisibleForAnimations = animateIdle
@ -763,7 +776,7 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
fileId: fileId,
animationCache: arguments.animationCache,
animationRenderer: arguments.animationRenderer,
placeholderColor: layout.spec.component.chosenOrder != nil ? UIColor(argb: layout.spec.component.colors.selectedForeground).withMultipliedAlpha(0.1) : UIColor(argb: layout.spec.component.colors.deselectedForeground).withMultipliedAlpha(0.1),
placeholderColor: layout.spec.component.chosenOrder != nil ? UIColor(argb: layout.spec.component.colors.selectedMediaPlaceholder) : UIColor(argb: layout.spec.component.colors.deselectedMediaPlaceholder),
animateIdle: animateIdle,
reaction: layout.spec.component.reaction.value,
transition: animation.transition
@ -929,6 +942,8 @@ public final class ReactionButtonComponent: Equatable {
public var selectedForeground: UInt32
public var extractedBackground: UInt32
public var extractedForeground: UInt32
public var deselectedMediaPlaceholder: UInt32
public var selectedMediaPlaceholder: UInt32
public init(
deselectedBackground: UInt32,
@ -936,7 +951,9 @@ public final class ReactionButtonComponent: Equatable {
deselectedForeground: UInt32,
selectedForeground: UInt32,
extractedBackground: UInt32,
extractedForeground: UInt32
extractedForeground: UInt32,
deselectedMediaPlaceholder: UInt32,
selectedMediaPlaceholder: UInt32
) {
self.deselectedBackground = deselectedBackground
self.selectedBackground = selectedBackground
@ -944,6 +961,8 @@ public final class ReactionButtonComponent: Equatable {
self.selectedForeground = selectedForeground
self.extractedBackground = extractedBackground
self.extractedForeground = extractedForeground
self.deselectedMediaPlaceholder = deselectedMediaPlaceholder
self.selectedMediaPlaceholder = selectedMediaPlaceholder
}
}

View File

@ -695,6 +695,14 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
currentMaskFrame = maskFrame
}
if let reaction = self.items[i].reaction, case .custom = reaction.rawValue, self.selectedItems.contains(reaction.rawValue) {
itemNode.layer.masksToBounds = true
itemNode.layer.cornerRadius = 12.0
} else {
itemNode.layer.masksToBounds = false
itemNode.layer.cornerRadius = 0.0
}
if !itemNode.isExtracted {
if isPreviewing {
if itemNode.supernode !== self.previewingItemContainer {
@ -923,7 +931,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
}
}
if let emojiView = reactionSelectionComponentHost.findTaggedView(tag: EmojiPagerContentComponent.Tag(id: AnyHashable("emoji"))) as? EmojiPagerContentComponent.View {
var initialPositionAndFrame: [MediaId: (frame: CGRect, frameIndex: Int, placeholder: UIImage)] = [:]
var initialPositionAndFrame: [MediaId: (frame: CGRect, cornerRadius: CGFloat, frameIndex: Int, placeholder: UIImage)] = [:]
for (_, itemNode) in self.visibleItemNodes {
guard let itemNode = itemNode as? ReactionNode else {
continue
@ -936,6 +944,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
}
initialPositionAndFrame[itemNode.item.stillAnimation.fileId] = (
frame: itemNode.frame,
cornerRadius: itemNode.layer.cornerRadius,
frameIndex: itemNode.currentFrameIndex,
placeholder: placeholder
)
@ -1140,7 +1149,12 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
items.append(ActionSheetTextItem(title: "Do you want to clear your recent reaction emoji from suggestions?", parseMarkdown: true))
items.append(ActionSheetButtonItem(title: presentationData.strings.Emoji_ClearRecent, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let _ = context.engine.stickers.clearRecentlyUsedReactions().start()
guard let strongSelf = self else {
return
}
strongSelf.scheduledEmojiContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupRemoved(id: "popular"))
let _ = strongSelf.context.engine.stickers.clearRecentlyUsedReactions().start()
}))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
@ -1658,6 +1672,11 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
case .began:
let point = recognizer.location(in: self.view)
if let itemNode = self.reactionItemNode(at: point) as? ReactionNode {
if self.selectedItems.contains(itemNode.item.reaction.rawValue) {
recognizer.state = .cancelled
return
}
self.highlightedReaction = itemNode.item.reaction
if #available(iOS 13.0, *) {
self.continuousHaptic = try? ContinuousHaptic(duration: longPressDuration)
@ -1935,7 +1954,19 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
}
self.itemNode = itemNode
if !forceSmallEffectAnimation {
let switchToInlineImmediately: Bool
if itemNode.item.listAnimation.isVideoEmoji || itemNode.item.listAnimation.isVideoSticker || itemNode.item.listAnimation.isAnimatedSticker || itemNode.item.listAnimation.isStaticEmoji {
switch itemNode.item.reaction.rawValue {
case .builtin:
switchToInlineImmediately = false
case .custom:
switchToInlineImmediately = true
}
} else {
switchToInlineImmediately = false
}
if !forceSmallEffectAnimation && !switchToInlineImmediately {
if let targetView = targetView as? ReactionIconView, !isLarge {
self.itemNodeIsEmbedded = true
targetView.addSubnode(itemNode)
@ -2161,6 +2192,15 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
return
}
/*if switchToInlineImmediately {
targetView.updateIsAnimationHidden(isAnimationHidden: false, transition: .immediate)
itemNode.isHidden = true
} else {
targetView.updateIsAnimationHidden(isAnimationHidden: true, transition: .immediate)
targetView.addSubnode(itemNode)
itemNode.frame = selfTargetBounds
}*/
if forceSmallEffectAnimation {
if let additionalAnimationNode = additionalAnimationNode {
additionalAnimationNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak additionalAnimationNode] _ in

View File

@ -178,13 +178,17 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.07),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff)
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1)
),
withoutWallpaper: chat.message.incoming.bubble.withoutWallpaper.withUpdated(
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.07),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff)
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1)
)
),
linkTextColor: accentColor,
@ -218,7 +222,9 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.12),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff),
reactionActiveForeground: UIColor(rgb: 0x000000, alpha: 0.0)
reactionActiveForeground: UIColor(rgb: 0x000000, alpha: 0.0),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1)
),
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
fill: outgoingBubbleFillColors,
@ -227,7 +233,9 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.12),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff),
reactionActiveForeground: UIColor(rgb: 0x000000, alpha: 0.0)
reactionActiveForeground: UIColor(rgb: 0x000000, alpha: 0.0),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1)
)
),
primaryTextColor: outgoingPrimaryTextColor,
@ -250,13 +258,17 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.12),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff)
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1)
),
withoutWallpaper: chat.message.freeform.withoutWallpaper.withUpdated(
reactionInactiveBackground: chat.message.incoming.bubble.withoutWallpaper.fill.last,
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff)
reactionActiveForeground: monochrome ? UIColor(rgb: 0x000000) : UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.1)
)
),
infoLinkTextColor: accentColor,
@ -498,7 +510,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0x1D1D1D, alpha: incomingBubbleAlpha)],
@ -508,7 +522,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
),
primaryTextColor: UIColor(rgb: 0xffffff),
@ -524,7 +540,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0x61BCF9), UIColor(rgb: 0x007AFF)],
@ -534,7 +552,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
), 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: 0xffffff, alpha: 0.2), 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)
),
@ -547,7 +567,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
reactionInactiveBackground: UIColor(rgb: 0x1f1f1f),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0x1f1f1f)],
@ -557,7 +579,9 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
reactionInactiveBackground: UIColor(rgb: 0x1f1f1f),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
),
infoPrimaryTextColor: UIColor(rgb: 0xffffff),

View File

@ -315,7 +315,9 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.07),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: UIColor(rgb: 0xffffff)
reactionActiveForeground: UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
fill: incomingFillColor.flatMap({ [$0] }),
@ -324,7 +326,9 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.07),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: UIColor(rgb: 0xffffff)
reactionActiveForeground: UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
),
secondaryTextColor: mainSecondaryTextColor?.withAlphaComponent(0.5),
@ -728,7 +732,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.07),
reactionInactiveForeground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveBackground: accentColor,
reactionActiveForeground: UIColor(rgb: 0xffffff, alpha: 1.0)
reactionActiveForeground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [incomingFillColor.withAlphaComponent(incomingBubbleAlpha)],
@ -738,7 +744,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.07),
reactionInactiveForeground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveBackground: accentColor,
reactionActiveForeground: UIColor(rgb: 0xffffff, alpha: 1.0)
reactionActiveForeground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
), 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
),
@ -752,7 +760,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: outgoingBubbleFillColors,
@ -762,7 +772,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.1),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 1.0),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
), 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
),
@ -775,7 +787,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
reactionInactiveBackground: incomingFillColor.withAlphaComponent(incomingBubbleAlpha),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: UIColor(rgb: 0xffffff)
reactionActiveForeground: UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [mainBackgroundColor],
@ -785,7 +799,9 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
reactionInactiveBackground: incomingFillColor.withAlphaComponent(incomingBubbleAlpha),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: accentColor,
reactionActiveForeground: UIColor(rgb: 0xffffff)
reactionActiveForeground: UIColor(rgb: 0xffffff),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1),
reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1)
)
),
infoPrimaryTextColor: UIColor(rgb: 0xffffff),

View File

@ -254,14 +254,18 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
reactionInactiveBackground: accentColor?.withMultipliedAlpha(0.1),
reactionInactiveForeground: accentColor,
reactionActiveBackground: accentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: chat.message.incoming.bubble.withoutWallpaper.withUpdated(
stroke: incomingBubbleStrokeColor,
reactionInactiveBackground: accentColor?.withMultipliedAlpha(0.1),
reactionInactiveForeground: accentColor,
reactionActiveBackground: accentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
linkHighlightColor: accentColor?.withAlphaComponent(0.3),
@ -290,7 +294,9 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
reactionInactiveBackground: outgoingControlColor?.withMultipliedAlpha(0.1),
reactionInactiveForeground: outgoingControlColor,
reactionActiveBackground: outgoingControlColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: chat.message.outgoing.bubble.withoutWallpaper.withUpdated(
fill: outgoingBubbleFillColors,
@ -299,7 +305,9 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
reactionInactiveBackground: outgoingControlColor?.withMultipliedAlpha(0.1),
reactionInactiveForeground: outgoingControlColor,
reactionActiveBackground: outgoingControlColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
primaryTextColor: outgoingPrimaryTextColor,
@ -567,7 +575,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: defaultDayAccentColor.withMultipliedAlpha(0.1),
reactionInactiveForeground: defaultDayAccentColor,
reactionActiveBackground: defaultDayAccentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0xffffff)],
@ -577,7 +587,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: defaultDayAccentColor.withMultipliedAlpha(0.1),
reactionInactiveForeground: defaultDayAccentColor,
reactionActiveBackground: defaultDayAccentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
primaryTextColor: UIColor(rgb: 0x000000),
@ -610,7 +622,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0x2DA32F).withMultipliedAlpha(0.12),
reactionInactiveForeground: UIColor(rgb: 0x2DA32F),
reactionActiveBackground: UIColor(rgb: 0x2DA32F),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0xe1ffc7)],
@ -620,7 +634,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0x2DA32F).withMultipliedAlpha(0.12),
reactionInactiveForeground: UIColor(rgb: 0x2DA32F),
reactionActiveBackground: UIColor(rgb: 0x2DA32F),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
primaryTextColor: UIColor(rgb: 0x000000),
@ -655,7 +671,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0xffffff),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 0.8),
reactionActiveForeground: UIColor(white: 0.0, alpha: 0.1)
reactionActiveForeground: UIColor(white: 0.0, alpha: 0.1),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0xffffff)],
@ -665,7 +683,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0xffffff),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff, alpha: 0.8),
reactionActiveForeground: UIColor(white: 0.0, alpha: 0.1)
reactionActiveForeground: UIColor(white: 0.0, alpha: 0.1),
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
infoPrimaryTextColor: UIColor(rgb: 0x000000),
@ -695,7 +715,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: defaultDayAccentColor.withMultipliedAlpha(0.1),
reactionInactiveForeground: defaultDayAccentColor,
reactionActiveBackground: defaultDayAccentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0xf1f1f4)],
@ -705,7 +727,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: .clear,
reactionInactiveForeground: defaultDayAccentColor,
reactionActiveBackground: defaultDayAccentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
primaryTextColor: UIColor(rgb: 0x000000),
@ -741,7 +765,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.12),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0x57b2e0), defaultDayAccentColor],
@ -751,7 +777,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0xffffff, alpha: 0.12),
reactionInactiveForeground: UIColor(rgb: 0xffffff),
reactionActiveBackground: UIColor(rgb: 0xffffff),
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
primaryTextColor: UIColor(rgb: 0xffffff),
@ -786,7 +814,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: defaultDayAccentColor.withMultipliedAlpha(0.1),
reactionInactiveForeground: defaultDayAccentColor,
reactionActiveBackground: defaultDayAccentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
),
withoutWallpaper: PresentationThemeBubbleColorComponents(
fill: [UIColor(rgb: 0xe5e5ea)],
@ -796,7 +826,9 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
reactionInactiveBackground: UIColor(rgb: 0xF1F0F5),
reactionInactiveForeground: defaultDayAccentColor,
reactionActiveBackground: defaultDayAccentColor,
reactionActiveForeground: .clear
reactionActiveForeground: .clear,
reactionInactiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2),
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
)
),
infoPrimaryTextColor: UIColor(rgb: 0x000000),

View File

@ -759,6 +759,8 @@ public final class PresentationThemeBubbleColorComponents {
public let reactionInactiveForeground: UIColor
public let reactionActiveBackground: UIColor
public let reactionActiveForeground: UIColor
public let reactionInactiveMediaPlaceholder: UIColor
public let reactionActiveMediaPlaceholder: UIColor
public init(
fill: [UIColor],
@ -768,7 +770,9 @@ public final class PresentationThemeBubbleColorComponents {
reactionInactiveBackground: UIColor,
reactionInactiveForeground: UIColor,
reactionActiveBackground: UIColor,
reactionActiveForeground: UIColor
reactionActiveForeground: UIColor,
reactionInactiveMediaPlaceholder: UIColor,
reactionActiveMediaPlaceholder: UIColor
) {
self.fill = fill
self.highlightedFill = highlightedFill
@ -778,6 +782,8 @@ public final class PresentationThemeBubbleColorComponents {
self.reactionInactiveForeground = reactionInactiveForeground
self.reactionActiveBackground = reactionActiveBackground
self.reactionActiveForeground = reactionActiveForeground
self.reactionInactiveMediaPlaceholder = reactionInactiveMediaPlaceholder
self.reactionActiveMediaPlaceholder = reactionActiveMediaPlaceholder
}
public func withUpdated(
@ -787,7 +793,9 @@ public final class PresentationThemeBubbleColorComponents {
reactionInactiveBackground: UIColor? = nil,
reactionInactiveForeground: UIColor? = nil,
reactionActiveBackground: UIColor? = nil,
reactionActiveForeground: UIColor? = nil
reactionActiveForeground: UIColor? = nil,
reactionInactiveMediaPlaceholder: UIColor? = nil,
reactionActiveMediaPlaceholder: UIColor? = nil
) -> PresentationThemeBubbleColorComponents {
return PresentationThemeBubbleColorComponents(
fill: fill ?? self.fill,
@ -797,7 +805,9 @@ public final class PresentationThemeBubbleColorComponents {
reactionInactiveBackground: reactionInactiveBackground ?? self.reactionInactiveBackground,
reactionInactiveForeground: reactionInactiveForeground ?? self.reactionInactiveForeground,
reactionActiveBackground: reactionActiveBackground ?? self.reactionActiveBackground,
reactionActiveForeground: reactionActiveForeground ?? self.reactionActiveForeground
reactionActiveForeground: reactionActiveForeground ?? self.reactionActiveForeground,
reactionInactiveMediaPlaceholder: reactionInactiveMediaPlaceholder ?? self.reactionInactiveMediaPlaceholder,
reactionActiveMediaPlaceholder: reactionActiveMediaPlaceholder ?? self.reactionActiveMediaPlaceholder
)
}
}

View File

@ -1109,6 +1109,8 @@ extension PresentationThemeBubbleColorComponents: Codable {
case bgList
case reactionInactiveBg
case reactionInactiveFg
case reactionInactiveMediaPlaceholder
case reactionActiveMediaPlaceholder
case reactionActiveBg
case reactionActiveFg
case __workaroundNonexistingKey
@ -1147,6 +1149,20 @@ extension PresentationThemeBubbleColorComponents: Codable {
reactionInactiveBackground = (try decodeColor(values, .__workaroundNonexistingKey, fallbackKey: "\(fallbackKeyPrefix).accentControl")).withMultipliedAlpha(0.1)
}
let reactionInactiveMediaPlaceholder: UIColor
if let color = try? decodeColor(values, .reactionInactiveMediaPlaceholder) {
reactionInactiveMediaPlaceholder = color
} else {
reactionInactiveMediaPlaceholder = (try decodeColor(values, .__workaroundNonexistingKey, fallbackKey: "\(fallbackKeyPrefix).accentControl")).withMultipliedAlpha(0.1)
}
let reactionActiveMediaPlaceholder: UIColor
if let color = try? decodeColor(values, .reactionActiveMediaPlaceholder) {
reactionActiveMediaPlaceholder = color
} else {
reactionActiveMediaPlaceholder = (try decodeColor(values, .__workaroundNonexistingKey, fallbackKey: "\(fallbackKeyPrefix).accentControl")).withMultipliedAlpha(0.1)
}
let reactionInactiveForeground: UIColor
if let color = try? decodeColor(values, .reactionInactiveFg) {
reactionInactiveForeground = color
@ -1176,7 +1192,9 @@ extension PresentationThemeBubbleColorComponents: Codable {
reactionInactiveBackground: reactionInactiveBackground,
reactionInactiveForeground: reactionInactiveForeground,
reactionActiveBackground: reactionActiveBackground,
reactionActiveForeground: reactionActiveForeground
reactionActiveForeground: reactionActiveForeground,
reactionInactiveMediaPlaceholder: reactionInactiveMediaPlaceholder,
reactionActiveMediaPlaceholder: reactionActiveMediaPlaceholder
)
}
@ -1199,6 +1217,8 @@ extension PresentationThemeBubbleColorComponents: Codable {
try encodeColor(&values, self.reactionInactiveForeground, .reactionInactiveFg)
try encodeColor(&values, self.reactionActiveBackground, .reactionActiveBg)
try encodeColor(&values, self.reactionActiveForeground, .reactionActiveFg)
try encodeColor(&values, self.reactionInactiveMediaPlaceholder, .reactionInactiveMediaPlaceholder)
try encodeColor(&values, self.reactionActiveMediaPlaceholder, .reactionActiveMediaPlaceholder)
}
}

View File

@ -1511,6 +1511,7 @@ public final class EmojiPagerContentComponent: Component {
case generic
case groupExpanded(id: AnyHashable)
case groupInstalled(id: AnyHashable)
case groupRemoved(id: AnyHashable)
}
public let type: AnimationType
@ -2779,7 +2780,7 @@ public final class EmojiPagerContentComponent: Component {
}
}
public func animateInReactionSelection(sourceItems: [MediaId: (frame: CGRect, frameIndex: Int, placeholder: UIImage)]) {
public func animateInReactionSelection(sourceItems: [MediaId: (frame: CGRect, cornerRadius: CGFloat, frameIndex: Int, placeholder: UIImage)]) {
guard let component = self.component, let itemLayout = self.itemLayout else {
return
}
@ -2800,6 +2801,13 @@ public final class EmojiPagerContentComponent: Component {
itemSelectionLayer.animate(from: (min(sourceItem.frame.width, sourceItem.frame.height) * 0.5) as NSNumber, to: 8.0 as NSNumber, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.3)
}
if sourceItem.cornerRadius > 0.0 {
itemLayer.masksToBounds = true
itemLayer.animate(from: sourceItem.cornerRadius as NSNumber, to: 0.0 as NSNumber, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.3, completion: { [weak itemLayer] _ in
itemLayer?.masksToBounds = false
})
}
component.animationRenderer.setFrameIndex(itemId: animationData.resource.resource.id.stringRepresentation, size: itemLayer.pixelSize, frameIndex: sourceItem.frameIndex, placeholder: sourceItem.placeholder)
} else {
let distance = itemLayer.position.y - itemLayout.frame(groupIndex: 0, itemIndex: 0).midY
@ -3609,6 +3617,8 @@ public final class EmojiPagerContentComponent: Component {
transitionHintInstalledGroupId = groupId
case let .groupExpanded(groupId):
transitionHintExpandedGroupId = groupId
case let .groupRemoved(groupId):
transitionHintInstalledGroupId = groupId
default:
break
}
@ -4482,6 +4492,8 @@ public final class EmojiPagerContentComponent: Component {
transitionHintInstalledGroupId = groupId
case let .groupExpanded(groupId):
transitionHintExpandedGroupId = groupId
case let .groupRemoved(groupId):
transitionHintInstalledGroupId = groupId
default:
break
}
@ -4588,6 +4600,10 @@ public final class EmojiPagerContentComponent: Component {
}
}
if transitionHintExpandedGroupId != nil {
calculateUpdatedItemPositions = true
}
var itemGroups: [ItemGroupDescription] = []
for itemGroup in component.itemGroups {
itemGroups.append(ItemGroupDescription(
@ -4901,7 +4917,7 @@ public final class EmojiPagerContentComponent: Component {
var existingIds = Set<MediaId>()
for file in iconStatusEmoji {
for file in iconStatusEmoji.prefix(7) {
if existingIds.contains(file.fileId) {
continue
}
@ -4982,7 +4998,7 @@ public final class EmojiPagerContentComponent: Component {
}
}
if let featuredStatusEmoji = featuredStatusEmoji {
for item in featuredStatusEmoji.items.prefix(7) {
for item in featuredStatusEmoji.items {
guard let item = item.contents.get(RecentMediaItem.self) else {
continue
}

View File

@ -530,6 +530,7 @@ public final class EntityKeyboardComponent: Component {
items: topEmojiItems,
containerSideInset: component.containerInsets.left + component.topPanelInsets.left,
activeContentItemIdUpdated: emojiContentItemIdUpdated,
activeContentItemMapping: ["popular": "recent"],
reorderItems: { [weak self] items in
guard let strongSelf = self else {
return

View File

@ -1170,6 +1170,7 @@ public final class EntityKeyboardTopPanelComponent: Component {
let defaultActiveItemId: AnyHashable?
let forceActiveItemId: AnyHashable?
let activeContentItemIdUpdated: ActionSlot<(AnyHashable, AnyHashable?, Transition)>
let activeContentItemMapping: [AnyHashable: AnyHashable]
let reorderItems: ([Item]) -> Void
init(
@ -1180,6 +1181,7 @@ public final class EntityKeyboardTopPanelComponent: Component {
defaultActiveItemId: AnyHashable? = nil,
forceActiveItemId: AnyHashable? = nil,
activeContentItemIdUpdated: ActionSlot<(AnyHashable, AnyHashable?, Transition)>,
activeContentItemMapping: [AnyHashable: AnyHashable] = [:],
reorderItems: @escaping ([Item]) -> Void
) {
self.id = id
@ -1189,6 +1191,7 @@ public final class EntityKeyboardTopPanelComponent: Component {
self.defaultActiveItemId = defaultActiveItemId
self.forceActiveItemId = forceActiveItemId
self.activeContentItemIdUpdated = activeContentItemIdUpdated
self.activeContentItemMapping = activeContentItemMapping
self.reorderItems = reorderItems
}
@ -2037,9 +2040,10 @@ public final class EntityKeyboardTopPanelComponent: Component {
}
component.activeContentItemIdUpdated.connect { [weak self] (itemId, subcontentItemId, transition) in
guard let strongSelf = self else {
guard let strongSelf = self, let component = strongSelf.component else {
return
}
let itemId = component.activeContentItemMapping[itemId] ?? itemId
strongSelf.activeContentItemIdUpdated(itemId: itemId, subcontentItemId: subcontentItemId, transition: transition)
}

View File

@ -386,7 +386,9 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
deselectedForeground: themeColors.reactionInactiveForeground.argb,
selectedForeground: themeColors.reactionActiveForeground.argb,
extractedBackground: arguments.presentationData.theme.theme.contextMenu.backgroundColor.argb,
extractedForeground: arguments.presentationData.theme.theme.contextMenu.primaryColor.argb
extractedForeground: arguments.presentationData.theme.theme.contextMenu.primaryColor.argb,
deselectedMediaPlaceholder: themeColors.reactionInactiveMediaPlaceholder.argb,
selectedMediaPlaceholder: themeColors.reactionActiveMediaPlaceholder.argb
)
case .BubbleOutgoing, .ImageOutgoing, .FreeOutgoing:
let themeColors = bubbleColorComponents(theme: arguments.presentationData.theme.theme, incoming: false, wallpaper: !arguments.presentationData.theme.wallpaper.isEmpty)
@ -397,7 +399,9 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
deselectedForeground: themeColors.reactionInactiveForeground.argb,
selectedForeground: themeColors.reactionActiveForeground.argb,
extractedBackground: arguments.presentationData.theme.theme.contextMenu.backgroundColor.argb,
extractedForeground: arguments.presentationData.theme.theme.contextMenu.primaryColor.argb
extractedForeground: arguments.presentationData.theme.theme.contextMenu.primaryColor.argb,
deselectedMediaPlaceholder: themeColors.reactionInactiveMediaPlaceholder.argb,
selectedMediaPlaceholder: themeColors.reactionActiveMediaPlaceholder.argb
)
}

View File

@ -103,7 +103,9 @@ final class MessageReactionButtonsNode: ASDisplayNode {
deselectedForeground: themeColors.reactionInactiveForeground.argb,
selectedForeground: themeColors.reactionActiveForeground.argb,
extractedBackground: presentationData.theme.theme.contextMenu.backgroundColor.argb,
extractedForeground: presentationData.theme.theme.contextMenu.primaryColor.argb
extractedForeground: presentationData.theme.theme.contextMenu.primaryColor.argb,
deselectedMediaPlaceholder: themeColors.reactionInactiveMediaPlaceholder.argb,
selectedMediaPlaceholder: themeColors.reactionActiveMediaPlaceholder.argb
)
case .outgoing:
themeColors = bubbleColorComponents(theme: presentationData.theme.theme, incoming: false, wallpaper: !presentationData.theme.wallpaper.isEmpty)
@ -113,7 +115,9 @@ final class MessageReactionButtonsNode: ASDisplayNode {
deselectedForeground: themeColors.reactionInactiveForeground.argb,
selectedForeground: themeColors.reactionActiveForeground.argb,
extractedBackground: presentationData.theme.theme.contextMenu.backgroundColor.argb,
extractedForeground: presentationData.theme.theme.contextMenu.primaryColor.argb
extractedForeground: presentationData.theme.theme.contextMenu.primaryColor.argb,
deselectedMediaPlaceholder: themeColors.reactionInactiveMediaPlaceholder.argb,
selectedMediaPlaceholder: themeColors.reactionActiveMediaPlaceholder.argb
)
case .freeform:
if presentationData.theme.wallpaper.isEmpty {
@ -128,7 +132,9 @@ final class MessageReactionButtonsNode: ASDisplayNode {
deselectedForeground: themeColors.reactionInactiveForeground.argb,
selectedForeground: themeColors.reactionActiveForeground.argb,
extractedBackground: presentationData.theme.theme.contextMenu.backgroundColor.argb,
extractedForeground: presentationData.theme.theme.contextMenu.primaryColor.argb
extractedForeground: presentationData.theme.theme.contextMenu.primaryColor.argb,
deselectedMediaPlaceholder: themeColors.reactionInactiveMediaPlaceholder.argb,
selectedMediaPlaceholder: themeColors.reactionActiveMediaPlaceholder.argb
)
}

View File

@ -73,6 +73,9 @@ import EmojiStatusSelectionComponent
import AnimationCache
import MultiAnimationRenderer
import EntityKeyboard
import AvatarNode
import ComponentFlow
import EmojiStatusComponent
protocol PeerInfoScreenItem: AnyObject {
var id: AnyHashable { get }
@ -8421,11 +8424,15 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
})))
let avatarSize = CGSize(width: 28.0, height: 28.0)
//let avatarSize = CGSize(width: 28.0, height: 28.0)
items.append(.action(ContextMenuActionItem(text: primary.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: primary.0.account, peer: primary.1, size: avatarSize)), action: { _, f in
items.append(.custom(AccountPeerContextItem(context: self.context, account: self.context.account, peer: primary.1, action: { _, f in
f(.default)
})))
}), true))
/*items.append(.action(ContextMenuActionItem(text: primary.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: primary.0.account, peer: primary.1, size: avatarSize)), action: { _, f in
f(.default)
})))*/
if !other.isEmpty {
items.append(.separator)
@ -8433,13 +8440,20 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
for account in other {
let id = account.0.account.id
items.append(.action(ContextMenuActionItem(text: account.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), badge: account.2 != 0 ? ContextMenuActionBadge(value: "\(account.2)", color: .accent) : nil, icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: account.0.account, peer: account.1, size: avatarSize)), action: { [weak self] _, f in
items.append(.custom(AccountPeerContextItem(context: self.context, account: account.0.account, peer: account.1, action: { [weak self] _, f in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.switchToAccount(id: id)
f(.dismissWithoutContent)
})))
}), true))
/*items.append(.action(ContextMenuActionItem(text: account.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), badge: account.2 != 0 ? ContextMenuActionBadge(value: "\(account.2)", color: .accent) : nil, icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: account.0.account, peer: account.1, size: avatarSize)), action: { [weak self] _, f in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.switchToAccount(id: id)
f(.dismissWithoutContent)
})))*/
}
let controller = ContextController(account: primary.0.account, presentationData: self.presentationData, source: .extracted(SettingsTabBarContextExtractedContentSource(controller: self, sourceNode: sourceNode)), items: .single(ContextController.Items(content: .list(items))), recognizer: nil, gesture: gesture)
@ -9166,3 +9180,178 @@ struct ClearPeerHistory {
}
}
}
private final class AccountPeerContextItem: ContextMenuCustomItem {
let context: AccountContext
let account: Account
let peer: EnginePeer
let action: (ContextControllerProtocol, @escaping (ContextMenuActionResult) -> Void) -> Void
init(context: AccountContext, account: Account, peer: EnginePeer, action: @escaping (ContextControllerProtocol, @escaping (ContextMenuActionResult) -> Void) -> Void) {
self.context = context
self.account = account
self.peer = peer
self.action = action
}
public func node(presentationData: PresentationData, getController: @escaping () -> ContextControllerProtocol?, actionSelected: @escaping (ContextMenuActionResult) -> Void) -> ContextMenuCustomNode {
return AccountPeerContextItemNode(presentationData: presentationData, item: self, getController: getController, actionSelected: actionSelected)
}
}
private final class AccountPeerContextItemNode: ASDisplayNode, ContextMenuCustomNode {
private let item: AccountPeerContextItem
private let presentationData: PresentationData
private let getController: () -> ContextControllerProtocol?
private let actionSelected: (ContextMenuActionResult) -> Void
private let highlightedBackgroundNode: ASDisplayNode
private let buttonNode: HighlightTrackingButtonNode
private let textNode: ImmediateTextNode
private let avatarNode: AvatarNode
private let emojiStatusView: ComponentView<Empty>
init(presentationData: PresentationData, item: AccountPeerContextItem, getController: @escaping () -> ContextControllerProtocol?, actionSelected: @escaping (ContextMenuActionResult) -> Void) {
self.item = item
self.presentationData = presentationData
self.getController = getController
self.actionSelected = actionSelected
let textFont = Font.regular(presentationData.listsFontSize.baseDisplaySize * 17.0 / 17.0)
self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isAccessibilityElement = false
self.highlightedBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
self.highlightedBackgroundNode.alpha = 0.0
self.textNode = ImmediateTextNode()
self.textNode.isAccessibilityElement = false
self.textNode.isUserInteractionEnabled = false
self.textNode.displaysAsynchronously = false
let peerTitle = item.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
self.textNode.attributedText = NSAttributedString(string: peerTitle, font: textFont, textColor: presentationData.theme.contextMenu.primaryColor)
self.textNode.maximumNumberOfLines = 1
self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 14.0))
self.emojiStatusView = ComponentView<Empty>()
self.buttonNode = HighlightTrackingButtonNode()
self.buttonNode.isAccessibilityElement = true
self.buttonNode.accessibilityLabel = peerTitle
super.init()
self.addSubnode(self.highlightedBackgroundNode)
self.addSubnode(self.textNode)
self.addSubnode(self.avatarNode)
self.addSubnode(self.buttonNode)
self.buttonNode.highligthedChanged = { [weak self] highligted in
guard let strongSelf = self else {
return
}
if highligted {
strongSelf.highlightedBackgroundNode.alpha = 1.0
} else {
strongSelf.highlightedBackgroundNode.alpha = 0.0
strongSelf.highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
}
}
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
}
func updateLayout(constrainedWidth: CGFloat, constrainedHeight: CGFloat) -> (CGSize, (CGSize, ContainedViewLayoutTransition) -> Void) {
let sideInset: CGFloat = 16.0
let iconSideInset: CGFloat = 12.0
let verticalInset: CGFloat = 12.0
let iconSize = CGSize(width: 28.0, height: 28.0)
let standardIconWidth: CGFloat = 32.0
var rightTextInset: CGFloat = sideInset
if !iconSize.width.isZero {
rightTextInset = max(iconSize.width, standardIconWidth) + iconSideInset + sideInset - 12.0
}
self.avatarNode.setPeer(context: self.item.context, account: self.item.account, theme: self.presentationData.theme, peer: self.item.peer)
if case let .user(user) = self.item.peer, let _ = user.emojiStatus {
rightTextInset += 32.0
}
let textSize = self.textNode.updateLayout(CGSize(width: constrainedWidth - sideInset - rightTextInset, height: .greatestFiniteMagnitude))
return (CGSize(width: textSize.width + sideInset + rightTextInset, height: verticalInset * 2.0 + textSize.height), { size, transition in
let verticalOrigin = floor((size.height - textSize.height) / 2.0)
let textFrame = CGRect(origin: CGPoint(x: sideInset, y: verticalOrigin), size: textSize)
transition.updateFrameAdditive(node: self.textNode, frame: textFrame)
if case let .user(user) = self.item.peer, let emojiStatus = user.emojiStatus {
let emojiStatusSize = self.emojiStatusView.update(
transition: .immediate,
component: AnyComponent(EmojiStatusComponent(
context: self.item.context,
animationCache: self.item.context.animationCache,
animationRenderer: self.item.context.animationRenderer,
content: .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 28.0, height: 28.0), placeholderColor: self.presentationData.theme.list.mediaPlaceholderColor, themeColor: self.presentationData.theme.list.itemAccentColor, loopMode: .forever),
isVisibleForAnimations: true,
action: nil
)),
environment: {},
containerSize: CGSize(width: 28.0, height: 28.0)
)
if let view = self.emojiStatusView.view {
if view.superview == nil {
self.view.addSubview(view)
}
transition.updateFrame(view: view, frame: CGRect(origin: CGPoint(x: textFrame.maxX + 2.0, y: textFrame.minY + floor((textFrame.height - emojiStatusSize.height) / 2.0)), size: emojiStatusSize))
}
}
transition.updateFrame(node: self.avatarNode, frame: CGRect(origin: CGPoint(x: size.width - standardIconWidth - iconSideInset + floor((standardIconWidth - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize))
transition.updateFrame(node: self.highlightedBackgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)))
transition.updateFrame(node: self.buttonNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)))
})
}
func updateTheme(presentationData: PresentationData) {
self.highlightedBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
if let attributedText = self.textNode.attributedText {
let updatedAttributedText = NSMutableAttributedString(attributedString: attributedText)
updatedAttributedText.addAttribute(.foregroundColor, value: presentationData.theme.contextMenu.primaryColor.cgColor, range: NSRange(location: 0, length: updatedAttributedText.length))
self.textNode.attributedText = updatedAttributedText
}
}
@objc private func buttonPressed() {
self.performAction()
}
func canBeHighlighted() -> Bool {
return true
}
func setIsHighlighted(_ value: Bool) {
if value {
self.highlightedBackgroundNode.alpha = 1.0
} else {
self.highlightedBackgroundNode.alpha = 0.0
}
}
func updateIsHighlighted(isHighlighted: Bool) {
self.setIsHighlighted(isHighlighted)
}
func performAction() {
guard let controller = self.getController() else {
return
}
self.item.action(controller, { [weak self] result in
self?.actionSelected(result)
})
}
}