@@ -12,6 +12,7 @@ import TelegramCore
12
12
import Postbox
13
13
import TGUIKit
14
14
import Accelerate
15
+ import AppKit
15
16
16
17
class InlineStickerLockLayer : SimpleLayer {
17
18
private let lockedView : SimpleLayer = SimpleLayer ( )
@@ -250,14 +251,14 @@ private final class MultiTargetContextCache {
250
251
}
251
252
252
253
final class InlineStickerView : View {
253
- init ( account: Account , inlinePacksContext: InlineStickersContext ? , emoji: ChatTextCustomEmojiAttribute , size: NSSize , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil ) {
254
- let layer = InlineStickerItemLayer ( account: account, inlinePacksContext: inlinePacksContext, emoji: emoji, size: size, getColors: getColors)
254
+ init ( account: Account , inlinePacksContext: InlineStickersContext ? , emoji: ChatTextCustomEmojiAttribute , size: NSSize , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil , shimmerColor : InlineStickerItemLayer . Shimmer = . init ( circle : false ) ) {
255
+ let layer = InlineStickerItemLayer ( account: account, inlinePacksContext: inlinePacksContext, emoji: emoji, size: size, getColors: getColors, shimmerColor : shimmerColor )
255
256
super. init ( frame: size. bounds)
256
257
self . layer = layer
257
258
layer. superview = self
258
259
}
259
- init ( account: Account , file: TelegramMediaFile , size: NSSize , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil ) {
260
- let layer = InlineStickerItemLayer ( account: account, file: file, size: size, getColors: getColors)
260
+ init ( account: Account , file: TelegramMediaFile , size: NSSize , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil , shimmerColor : InlineStickerItemLayer . Shimmer = . init ( circle : false ) ) {
261
+ let layer = InlineStickerItemLayer ( account: account, file: file, size: size, getColors: getColors, shimmerColor : shimmerColor )
261
262
super. init ( frame: size. bounds)
262
263
self . layer = layer
263
264
layer. superview = self
@@ -359,11 +360,23 @@ final class InlineStickerItemLayer : SimpleLayer {
359
360
360
361
private let getColors : ( ( TelegramMediaFile ) -> [ LottieColor ] ) ?
361
362
362
- init ( account: Account , inlinePacksContext: InlineStickersContext ? , emoji: ChatTextCustomEmojiAttribute , size: NSSize , playPolicy: LottiePlayPolicy = . loop, checkStatus: Bool = false , aspectFilled: Bool = false , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil ) {
363
+ struct Shimmer {
364
+ let color : NSColor
365
+ let circle : Bool
366
+ init ( color: NSColor = NSColor ( 0x748391 ) , circle: Bool ) {
367
+ self . color = color
368
+ self . circle = circle
369
+ }
370
+ }
371
+ private let shimmerColor : Shimmer
372
+
373
+
374
+ init ( account: Account , inlinePacksContext: InlineStickersContext ? , emoji: ChatTextCustomEmojiAttribute , size: NSSize , playPolicy: LottiePlayPolicy = . loop, checkStatus: Bool = false , aspectFilled: Bool = false , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil , shimmerColor: Shimmer = Shimmer ( circle: false ) ) {
363
375
self . aspectFilled = aspectFilled
364
376
self . account = account
365
377
self . playPolicy = playPolicy
366
378
self . getColors = getColors
379
+ self . shimmerColor = shimmerColor
367
380
super. init ( )
368
381
self . frame = size. bounds
369
382
self . initialize ( )
@@ -386,11 +399,12 @@ final class InlineStickerItemLayer : SimpleLayer {
386
399
} )
387
400
}
388
401
389
- init ( account: Account , file: TelegramMediaFile , size: NSSize , playPolicy: LottiePlayPolicy = . loop, aspectFilled: Bool = false , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil ) {
402
+ init ( account: Account , file: TelegramMediaFile , size: NSSize , playPolicy: LottiePlayPolicy = . loop, aspectFilled: Bool = false , getColors: ( ( TelegramMediaFile ) -> [ LottieColor ] ) ? = nil , shimmerColor : Shimmer = Shimmer ( circle : false ) ) {
390
403
self . aspectFilled = aspectFilled
391
404
self . account = account
392
405
self . playPolicy = playPolicy
393
406
self . getColors = getColors
407
+ self . shimmerColor = shimmerColor
394
408
super. init ( )
395
409
self . initialize ( )
396
410
self . file = file
@@ -449,20 +463,26 @@ final class InlineStickerItemLayer : SimpleLayer {
449
463
}
450
464
}
451
465
}
466
+ private var isPreviousPreview : Bool = false
467
+
452
468
private var contextToken : ( Int , MultiTargetContextCache . Key ) ?
453
469
private func set( _ animation: LottieAnimation ? , force: Bool = false ) {
454
470
self . animation = animation
455
471
if let animation = animation, let isPlayable = self . isPlayable, isPlayable, !stopped {
456
- weak var layer : CALayer ? = self
472
+ weak var layer : InlineStickerItemLayer ? = self
457
473
let key : MultiTargetContextCache . Key = . init( key: animation. key, unique: unique)
458
474
delayDisposable. set ( delaySignal ( MultiTargetContextCache . exists ( key) || force ? 0 : 0.1 ) . start ( completed: { [ weak self] in
459
-
475
+
460
476
self ? . contextToken = ( MultiTargetContextCache . create ( animation, key: key, displayFrame: { image in
461
477
DispatchQueue . main. async {
462
478
layer? . contents = image
479
+ if layer? . isPreviousPreview == true {
480
+ layer? . animateContents ( )
481
+ layer? . isPreviousPreview = false
482
+ }
463
483
}
464
484
} , release: {
465
-
485
+
466
486
} , updateState: { [ weak self] state in
467
487
self ? . updateState ( state)
468
488
} ) , key)
@@ -590,7 +610,7 @@ final class InlineStickerItemLayer : SimpleLayer {
590
610
}
591
611
592
612
fetchDisposable. set ( fetchedMediaResource ( mediaBox: account. postbox. mediaBox, reference: mediaResource) . start ( ) )
593
-
613
+ let shimmerColor = self . shimmerColor
594
614
let fillColor : NSColor ? = getColors ? ( file) . first? . color
595
615
let emptyColor : TransformImageEmptyColor ?
596
616
if let fillColor = fillColor {
@@ -612,28 +632,29 @@ final class InlineStickerItemLayer : SimpleLayer {
612
632
613
633
614
634
let signal : Signal < ImageDataTransformation , NoError >
615
-
635
+
616
636
switch file. mimeType {
617
637
case " image/webp " :
618
638
signal = chatMessageSticker ( postbox: account. postbox, file: reference, small: aspectSize. width <= 5 , scale: System . backingScale, fetched: true )
619
639
default :
620
640
signal = chatMessageAnimatedSticker ( postbox: account. postbox, file: reference, small: aspectSize. width <= 5 , scale: System . backingScale, size: aspectSize, fetched: true , thumbAtFrame: 0 , isVideo: file. fileName == " webm-preview " || file. isVideoSticker)
621
641
}
622
-
642
+
623
643
var result : TransformImageResult ?
624
644
_ = cachedMedia ( media: file, arguments: arguments, scale: System . backingScale) . start ( next: { value in
625
645
result = value
626
646
} )
627
647
if self . playerState != . playing {
628
648
self . contents = result? . image
629
-
649
+
630
650
if let image = result? . image {
631
651
self . preview = image
652
+ self . isPreviousPreview = true
632
653
}
633
654
}
634
655
635
656
636
- if self . preview == nil , let data = file . immediateThumbnailData , self . playerState != . playing {
657
+ if self . preview == nil , self . playerState != . playing {
637
658
638
659
let dataSignal = account. postbox. mediaBox. resourceData ( mediaResource. resource)
639
660
|> map { $0. complete }
@@ -649,10 +670,19 @@ final class InlineStickerItemLayer : SimpleLayer {
649
670
current = ShimmerLayer ( )
650
671
self ? . addSublayer ( current)
651
672
self ? . shimmer = current
652
- current. frame = size. bounds. focus ( aspectSize)
653
673
}
654
- current. update ( backgroundColor: nil , foregroundColor: NSColor ( rgb: 0x748391 , alpha: 0.2 ) , shimmeringColor: NSColor ( rgb: 0x748391 , alpha: 0.35 ) , data: data, size: aspectSize)
655
- current. updateAbsoluteRect ( size. bounds, within: aspectSize)
674
+
675
+ let data = shimmerColor. circle ? nil : file. immediateThumbnailData
676
+
677
+ let shimmerSize = aspectSize
678
+
679
+ current. update ( backgroundColor: nil , foregroundColor: shimmerColor. color. withAlphaComponent ( 0.2 ) , shimmeringColor: shimmerColor. color. withAlphaComponent ( 0.35 ) , data: data, size: shimmerSize)
680
+ current. updateAbsoluteRect ( size. bounds, within: shimmerSize)
681
+
682
+ current. frame = size. bounds. focus ( aspectSize)
683
+
684
+ self ? . isPreviousPreview = true
685
+
656
686
} else {
657
687
if let shimmer = self ? . shimmer {
658
688
shimmer. animateAlpha ( from: 1 , to: 0 , duration: 0.2 , removeOnCompletion: false , completion: { [ weak shimmer] _ in
@@ -683,11 +713,15 @@ final class InlineStickerItemLayer : SimpleLayer {
683
713
let fontImage = fontContext? . generateImage ( )
684
714
return ( TransformImageResult ( image, context? . isHighQuality ?? false ) , TransformImageResult ( fontImage, fontContext? . isHighQuality ?? false ) )
685
715
} |> deliverOnMainQueue
686
-
716
+
687
717
previewDisposable = result. start ( next: { [ weak self] result, fontResult in
688
718
if self ? . playerState != . playing {
689
719
self ? . contents = result. image
690
720
}
721
+ if self ? . isPreviousPreview == true {
722
+ self ? . animateContents ( )
723
+ self ? . isPreviousPreview = false
724
+ }
691
725
if let image = result. image {
692
726
self ? . preview = image
693
727
if let shimmer = self ? . shimmer {
@@ -697,7 +731,7 @@ final class InlineStickerItemLayer : SimpleLayer {
697
731
self ? . shimmer = nil
698
732
}
699
733
}
700
-
734
+
701
735
cacheMedia ( fontResult, media: file, arguments: fontArguments, scale: System . backingScale)
702
736
cacheMedia ( result, media: file, arguments: arguments, scale: System . backingScale)
703
737
} )
0 commit comments