UI improvements

This commit is contained in:
Ali 2023-01-31 12:42:37 +01:00
parent 38935ca811
commit 4b2902ac71
21 changed files with 267 additions and 59 deletions

View File

@ -8847,3 +8847,7 @@ Sorry for the inconvenience.";
"Chat.PlaceholderTextNotAllowed" = "Text not allowed";
"CallList.DeleteAll" = "Delete All";
"DataUsage.TopSectionAll" = "All";
"DataUsage.TopSectionMobile" = "Mobile";
"DataUsage.TopSectionWifi" = "Wifi";

View File

@ -76,4 +76,6 @@
+ (NSData *)_manuallyEncryptedMessage:(NSData *)preparedData messageId:(int64_t)messageId authKey:(MTDatacenterAuthKey *)authKey;
- (void)simulateDisconnection;
@end

View File

@ -62,4 +62,6 @@
- (void)updateSchemes:(NSArray<MTTransportScheme *> * _Nonnull)schemes;
- (void)simulateDisconnection;
@end

View File

@ -228,7 +228,7 @@ static int32_t fixedTimeDifferenceValue = 0;
_isTestingEnvironment = isTestingEnvironment;
_useTempAuthKeys = useTempAuthKeys;
#if DEBUG
_tempKeyExpiration = 10 * 60;
_tempKeyExpiration = 30;
#else
_tempKeyExpiration = 24 * 60 * 60;
#endif

View File

@ -247,6 +247,12 @@ typedef enum {
}
case MTDatacenterAuthStageReqDH:
{
#if DEBUG
if (arc4random_uniform(100) < 50) {
[mtProto simulateDisconnection];
}
#endif
MTBuffer *reqDhBuffer = [[MTBuffer alloc] init];
[reqDhBuffer appendInt32:(int32_t)0xd712e4be];
[reqDhBuffer appendBytes:_nonce.bytes length:_nonce.length];

View File

@ -657,6 +657,15 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
}];
}
- (void)simulateDisconnection {
[[MTProto managerQueue] dispatchOnQueue:^
{
if (_transport != nil) {
[_transport simulateDisconnection];
}
}];
}
- (bool)canAskForTransactions
{
return (_mtState & (MTProtoStateAwaitingDatacenterScheme | MTProtoStateAwaitingDatacenterAuthorization | MTProtoStateAwaitingDatacenterAuthToken | MTProtoStateAwaitingTimeFixAndSalts | MTProtoStateStopped)) == 0;
@ -770,7 +779,10 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
return;
}
if (_useUnauthorizedMode) {
#if DEBUG
#else
return;
#endif
}
if (hasConnectionProblems) {

View File

@ -804,4 +804,18 @@ static const NSTimeInterval MTTcpTransportSleepWatchdogTimeout = 60.0;
}];
}
- (void)simulateDisconnection {
MTTcpTransportContext *transportContext = _transportContext;
[[MTTcpTransport tcpTransportQueue] dispatchOnQueue:^ {
if (transportContext.connection.scheme != nil) {
MTTransportScheme *scheme = transportContext.connection.scheme;
__weak MTTcpTransport *weakSelf = self;
dispatch_async([MTTcpTransport tcpTransportQueue].nativeQueue, ^{
__strong MTTcpTransport *strongSelf = weakSelf;
[strongSelf connectionWatchdogTimeout:scheme];
});
}
}];
}
@end

View File

@ -92,4 +92,7 @@
- (void)updateSchemes:(NSArray<MTTransportScheme *> * _Nonnull)schemes {
}
- (void)simulateDisconnection {
}
@end

View File

@ -1475,6 +1475,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)]
}
@ -1528,6 +1529,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)], isFinalResult))
}

View File

@ -397,10 +397,14 @@ final class StickerPackEmojisItemNode: GridItemNode {
if let current = strongSelf.visibleItemPlaceholderViews[itemId] {
placeholderView = current
} else {
var placeholderContent: EmojiPagerContentComponent.View.ItemPlaceholderView.Content?
if let immediateThumbnailData = item.file.immediateThumbnailData {
placeholderContent = .thumbnail(immediateThumbnailData)
}
placeholderView = EmojiPagerContentComponent.View.ItemPlaceholderView(
context: context,
dimensions: item.file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0),
immediateThumbnailData: item.file.immediateThumbnailData,
content: placeholderContent,
shimmerView: nil,//strongSelf.shimmerHostView,
color: theme.chat.inputPanel.primaryTextColor.withMultipliedAlpha(0.08),
size: itemNativeFitSize

View File

@ -233,11 +233,11 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
let imageSize = dimensitons.cgSize.aspectFitted(boundingSize)
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))()
var imageFrame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: textSize.height + textSpacing - topOffset), size: imageSize)
var imageFrame = CGRect(origin: CGPoint(x: floor((boundingSize.width - imageSize.width) / 2.0), y: textSize.height + textSpacing - topOffset), size: imageSize)
var centerOffset: CGFloat = 0.0
if self.item.file.isPremiumSticker {
let originalImageFrame = imageFrame
imageFrame.origin.x = size.width - imageFrame.width - 18.0
imageFrame.origin.x = min(imageFrame.minX + imageFrame.width * 0.1, size.width - imageFrame.width - 18.0)
centerOffset = imageFrame.minX - originalImageFrame.minX
}
self.imageNode.frame = imageFrame
@ -254,9 +254,9 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
self.textNode.frame = CGRect(origin: CGPoint(x: floor((imageFrame.size.width - textSize.width) / 2.0) - centerOffset, y: -textSize.height - textSpacing), size: textSize)
if self.item.file.isCustomEmoji {
return CGSize(width: size.width, height: imageFrame.height)
return CGSize(width: boundingSize.width, height: imageFrame.height)
} else {
return CGSize(width: size.width, height: imageFrame.height + textSize.height + textSpacing)
return CGSize(width: boundingSize.width, height: imageFrame.height + textSize.height + textSpacing)
}
} else {
return CGSize(width: size.width, height: 10.0)

View File

@ -476,6 +476,9 @@ func _internal_searchEmoji(account: Account, query: [String], scope: SearchStick
if let currentCached = cached, currentTime > currentCached.timestamp + searchStickersConfiguration.cacheTimeout {
cached = nil
}
#if DEBUG
cached = nil
#endif
return (result, cached, isPremium, searchStickersConfiguration)
}

View File

@ -189,32 +189,6 @@ public extension TelegramEngine {
|> map { items, isFinalResult -> (items: [TelegramMediaFile], isFinalResult: Bool) in
return (items.map(\.file), isFinalResult)
}
/*return self.account.network.request(Api.functions.messages.searchCustomEmoji(emoticon: emojiString.joined(separator: ""), hash: 0))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.EmojiList?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<[TelegramMediaFile], NoError> in
guard let result = result else {
return .single([])
}
switch result {
case let .emojiList(_, documentIds):
return self.resolveInlineStickers(fileIds: documentIds)
|> map { result -> [TelegramMediaFile] in
var files: [TelegramMediaFile] = []
for id in documentIds {
if let file = result[id] {
files.append(file)
}
}
return files
}
default:
return .single([])
}
}*/
}
}
}

View File

@ -435,6 +435,7 @@ final class AvatarEditorScreenComponent: Component {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: emojiItems
)
)
@ -454,6 +455,7 @@ final class AvatarEditorScreenComponent: Component {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: stickerItems
)
)
@ -510,6 +512,7 @@ final class AvatarEditorScreenComponent: Component {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)], isFinalResult))
}

View File

@ -1087,6 +1087,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)]
}
@ -1140,6 +1141,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)], isFinalResult))
}
@ -1155,12 +1157,31 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
return
}
if group.items.isEmpty && !result.isFinalResult {
self.emojiSearchStateValue.isSearching = true
//self.emojiSearchStateValue.isSearching = true
self.emojiSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: [
EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
title: nil,
subtitle: nil,
actionButtonTitle: nil,
isFeatured: false,
isPremiumLocked: false,
isEmbedded: false,
hasClear: false,
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: true,
items: []
)
], id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
return
}
self.emojiSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: result.items, id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
version += 1
//DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0, execute: {
self.emojiSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: result.items, id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
version += 1
//})
}))
}
},
@ -1416,6 +1437,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)], files.isFinalResult))
}
@ -1430,7 +1452,25 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
return
}
if group.items.isEmpty && !result.isFinalResult {
strongSelf.stickerSearchStateValue.isSearching = true
//strongSelf.stickerSearchStateValue.isSearching = true
strongSelf.stickerSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: [
EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
title: nil,
subtitle: nil,
actionButtonTitle: nil,
isFeatured: false,
isPremiumLocked: false,
isEmbedded: false,
hasClear: false,
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: true,
items: []
)
], id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
return
}
strongSelf.stickerSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: result.items, id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
@ -1467,7 +1507,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
if let emojiSearchResult = emojiSearchState.result {
var emptySearchResults: EmojiPagerContentComponent.EmptySearchResults?
if !emojiSearchResult.groups.contains(where: { !$0.items.isEmpty }) {
if !emojiSearchResult.groups.contains(where: { !$0.items.isEmpty || $0.fillWithLoadingPlaceholders }) {
emptySearchResults = EmojiPagerContentComponent.EmptySearchResults(
text: presentationData.strings.EmojiSearch_SearchEmojiEmptyResult,
iconFile: nil
@ -1485,7 +1525,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
if let stickerSearchResult = stickerSearchState.result {
var stickerSearchResults: EmojiPagerContentComponent.EmptySearchResults?
if !stickerSearchResult.groups.contains(where: { !$0.items.isEmpty }) {
if !stickerSearchResult.groups.contains(where: { !$0.items.isEmpty || $0.fillWithLoadingPlaceholders }) {
stickerSearchResults = EmojiPagerContentComponent.EmptySearchResults(
text: presentationData.strings.EmojiSearch_SearchStickersEmptyResult,
iconFile: nil

View File

@ -568,6 +568,7 @@ public final class EmojiStatusSelectionController: ViewController {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)]
}
@ -621,6 +622,7 @@ public final class EmojiStatusSelectionController: ViewController {
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)], isFinalResult))
}

View File

@ -2472,6 +2472,7 @@ public final class EmojiPagerContentComponent: Component {
public let collapsedLineCount: Int?
public let displayPremiumBadges: Bool
public let headerItem: EntityKeyboardAnimationData?
public let fillWithLoadingPlaceholders: Bool
public let items: [Item]
public init(
@ -2487,6 +2488,7 @@ public final class EmojiPagerContentComponent: Component {
collapsedLineCount: Int?,
displayPremiumBadges: Bool,
headerItem: EntityKeyboardAnimationData?,
fillWithLoadingPlaceholders: Bool,
items: [Item]
) {
self.supergroupId = supergroupId
@ -2501,6 +2503,7 @@ public final class EmojiPagerContentComponent: Component {
self.collapsedLineCount = collapsedLineCount
self.displayPremiumBadges = displayPremiumBadges
self.headerItem = headerItem
self.fillWithLoadingPlaceholders = fillWithLoadingPlaceholders
self.items = items
}
@ -2544,6 +2547,9 @@ public final class EmojiPagerContentComponent: Component {
if lhs.headerItem != rhs.headerItem {
return false
}
if lhs.fillWithLoadingPlaceholders != rhs.fillWithLoadingPlaceholders {
return false
}
if lhs.items != rhs.items {
return false
}
@ -3035,6 +3041,11 @@ public final class EmojiPagerContentComponent: Component {
}
public final class ItemPlaceholderView: UIView {
public enum Content {
case thumbnail(Data)
case template(UIImage)
}
private let shimmerView: PortalSourceView?
private var placeholderView: PortalView?
private let placeholderMaskLayer: SimpleLayer
@ -3043,7 +3054,7 @@ public final class EmojiPagerContentComponent: Component {
public init(
context: AccountContext,
dimensions: CGSize?,
immediateThumbnailData: Data?,
content: Content?,
shimmerView: PortalSourceView?,
color: UIColor,
size: CGSize
@ -3063,19 +3074,31 @@ public final class EmojiPagerContentComponent: Component {
}
let useDirectContent = self.placeholderView == nil
Queue.concurrentDefaultQueue().async { [weak self] in
if let image = generateStickerPlaceholderImage(data: immediateThumbnailData, size: size, scale: min(2.0, UIScreenScale), imageSize: dimensions ?? CGSize(width: 512.0, height: 512.0), backgroundColor: nil, foregroundColor: useDirectContent ? color : .black) {
Queue.mainQueue().async {
guard let strongSelf = self else {
return
}
if let content {
switch content {
case let .thumbnail(immediateThumbnailData):
Queue.concurrentDefaultQueue().async { [weak self] in
if let image = generateStickerPlaceholderImage(data: immediateThumbnailData, size: size, scale: min(2.0, UIScreenScale), imageSize: dimensions ?? CGSize(width: 512.0, height: 512.0), backgroundColor: nil, foregroundColor: useDirectContent ? color : .black) {
Queue.mainQueue().async {
guard let strongSelf = self else {
return
}
if useDirectContent {
strongSelf.layer.contents = image.cgImage
} else {
strongSelf.placeholderMaskLayer.contents = image.cgImage
if useDirectContent {
strongSelf.layer.contents = image.cgImage
} else {
strongSelf.placeholderMaskLayer.contents = image.cgImage
}
}
}
}
case let .template(templateImage):
if useDirectContent {
self.layer.contents = templateImage.cgImage
self.tintColor = color
} else {
self.placeholderMaskLayer.contents = templateImage.cgImage
}
}
}
}
@ -3590,6 +3613,7 @@ public final class EmojiPagerContentComponent: Component {
private var visibleSearchHeader: EmojiSearchHeaderView?
private var visibleEmptySearchResultsView: EmptySearchResultsView?
private var visibleItemPlaceholderViews: [ItemLayer.Key: ItemPlaceholderView] = [:]
private var visibleFillPlaceholdersViews: [Int: ItemPlaceholderView] = [:]
private var visibleItemSelectionLayers: [ItemLayer.Key: ItemSelectionLayer] = [:]
private var visibleItemLayers: [ItemLayer.Key: ItemLayer] = [:]
private var visibleGroupHeaders: [AnyHashable: GroupHeaderLayer] = [:]
@ -3600,6 +3624,16 @@ public final class EmojiPagerContentComponent: Component {
private var ignoreScrolling: Bool = false
private var keepTopPanelVisibleUntilScrollingInput: Bool = false
private struct FillPlaceholderParams: Equatable {
var size: CGSize
init(size: CGSize) {
self.size = size
}
}
private var fillPlaceholder: (params: FillPlaceholderParams, image: UIImage)?
private var component: EmojiPagerContentComponent?
private weak var state: EmptyComponentState?
private var pagerEnvironment: PagerComponentChildEnvironment?
@ -5243,6 +5277,7 @@ public final class EmojiPagerContentComponent: Component {
var validGroupBorderIds = Set<AnyHashable>()
var validGroupPremiumButtonIds = Set<AnyHashable>()
var validGroupExpandActionButtons = Set<AnyHashable>()
var validFillPlaceholdersIndices = Set<Int>()
let effectiveVisibleBounds = CGRect(origin: self.scrollView.bounds.origin, size: self.effectiveVisibleSize)
let topVisibleDetectionBounds = effectiveVisibleBounds.offsetBy(dx: 0.0, dy: pagerEnvironment.containerInsets.top)
@ -5541,7 +5576,6 @@ public final class EmojiPagerContentComponent: Component {
for index in groupItemRange.lowerBound ..< groupItemRange.upperBound {
let item = itemGroup.items[index]
if assignTopVisibleSubgroupId {
if let subgroupId = item.subgroupId {
topVisibleSubgroupId = AnyHashable(subgroupId)
@ -5600,10 +5634,14 @@ public final class EmojiPagerContentComponent: Component {
if let current = strongSelf.visibleItemPlaceholderViews[itemId] {
placeholderView = current
} else {
var placeholderContent: ItemPlaceholderView.Content?
if let immediateThumbnailData = animationData.immediateThumbnailData {
placeholderContent = .thumbnail(immediateThumbnailData)
}
placeholderView = ItemPlaceholderView(
context: component.context,
dimensions: animationData.dimensions,
immediateThumbnailData: animationData.immediateThumbnailData,
content: placeholderContent,
shimmerView: strongSelf.shimmerHostView,
color: placeholderColor,
size: itemNativeFitSize
@ -5756,6 +5794,61 @@ public final class EmojiPagerContentComponent: Component {
itemLayer.isVisibleForAnimations = keyboardChildEnvironment.isContentInFocus
}
}
if itemGroup.fillWithLoadingPlaceholders {
let placeholderSizeFactor: CGFloat = 0.9
let placeholderColor = keyboardChildEnvironment.theme.chat.inputPanel.primaryTextColor.withMultipliedAlpha(0.1)
let fillPlaceholderImage: UIImage?
let fillPlaceholderParams = FillPlaceholderParams(size: CGSize(width: floor(itemLayout.nativeItemSize * placeholderSizeFactor), height: floor(itemLayout.nativeItemSize * placeholderSizeFactor)))
if let current = self.fillPlaceholder, current.params == fillPlaceholderParams {
fillPlaceholderImage = current.image
} else {
switch component.itemLayoutType {
case .compact:
fillPlaceholderImage = generateFilledCircleImage(diameter: fillPlaceholderParams.size.width, color: .black)
case .detailed:
fillPlaceholderImage = generateFilledRoundedRectImage(size: fillPlaceholderParams.size, cornerRadius: floor(fillPlaceholderParams.size.width * 0.2), color: .black)
}
if let fillPlaceholderImage {
self.fillPlaceholder = (fillPlaceholderParams, fillPlaceholderImage)
}
}
let fillPlaceholderContent: ItemPlaceholderView.Content? = fillPlaceholderImage.flatMap(ItemPlaceholderView.Content.template)
var placeholderIndex = groupItems.groupItems?.lowerBound ?? 0
while true {
var itemFrame = itemLayout.frame(groupIndex: groupItems.groupIndex, itemIndex: placeholderIndex)
if itemFrame.minY >= effectiveVisibleBounds.maxY {
break
}
let visibleItemSize = CGSize(width: floor(itemFrame.width * placeholderSizeFactor), height: floor(itemFrame.height * placeholderSizeFactor))
itemFrame = CGRect(origin: CGPoint(x: floor(itemFrame.midX - visibleItemSize.width * 0.5), y: floor(itemFrame.midY - visibleItemSize.height * 0.5)), size: visibleItemSize)
validFillPlaceholdersIndices.insert(placeholderIndex)
let placeholderView: ItemPlaceholderView
if let current = self.visibleFillPlaceholdersViews[placeholderIndex] {
placeholderView = current
} else {
placeholderView = ItemPlaceholderView(
context: component.context,
dimensions: nil,
content: fillPlaceholderContent,
shimmerView: self.shimmerHostView,
color: placeholderColor,
size: itemFrame.size
)
self.visibleFillPlaceholdersViews[placeholderIndex] = placeholderView
self.placeholdersContainerView.addSubview(placeholderView)
}
placeholderView.frame = itemFrame
placeholderView.update(size: itemFrame.size)
placeholderIndex += 1
}
self.updateShimmerIfNeeded()
}
}
var removedPlaceholerViews = false
@ -5869,6 +5962,26 @@ public final class EmojiPagerContentComponent: Component {
self.visibleItemSelectionLayers.removeValue(forKey: id)
}
var removedFillPlaceholderIndices: [Int] = []
for (index, placeholderView) in self.visibleFillPlaceholdersViews {
if !validFillPlaceholdersIndices.contains(index) {
if !transition.animation.isImmediate {
placeholderView.alpha = 0.0
placeholderView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak placeholderView] _ in
placeholderView?.removeFromSuperview()
})
} else {
placeholderView.removeFromSuperview()
}
removedFillPlaceholderIndices.append(index)
removedPlaceholerViews = true
}
}
for index in removedFillPlaceholderIndices {
self.visibleFillPlaceholdersViews.removeValue(forKey: index)
}
var removedGroupHeaderIds: [AnyHashable] = []
for (id, groupHeaderLayer) in self.visibleGroupHeaders {
if !validGroupHeaderIds.contains(id) {
@ -6679,7 +6792,7 @@ public final class EmojiPagerContentComponent: Component {
var animateContentCrossfade = false
if let previousComponent, previousComponent.itemContentUniqueId != component.itemContentUniqueId, itemTransition.animation.isImmediate {
if previousComponent.itemContentUniqueId?.id != component.itemContentUniqueId?.id {
if !(previousComponent.contentItemGroups.contains(where: { $0.fillWithLoadingPlaceholders }) && component.contentItemGroups.contains(where: { $0.fillWithLoadingPlaceholders })) && previousComponent.itemContentUniqueId?.id != component.itemContentUniqueId?.id {
animateContentCrossfade = true
}
}
@ -6705,6 +6818,15 @@ public final class EmojiPagerContentComponent: Component {
snapshotLayer.animateScale(from: 1.0, to: crossfadeMinScale, duration: 0.2, removeOnCompletion: false)
}
}
for (_, placeholderView) in self.visibleFillPlaceholdersViews {
if let snapshotLayer = placeholderView.layer.snapshotContentTree() {
placeholderView.layer.superlayer?.insertSublayer(snapshotLayer, above: placeholderView.layer)
snapshotLayer.animateAlpha(from: CGFloat(snapshotLayer.opacity), to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotLayer] _ in
snapshotLayer?.removeFromSuperlayer()
})
snapshotLayer.animateScale(from: 1.0, to: crossfadeMinScale, duration: 0.2, removeOnCompletion: false)
}
}
for (_, selectionLayer) in self.visibleItemSelectionLayers {
if let snapshotLayer = selectionLayer.snapshotContentTree() {
selectionLayer.superlayer?.insertSublayer(snapshotLayer, above: selectionLayer)
@ -6758,6 +6880,10 @@ public final class EmojiPagerContentComponent: Component {
placeholderView.layer.animateAlpha(from: 0.0, to: CGFloat(placeholderView.layer.opacity), duration: 0.2)
placeholderView.layer.animateScale(from: crossfadeMinScale, to: 1.0, duration: 0.2)
}
for (_, placeholderView) in self.visibleFillPlaceholdersViews {
placeholderView.layer.animateAlpha(from: 0.0, to: CGFloat(placeholderView.layer.opacity), duration: 0.2)
placeholderView.layer.animateScale(from: crossfadeMinScale, to: 1.0, duration: 0.2)
}
for (_, selectionLayer) in self.visibleItemSelectionLayers {
selectionLayer.animateAlpha(from: 0.0, to: CGFloat(selectionLayer.opacity), duration: 0.2)
}
@ -7718,6 +7844,7 @@ public final class EmojiPagerContentComponent: Component {
collapsedLineCount: group.collapsedLineCount,
displayPremiumBadges: false,
headerItem: headerItem,
fillWithLoadingPlaceholders: false,
items: group.items
)
}
@ -8244,6 +8371,7 @@ public final class EmojiPagerContentComponent: Component {
collapsedLineCount: nil,
displayPremiumBadges: group.displayPremiumBadges,
headerItem: group.headerItem,
fillWithLoadingPlaceholders: false,
items: group.items
)
}

View File

@ -123,6 +123,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
collapsedLineCount: 3,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: groupItems
))
}
@ -286,6 +287,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)]
}
@ -339,6 +341,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)], isFinalResult))
}

View File

@ -215,10 +215,14 @@ final class EntityKeyboardAnimationTopPanelComponent: Component {
private func updateDisplayPlaceholder(displayPlaceholder: Bool, duration: Double) {
if displayPlaceholder {
if self.placeholderView == nil, let component = self.component {
var placeholderContent: EmojiPagerContentComponent.View.ItemPlaceholderView.Content?
if let immediateThumbnailData = component.item.immediateThumbnailData {
placeholderContent = .thumbnail(immediateThumbnailData)
}
let placeholderView = EmojiPagerContentComponent.View.ItemPlaceholderView(
context: component.context,
dimensions: component.item.dimensions,
immediateThumbnailData: component.item.immediateThumbnailData,
content: placeholderContent,
shimmerView: nil,
color: component.theme.chat.inputPanel.primaryTextColor.withMultipliedAlpha(0.08),
size: CGSize(width: 28.0, height: 28.0)

View File

@ -913,9 +913,9 @@ final class DataUsageScreenComponent: Component {
component: AnyComponent(SegmentControlComponent(
theme: environment.theme,
items: [
SegmentControlComponent.Item(id: AnyHashable(SelectedStats.all), title: "All"),
SegmentControlComponent.Item(id: AnyHashable(SelectedStats.mobile), title: "Mobile"),
SegmentControlComponent.Item(id: AnyHashable(SelectedStats.wifi), title: "WiFi")
SegmentControlComponent.Item(id: AnyHashable(SelectedStats.all), title: environment.strings.DataUsage_TopSectionAll),
SegmentControlComponent.Item(id: AnyHashable(SelectedStats.mobile), title: environment.strings.DataUsage_TopSectionMobile),
SegmentControlComponent.Item(id: AnyHashable(SelectedStats.wifi), title: environment.strings.DataUsage_TopSectionWifi)
],
selectedId: "total",
action: { [weak self] id in

View File

@ -2479,7 +2479,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
textView.inputView = updatedInputView
if textView.isFirstResponder {
if self.chatPresentationInterfaceStateRequiresInputFocus(chatPresentationInterfaceState) {
waitForKeyboardLayout = true
if let validLayout = self.validLayout, validLayout.0.inputHeight != nil {
waitForKeyboardLayout = true
}
}
textView.reloadInputViews()
}