mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
0cfbafa6c1
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
@interface TGBridgeUserCache : NSObject
|
@interface TGBridgeUserCache : NSObject
|
||||||
|
|
||||||
- (TGBridgeUser *)userWithId:(int32_t)userId;
|
- (TGBridgeUser *)userWithId:(int64_t)userId;
|
||||||
- (NSDictionary *)usersWithIndexSet:(NSIndexSet *)indexSet;
|
- (NSDictionary *)usersWithIds:(NSArray<NSNumber *> *)indexSet;
|
||||||
- (void)storeUser:(TGBridgeUser *)user;
|
- (void)storeUser:(TGBridgeUser *)user;
|
||||||
- (void)storeUsers:(NSArray *)users;
|
- (void)storeUsers:(NSArray *)users;
|
||||||
- (NSArray *)applyUserChanges:(NSArray *)userChanges;
|
- (NSArray *)applyUserChanges:(NSArray *)userChanges;
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (TGBridgeUser *)userWithId:(int32_t)userId
|
- (TGBridgeUser *)userWithId:(int64_t)userId
|
||||||
{
|
{
|
||||||
__block TGBridgeUser *user = nil;
|
__block TGBridgeUser *user = nil;
|
||||||
|
|
||||||
@ -44,26 +44,28 @@
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)usersWithIndexSet:(NSIndexSet *)indexSet
|
- (NSDictionary *)usersWithIds:(NSArray<NSNumber *> *)indexSet
|
||||||
{
|
{
|
||||||
NSMutableDictionary *users = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *users = [[NSMutableDictionary alloc] init];
|
||||||
NSMutableIndexSet *neededUsers = [indexSet mutableCopy];
|
NSMutableSet<NSNumber *> *neededUsers = [indexSet mutableCopy];
|
||||||
|
|
||||||
NSMutableIndexSet *foundUsers = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *foundUsers = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
OSSpinLockLock(&_userByUidLock);
|
OSSpinLockLock(&_userByUidLock);
|
||||||
[neededUsers enumerateIndexesUsingBlock:^(NSUInteger index, BOOL * _Nonnull stop)
|
for (NSNumber *nId in neededUsers) {
|
||||||
{
|
int64_t index = [nId longLongValue];
|
||||||
TGBridgeUser *user = _userByUid[@(index)];
|
TGBridgeUser *user = _userByUid[@(index)];
|
||||||
if (user != nil)
|
if (user != nil)
|
||||||
{
|
{
|
||||||
users[@(index)] = user;
|
users[@(index)] = user;
|
||||||
[foundUsers addIndex:index];
|
[foundUsers addObject:@(index)];
|
||||||
}
|
}
|
||||||
}];
|
}
|
||||||
OSSpinLockUnlock(&_userByUidLock);
|
OSSpinLockUnlock(&_userByUidLock);
|
||||||
|
|
||||||
[neededUsers removeIndexes:foundUsers];
|
for (NSNumber *nId in foundUsers) {
|
||||||
|
[neededUsers removeObject:nId];
|
||||||
|
}
|
||||||
|
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ NSString *const TGNeoChatRowIdentifier = @"TGNeoChatRow";
|
|||||||
_currentChat = chat;
|
_currentChat = chat;
|
||||||
|
|
||||||
NSDictionary *oldUsers = _currentUsers;
|
NSDictionary *oldUsers = _currentUsers;
|
||||||
_currentUsers = [[TGBridgeUserCache instance] usersWithIndexSet:[chat involvedUserIds]];
|
_currentUsers = [[TGBridgeUserCache instance] usersWithIds:[chat involvedUserIds]];
|
||||||
|
|
||||||
bool shouldUpdate = [self shouldUpdateContentFrom:oldChat oldUsers:oldUsers to:_currentChat newUsers:_currentUsers];
|
bool shouldUpdate = [self shouldUpdateContentFrom:oldChat oldUsers:oldUsers to:_currentChat newUsers:_currentUsers];
|
||||||
if (shouldUpdate)
|
if (shouldUpdate)
|
||||||
|
@ -703,9 +703,10 @@ const NSInteger TGNeoConversationControllerInitialRenderCount = 4;
|
|||||||
NSMutableArray *botInfoSignals = [[NSMutableArray alloc] init];
|
NSMutableArray *botInfoSignals = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *botUsers = [[NSMutableArray alloc] init];
|
NSMutableArray *botUsers = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *initialStates = [[NSMutableArray alloc] init];
|
NSMutableArray *initialStates = [[NSMutableArray alloc] init];
|
||||||
[_chatModel.participantsUserIds enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop)
|
|
||||||
{
|
for (NSNumber *nId in _chatModel.participantsUserIds) {
|
||||||
TGBridgeUser *user = [[TGBridgeUserCache instance] userWithId:(int32_t)idx];
|
int64_t idx = [nId longLongValue];
|
||||||
|
TGBridgeUser *user = [[TGBridgeUserCache instance] userWithId:idx];
|
||||||
if ([user isBot])
|
if ([user isBot])
|
||||||
{
|
{
|
||||||
[botUsers addObject:user];
|
[botUsers addObject:user];
|
||||||
@ -718,7 +719,7 @@ const NSInteger TGNeoConversationControllerInitialRenderCount = 4;
|
|||||||
return botInfo.commandList;
|
return botInfo.commandList;
|
||||||
}]];
|
}]];
|
||||||
}
|
}
|
||||||
}];
|
}
|
||||||
|
|
||||||
return [[SSignal combineSignals:botInfoSignals withInitialStates:initialStates] map:^id(NSArray *commandLists)
|
return [[SSignal combineSignals:botInfoSignals withInitialStates:initialStates] map:^id(NSArray *commandLists)
|
||||||
{
|
{
|
||||||
@ -767,15 +768,14 @@ const NSInteger TGNeoConversationControllerInitialRenderCount = 4;
|
|||||||
|
|
||||||
if ([self peerIsAnyGroup])
|
if ([self peerIsAnyGroup])
|
||||||
{
|
{
|
||||||
[_chatModel.participantsUserIds enumerateIndexesUsingBlock:^(NSUInteger userId, BOOL * _Nonnull stop)
|
for (NSNumber *nId in _chatModel.participantsUserIds) {
|
||||||
{
|
int64_t userId = [nId longLongValue];
|
||||||
TGBridgeUser *user = [[TGBridgeUserCache instance] userWithId:(int32_t)userId];
|
TGBridgeUser *user = [[TGBridgeUserCache instance] userWithId:userId];
|
||||||
if ([user isBot])
|
if ([user isBot]) {
|
||||||
{
|
|
||||||
_hasBots = true;
|
_hasBots = true;
|
||||||
*stop = true;
|
break;
|
||||||
}
|
}
|
||||||
}];
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -144,7 +144,7 @@ NSString *const TGNeoMessageAudioAnimatedIcon = @"animatedIcon";
|
|||||||
}
|
}
|
||||||
|
|
||||||
NSMutableDictionary *users = [NSMutableDictionary dictionaryWithDictionary:additionalPeers];
|
NSMutableDictionary *users = [NSMutableDictionary dictionaryWithDictionary:additionalPeers];
|
||||||
[users addEntriesFromDictionary:[[TGBridgeUserCache instance] usersWithIndexSet:[message involvedUserIds]]];
|
[users addEntriesFromDictionary:[[TGBridgeUserCache instance] usersWithIds:[message involvedUserIds]]];
|
||||||
|
|
||||||
return [[viewModelClass alloc] initWithMessage:message type:type users:users context:context];
|
return [[viewModelClass alloc] initWithMessage:message type:type users:users context:context];
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@
|
|||||||
@property (nonatomic) int32_t participantsCount;
|
@property (nonatomic) int32_t participantsCount;
|
||||||
@property (nonatomic, strong) NSArray *participants;
|
@property (nonatomic, strong) NSArray *participants;
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds;
|
- (NSArray<NSNumber *> *)involvedUserIds;
|
||||||
- (NSIndexSet *)participantsUserIds;
|
- (NSArray<NSNumber *> *)participantsUserIds;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -94,13 +94,13 @@ NSString *const TGBridgeChatsArrayKey = @"chats";
|
|||||||
[aCoder encodeObject:self.participants forKey:TGBridgeChatGroupParticipantsKey];
|
[aCoder encodeObject:self.participants forKey:TGBridgeChatGroupParticipantsKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds
|
- (NSArray<NSNumber *> *)involvedUserIds
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *userIds = [[NSMutableSet alloc] init];
|
||||||
if (!self.isGroup && !self.isChannel && self.identifier != 0)
|
if (!self.isGroup && !self.isChannel && self.identifier != 0)
|
||||||
[userIds addIndex:(int32_t)self.identifier];
|
[userIds addObject:[NSNumber numberWithLongLong:self.identifier]];
|
||||||
if ((!self.isChannel || self.isChannelGroup) && self.fromUid != self.identifier && self.fromUid != 0 && !TGPeerIdIsChannel(self.fromUid) && self.fromUid > 0)
|
if ((!self.isChannel || self.isChannelGroup) && self.fromUid != self.identifier && self.fromUid != 0 && !TGPeerIdIsChannel(self.fromUid) && self.fromUid > 0)
|
||||||
[userIds addIndex:(int32_t)self.fromUid];
|
[userIds addObject:[NSNumber numberWithLongLong:self.fromUid]];
|
||||||
|
|
||||||
for (TGBridgeMediaAttachment *attachment in self.media)
|
for (TGBridgeMediaAttachment *attachment in self.media)
|
||||||
{
|
{
|
||||||
@ -108,21 +108,30 @@ NSString *const TGBridgeChatsArrayKey = @"chats";
|
|||||||
{
|
{
|
||||||
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
||||||
if (actionAttachment.actionData[@"uid"] != nil)
|
if (actionAttachment.actionData[@"uid"] != nil)
|
||||||
[userIds addIndex:[actionAttachment.actionData[@"uid"] integerValue]];
|
[userIds addObject:[NSNumber numberWithLongLong:[actionAttachment.actionData[@"uid"] longLongValue]]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userIds;
|
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||||
|
for (NSNumber *object in userIds) {
|
||||||
|
[result addObject:object];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)participantsUserIds
|
- (NSArray<NSNumber *> *)participantsUserIds
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *userIds = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
for (NSNumber *uid in self.participants)
|
for (NSNumber *uid in self.participants) {
|
||||||
[userIds addIndex:uid.unsignedIntegerValue];
|
[userIds addObject:[NSNumber numberWithLongLong:uid.longLongValue]];
|
||||||
|
}
|
||||||
|
|
||||||
return userIds;
|
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||||
|
for (NSNumber *object in userIds) {
|
||||||
|
[result addObject:object];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isEqual:(id)object
|
- (BOOL)isEqual:(id)object
|
||||||
|
@ -50,7 +50,7 @@ typedef NS_ENUM(NSUInteger, TGBridgeMessageDeliveryState) {
|
|||||||
@property (nonatomic, strong) NSArray *media;
|
@property (nonatomic, strong) NSArray *media;
|
||||||
@property (nonatomic) bool forceReply;
|
@property (nonatomic) bool forceReply;
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds;
|
- (NSArray<NSNumber *> *)involvedUserIds;
|
||||||
- (NSArray *)textCheckingResults;
|
- (NSArray *)textCheckingResults;
|
||||||
|
|
||||||
+ (instancetype)temporaryNewMessageForText:(NSString *)text userId:(int32_t)userId;
|
+ (instancetype)temporaryNewMessageForText:(NSString *)text userId:(int32_t)userId;
|
||||||
|
@ -60,11 +60,11 @@ NSString *const TGBridgeMessagesArrayKey = @"messages";
|
|||||||
[aCoder encodeBool:self.forceReply forKey:TGBridgeMessageForceReplyKey];
|
[aCoder encodeBool:self.forceReply forKey:TGBridgeMessageForceReplyKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds
|
- (NSArray<NSNumber *> *)involvedUserIds
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *userIds = [[NSMutableSet alloc] init];
|
||||||
if (!TGPeerIdIsChannel(self.fromUid))
|
if (!TGPeerIdIsChannel(self.fromUid))
|
||||||
[userIds addIndex:(int32_t)self.fromUid];
|
[userIds addObject:[NSNumber numberWithLongLong:self.fromUid]];
|
||||||
|
|
||||||
for (TGBridgeMediaAttachment *attachment in self.media)
|
for (TGBridgeMediaAttachment *attachment in self.media)
|
||||||
{
|
{
|
||||||
@ -72,29 +72,33 @@ NSString *const TGBridgeMessagesArrayKey = @"messages";
|
|||||||
{
|
{
|
||||||
TGBridgeContactMediaAttachment *contactAttachment = (TGBridgeContactMediaAttachment *)attachment;
|
TGBridgeContactMediaAttachment *contactAttachment = (TGBridgeContactMediaAttachment *)attachment;
|
||||||
if (contactAttachment.uid != 0)
|
if (contactAttachment.uid != 0)
|
||||||
[userIds addIndex:contactAttachment.uid];
|
[userIds addObject:[NSNumber numberWithLongLong:contactAttachment.uid]];
|
||||||
}
|
}
|
||||||
else if ([attachment isKindOfClass:[TGBridgeForwardedMessageMediaAttachment class]])
|
else if ([attachment isKindOfClass:[TGBridgeForwardedMessageMediaAttachment class]])
|
||||||
{
|
{
|
||||||
TGBridgeForwardedMessageMediaAttachment *forwardAttachment = (TGBridgeForwardedMessageMediaAttachment *)attachment;
|
TGBridgeForwardedMessageMediaAttachment *forwardAttachment = (TGBridgeForwardedMessageMediaAttachment *)attachment;
|
||||||
if (forwardAttachment.peerId != 0 && !TGPeerIdIsChannel(forwardAttachment.peerId))
|
if (forwardAttachment.peerId != 0 && !TGPeerIdIsChannel(forwardAttachment.peerId))
|
||||||
[userIds addIndex:(int32_t)forwardAttachment.peerId];
|
[userIds addObject:[NSNumber numberWithLongLong:forwardAttachment.peerId]];
|
||||||
}
|
}
|
||||||
else if ([attachment isKindOfClass:[TGBridgeReplyMessageMediaAttachment class]])
|
else if ([attachment isKindOfClass:[TGBridgeReplyMessageMediaAttachment class]])
|
||||||
{
|
{
|
||||||
TGBridgeReplyMessageMediaAttachment *replyAttachment = (TGBridgeReplyMessageMediaAttachment *)attachment;
|
TGBridgeReplyMessageMediaAttachment *replyAttachment = (TGBridgeReplyMessageMediaAttachment *)attachment;
|
||||||
if (replyAttachment.message != nil && !TGPeerIdIsChannel(replyAttachment.message.fromUid))
|
if (replyAttachment.message != nil && !TGPeerIdIsChannel(replyAttachment.message.fromUid))
|
||||||
[userIds addIndex:(int32_t)replyAttachment.message.fromUid];
|
[userIds addObject:[NSNumber numberWithLongLong:replyAttachment.message.fromUid]];
|
||||||
}
|
}
|
||||||
else if ([attachment isKindOfClass:[TGBridgeActionMediaAttachment class]])
|
else if ([attachment isKindOfClass:[TGBridgeActionMediaAttachment class]])
|
||||||
{
|
{
|
||||||
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
||||||
if (actionAttachment.actionData[@"uid"] != nil)
|
if (actionAttachment.actionData[@"uid"] != nil)
|
||||||
[userIds addIndex:(int32_t)[actionAttachment.actionData[@"uid"] intValue]];
|
[userIds addObject:[NSNumber numberWithLongLong:[actionAttachment.actionData[@"uid"] intValue]]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userIds;
|
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||||
|
for (NSNumber *object in userIds) {
|
||||||
|
[result addObject:object];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)textCheckingResults
|
- (NSArray *)textCheckingResults
|
||||||
|
@ -293,10 +293,11 @@ public final class NavigateToChatControllerParams {
|
|||||||
public let options: NavigationAnimationOptions
|
public let options: NavigationAnimationOptions
|
||||||
public let parentGroupId: PeerGroupId?
|
public let parentGroupId: PeerGroupId?
|
||||||
public let chatListFilter: Int32?
|
public let chatListFilter: Int32?
|
||||||
|
public let chatNavigationStack: [PeerId]
|
||||||
public let changeColors: Bool
|
public let changeColors: Bool
|
||||||
public let completion: (ChatController) -> Void
|
public let completion: (ChatController) -> Void
|
||||||
|
|
||||||
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, changeColors: Bool = false, completion: @escaping (ChatController) -> Void = { _ in }) {
|
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [PeerId] = [], changeColors: Bool = false, completion: @escaping (ChatController) -> Void = { _ in }) {
|
||||||
self.navigationController = navigationController
|
self.navigationController = navigationController
|
||||||
self.chatController = chatController
|
self.chatController = chatController
|
||||||
self.chatLocationContextHolder = chatLocationContextHolder
|
self.chatLocationContextHolder = chatLocationContextHolder
|
||||||
@ -318,6 +319,7 @@ public final class NavigateToChatControllerParams {
|
|||||||
self.options = options
|
self.options = options
|
||||||
self.parentGroupId = parentGroupId
|
self.parentGroupId = parentGroupId
|
||||||
self.chatListFilter = chatListFilter
|
self.chatListFilter = chatListFilter
|
||||||
|
self.chatNavigationStack = chatNavigationStack
|
||||||
self.changeColors = changeColors
|
self.changeColors = changeColors
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
}
|
}
|
||||||
|
@ -540,7 +540,17 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if self.controlsHistoryPreload {
|
if self.controlsHistoryPreload {
|
||||||
self.context.account.viewTracker.chatListPreloadItems.set(itemNode.listNode.preloadItems.get())
|
self.context.account.viewTracker.chatListPreloadItems.set(combineLatest(queue: .mainQueue(),
|
||||||
|
context.sharedContext.hasOngoingCall.get(),
|
||||||
|
itemNode.listNode.preloadItems.get()
|
||||||
|
)
|
||||||
|
|> map { hasOngoingCall, preloadItems -> [ChatHistoryPreloadItem] in
|
||||||
|
if hasOngoingCall {
|
||||||
|
return []
|
||||||
|
} else {
|
||||||
|
return preloadItems
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,13 +179,13 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceNode {
|
|||||||
|
|
||||||
if previousComponent != component {
|
if previousComponent != component {
|
||||||
componentAlpha = animationFraction
|
componentAlpha = animationFraction
|
||||||
componentVerticalOffset = (1.0 - animationFraction) * 8.0
|
componentVerticalOffset = -(1.0 - animationFraction) * 8.0
|
||||||
if previousComponent.string < component.string {
|
if previousComponent.string < component.string {
|
||||||
componentVerticalOffset = -componentVerticalOffset
|
componentVerticalOffset = -componentVerticalOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
let previousComponentAlpha = 1.0 - componentAlpha
|
let previousComponentAlpha = 1.0 - componentAlpha
|
||||||
var previousComponentVerticalOffset = -animationFraction * 8.0
|
var previousComponentVerticalOffset = animationFraction * 8.0
|
||||||
if previousComponent.string < component.string {
|
if previousComponent.string < component.string {
|
||||||
previousComponentVerticalOffset = -previousComponentVerticalOffset
|
previousComponentVerticalOffset = -previousComponentVerticalOffset
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
|
|
||||||
public final class ContextReferenceContentNode: ASDisplayNode {
|
open class ContextReferenceContentNode: ASDisplayNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class ContextExtractedContentContainingNode: ASDisplayNode {
|
public final class ContextExtractedContentContainingNode: ASDisplayNode {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
|
|
||||||
open class ContextControllerSourceNode: ASDisplayNode {
|
open class ContextControllerSourceNode: ContextReferenceContentNode {
|
||||||
public private(set) var contextGesture: ContextGesture?
|
public private(set) var contextGesture: ContextGesture?
|
||||||
|
|
||||||
public var isGestureEnabled: Bool = true {
|
public var isGestureEnabled: Bool = true {
|
||||||
|
@ -1575,7 +1575,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func async(_ f: @escaping () -> Void) {
|
private func async(_ f: @escaping () -> Void) {
|
||||||
DispatchQueue.main.async(execute: f)
|
DispatchQueue.global(qos: .userInteractive).async(execute: f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func nodeForItem(synchronous: Bool, synchronousLoads: Bool, item: ListViewItem, previousNode: QueueLocalObject<ListViewItemNode>?, index: Int, previousItem: ListViewItem?, nextItem: ListViewItem?, params: ListViewItemLayoutParams, updateAnimationIsAnimated: Bool, updateAnimationIsCrossfade: Bool, completion: @escaping (QueueLocalObject<ListViewItemNode>, ListViewItemNodeLayout, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
private func nodeForItem(synchronous: Bool, synchronousLoads: Bool, item: ListViewItem, previousNode: QueueLocalObject<ListViewItemNode>?, index: Int, previousItem: ListViewItem?, nextItem: ListViewItem?, params: ListViewItemLayoutParams, updateAnimationIsAnimated: Bool, updateAnimationIsCrossfade: Bool, completion: @escaping (QueueLocalObject<ListViewItemNode>, ListViewItemNodeLayout, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||||
|
@ -325,7 +325,7 @@ private final class NavigationButtonItemNode: ImmediateTextNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final class NavigationButtonNode: ASDisplayNode {
|
public final class NavigationButtonNode: ContextControllerSourceNode {
|
||||||
private var nodes: [NavigationButtonItemNode] = []
|
private var nodes: [NavigationButtonItemNode] = []
|
||||||
|
|
||||||
public var singleCustomNode: ASDisplayNode? {
|
public var singleCustomNode: ASDisplayNode? {
|
||||||
@ -379,6 +379,7 @@ public final class NavigationButtonNode: ASDisplayNode {
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.isAccessibilityElement = false
|
self.isAccessibilityElement = false
|
||||||
|
self.isGestureEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var manualText: String {
|
var manualText: String {
|
||||||
|
@ -14,6 +14,7 @@ swift_library(
|
|||||||
"//submodules/TelegramCore:TelegramCore",
|
"//submodules/TelegramCore:TelegramCore",
|
||||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
"//submodules/Display:Display",
|
"//submodules/Display:Display",
|
||||||
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||||
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
|
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
|
||||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||||
|
@ -7,6 +7,7 @@ import TelegramPresentationData
|
|||||||
import AccountContext
|
import AccountContext
|
||||||
import TelegramAnimatedStickerNode
|
import TelegramAnimatedStickerNode
|
||||||
import ReactionButtonListComponent
|
import ReactionButtonListComponent
|
||||||
|
import SwiftSignalKit
|
||||||
|
|
||||||
public final class ReactionContextItem {
|
public final class ReactionContextItem {
|
||||||
public struct Reaction: Equatable {
|
public struct Reaction: Equatable {
|
||||||
@ -60,7 +61,8 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
private let previewingItemContainer: ASDisplayNode
|
private let previewingItemContainer: ASDisplayNode
|
||||||
private var visibleItemNodes: [Int: ReactionNode] = [:]
|
private var visibleItemNodes: [Int: ReactionNode] = [:]
|
||||||
|
|
||||||
private weak var currentLongPressItemNode: ReactionNode?
|
private var longPressRecognizer: UILongPressGestureRecognizer?
|
||||||
|
private var longPressTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
private var highlightedReaction: ReactionContextItem.Reaction?
|
private var highlightedReaction: ReactionContextItem.Reaction?
|
||||||
private var didTriggerExpandedReaction: Bool = false
|
private var didTriggerExpandedReaction: Bool = false
|
||||||
@ -144,9 +146,10 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
||||||
|
|
||||||
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressGesture(_:)))
|
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressGesture(_:)))
|
||||||
longPressGesture.minimumPressDuration = 0.2
|
longPressRecognizer.minimumPressDuration = 0.2
|
||||||
self.view.addGestureRecognizer(longPressGesture)
|
self.longPressRecognizer = longPressRecognizer
|
||||||
|
self.view.addGestureRecognizer(longPressRecognizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateLayout(size: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, transition: ContainedViewLayoutTransition) {
|
public func updateLayout(size: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, transition: ContainedViewLayoutTransition) {
|
||||||
@ -485,6 +488,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 0.9, removeOnCompletion: false)
|
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 0.9, removeOnCompletion: false)
|
||||||
itemNode.layer.animatePosition(from: itemNode.layer.position, to: targetPosition, duration: duration, removeOnCompletion: false)
|
itemNode.layer.animatePosition(from: itemNode.layer.position, to: targetPosition, duration: duration, removeOnCompletion: false)
|
||||||
|
targetSnapshotView.alpha = 1.0
|
||||||
targetSnapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration * 0.8)
|
targetSnapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration * 0.8)
|
||||||
targetSnapshotView.layer.animatePosition(from: sourceFrame.center, to: targetPosition, duration: duration, removeOnCompletion: false)
|
targetSnapshotView.layer.animatePosition(from: sourceFrame.center, to: targetPosition, duration: duration, removeOnCompletion: false)
|
||||||
targetSnapshotView.layer.animateScale(from: itemNode.bounds.width / targetSnapshotView.bounds.width, to: 1.0, duration: duration, removeOnCompletion: false, completion: { [weak targetSnapshotView] _ in
|
targetSnapshotView.layer.animateScale(from: itemNode.bounds.width / targetSnapshotView.bounds.width, to: 1.0, duration: duration, removeOnCompletion: false, completion: { [weak targetSnapshotView] _ in
|
||||||
@ -653,7 +657,6 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
theme: strongSelf.context.sharedContext.currentPresentationData.with({ $0 }).theme,
|
theme: strongSelf.context.sharedContext.currentPresentationData.with({ $0 }).theme,
|
||||||
reaction: itemNode.item,
|
reaction: itemNode.item,
|
||||||
targetView: targetView,
|
targetView: targetView,
|
||||||
hideNode: true,
|
|
||||||
completion: { [weak standaloneReactionAnimation] in
|
completion: { [weak standaloneReactionAnimation] in
|
||||||
standaloneReactionAnimation?.removeFromSupernode()
|
standaloneReactionAnimation?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
@ -704,8 +707,18 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if let (size, insets, anchorRect) = self.validLayout {
|
if let (size, insets, anchorRect) = self.validLayout {
|
||||||
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .animated(duration: 2.5, curve: .linear), animateInFromAnchorRect: nil, animateOutToAnchorRect: nil, animateReactionHighlight: true)
|
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .animated(duration: 2.5, curve: .linear), animateInFromAnchorRect: nil, animateOutToAnchorRect: nil, animateReactionHighlight: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.longPressTimer?.invalidate()
|
||||||
|
self.longPressTimer = SwiftSignalKit.Timer(timeout: 2.5, repeat: false, completion: { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.longPressRecognizer?.state = .cancelled
|
||||||
|
}, queue: .mainQueue())
|
||||||
|
self.longPressTimer?.start()
|
||||||
}
|
}
|
||||||
case .ended, .cancelled:
|
case .ended, .cancelled:
|
||||||
|
self.longPressTimer?.invalidate()
|
||||||
self.continuousHaptic = nil
|
self.continuousHaptic = nil
|
||||||
self.didTriggerExpandedReaction = true
|
self.didTriggerExpandedReaction = true
|
||||||
self.highlightGestureFinished(performAction: true)
|
self.highlightGestureFinished(performAction: true)
|
||||||
@ -839,7 +852,6 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
private var isCancelled: Bool = false
|
private var isCancelled: Bool = false
|
||||||
|
|
||||||
private weak var targetView: UIView?
|
private weak var targetView: UIView?
|
||||||
private var hideNode: Bool = false
|
|
||||||
|
|
||||||
override public init() {
|
override public init() {
|
||||||
super.init()
|
super.init()
|
||||||
@ -847,18 +859,17 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
self.isUserInteractionEnabled = false
|
self.isUserInteractionEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, reaction: ReactionContextItem, targetView: UIView, hideNode: Bool, completion: @escaping () -> Void) {
|
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, reaction: ReactionContextItem, targetView: UIView, completion: @escaping () -> Void) {
|
||||||
self.animateReactionSelection(context: context, theme: theme, reaction: reaction, targetView: targetView, currentItemNode: nil, hideNode: hideNode, completion: completion)
|
self.animateReactionSelection(context: context, theme: theme, reaction: reaction, targetView: targetView, currentItemNode: nil, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
func animateReactionSelection(context: AccountContext, theme: PresentationTheme, reaction: ReactionContextItem, targetView: UIView, currentItemNode: ReactionNode?, hideNode: Bool, completion: @escaping () -> Void) {
|
func animateReactionSelection(context: AccountContext, theme: PresentationTheme, reaction: ReactionContextItem, targetView: UIView, currentItemNode: ReactionNode?, completion: @escaping () -> Void) {
|
||||||
guard let sourceSnapshotView = targetView.snapshotContentTree() else {
|
guard let sourceSnapshotView = targetView.snapshotContentTree() else {
|
||||||
completion()
|
completion()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.targetView = targetView
|
self.targetView = targetView
|
||||||
self.hideNode = hideNode
|
|
||||||
|
|
||||||
let itemNode: ReactionNode
|
let itemNode: ReactionNode
|
||||||
if let currentItemNode = currentItemNode {
|
if let currentItemNode = currentItemNode {
|
||||||
@ -884,9 +895,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
|
|
||||||
targetView.imageView.isHidden = true
|
targetView.imageView.isHidden = true
|
||||||
} else {
|
} else {
|
||||||
if hideNode {
|
targetView.isHidden = true
|
||||||
targetView.isHidden = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,10 +960,8 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
if let targetView = targetView as? ReactionIconView {
|
if let targetView = targetView as? ReactionIconView {
|
||||||
targetView.imageView.isHidden = false
|
targetView.imageView.isHidden = false
|
||||||
} else {
|
} else {
|
||||||
if strongSelf.hideNode {
|
targetView.alpha = 1.0
|
||||||
targetView.alpha = 1.0
|
targetView.isHidden = false
|
||||||
targetView.isHidden = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,63 +988,6 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private func animateFromItemNodeToReaction(itemNode: ReactionNode, targetView: UIView, hideNode: Bool, completion: @escaping () -> Void) {
|
|
||||||
if "".isEmpty {
|
|
||||||
if hideNode {
|
|
||||||
targetView.alpha = 1.0
|
|
||||||
targetView.isHidden = false
|
|
||||||
}
|
|
||||||
completion()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let targetSnapshotView = targetView.snapshotContentTree(unhide: true) else {
|
|
||||||
completion()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let sourceFrame = itemNode.view.convert(itemNode.bounds, to: self.view)
|
|
||||||
let targetFrame = self.view.convert(targetView.convert(targetView.bounds, to: nil), from: nil)
|
|
||||||
|
|
||||||
targetSnapshotView.frame = targetFrame
|
|
||||||
self.view.insertSubview(targetSnapshotView, belowSubview: itemNode.view)
|
|
||||||
|
|
||||||
var completedTarget = false
|
|
||||||
var targetScaleCompleted = false
|
|
||||||
let intermediateCompletion: () -> Void = {
|
|
||||||
if completedTarget && targetScaleCompleted {
|
|
||||||
completion()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let targetPosition = targetFrame.center
|
|
||||||
let duration: Double = 0.16
|
|
||||||
|
|
||||||
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 0.9, removeOnCompletion: false)
|
|
||||||
itemNode.layer.animatePosition(from: itemNode.layer.position, to: targetPosition, duration: duration, removeOnCompletion: false)
|
|
||||||
targetSnapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration * 0.8)
|
|
||||||
targetSnapshotView.layer.animatePosition(from: sourceFrame.center, to: targetPosition, duration: duration, removeOnCompletion: false)
|
|
||||||
targetSnapshotView.layer.animateScale(from: itemNode.bounds.width / targetSnapshotView.bounds.width, to: 1.0, duration: duration, removeOnCompletion: false, completion: { [weak targetSnapshotView] _ in
|
|
||||||
completedTarget = true
|
|
||||||
intermediateCompletion()
|
|
||||||
|
|
||||||
targetSnapshotView?.isHidden = true
|
|
||||||
|
|
||||||
if hideNode {
|
|
||||||
targetView.alpha = 1.0
|
|
||||||
targetView.isHidden = false
|
|
||||||
targetSnapshotView?.isHidden = true
|
|
||||||
targetScaleCompleted = true
|
|
||||||
intermediateCompletion()
|
|
||||||
} else {
|
|
||||||
targetScaleCompleted = true
|
|
||||||
intermediateCompletion()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
itemNode.layer.animateScale(from: 1.0, to: (targetSnapshotView.bounds.width * 1.0) / itemNode.bounds.width, duration: duration, removeOnCompletion: false)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public func addRelativeContentOffset(_ offset: CGPoint, transition: ContainedViewLayoutTransition) {
|
public func addRelativeContentOffset(_ offset: CGPoint, transition: ContainedViewLayoutTransition) {
|
||||||
self.bounds = self.bounds.offsetBy(dx: 0.0, dy: offset.y)
|
self.bounds = self.bounds.offsetBy(dx: 0.0, dy: offset.y)
|
||||||
transition.animateOffsetAdditive(node: self, offset: -offset.y)
|
transition.animateOffsetAdditive(node: self, offset: -offset.y)
|
||||||
@ -1046,7 +996,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
public func cancel() {
|
public func cancel() {
|
||||||
self.isCancelled = true
|
self.isCancelled = true
|
||||||
|
|
||||||
if let targetView = self.targetView, self.hideNode {
|
if let targetView = self.targetView {
|
||||||
if let targetView = targetView as? ReactionIconView {
|
if let targetView = targetView as? ReactionIconView {
|
||||||
targetView.imageView.isHidden = false
|
targetView.imageView.isHidden = false
|
||||||
} else {
|
} else {
|
||||||
|
@ -171,7 +171,6 @@ class ReactionChatPreviewItemNode: ListViewItemNode {
|
|||||||
largeApplicationAnimation: reaction.effectAnimation
|
largeApplicationAnimation: reaction.effectAnimation
|
||||||
),
|
),
|
||||||
targetView: targetView,
|
targetView: targetView,
|
||||||
hideNode: true,
|
|
||||||
completion: { [weak standaloneReactionAnimation] in
|
completion: { [weak standaloneReactionAnimation] in
|
||||||
standaloneReactionAnimation?.removeFromSupernode()
|
standaloneReactionAnimation?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
|
@ -218,6 +218,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
public weak var parentController: ViewController?
|
public weak var parentController: ViewController?
|
||||||
|
|
||||||
private let currentChatListFilter: Int32?
|
private let currentChatListFilter: Int32?
|
||||||
|
private let chatNavigationStack: [PeerId]
|
||||||
|
|
||||||
public var peekActions: ChatControllerPeekActions = .standard
|
public var peekActions: ChatControllerPeekActions = .standard
|
||||||
private var didSetup3dTouch: Bool = false
|
private var didSetup3dTouch: Bool = false
|
||||||
@ -494,7 +495,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
private var inviteRequestsContext: PeerInvitationImportersContext?
|
private var inviteRequestsContext: PeerInvitationImportersContext?
|
||||||
private var inviteRequestsDisposable = MetaDisposable()
|
private var inviteRequestsDisposable = MetaDisposable()
|
||||||
|
|
||||||
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: Int32? = nil) {
|
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [PeerId] = []) {
|
||||||
let _ = ChatControllerCount.modify { value in
|
let _ = ChatControllerCount.modify { value in
|
||||||
return value + 1
|
return value + 1
|
||||||
}
|
}
|
||||||
@ -506,6 +507,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self.botStart = botStart
|
self.botStart = botStart
|
||||||
self.peekData = peekData
|
self.peekData = peekData
|
||||||
self.currentChatListFilter = chatListFilter
|
self.currentChatListFilter = chatListFilter
|
||||||
|
self.chatNavigationStack = chatNavigationStack
|
||||||
|
|
||||||
var useSharedAnimationPhase = false
|
var useSharedAnimationPhase = false
|
||||||
switch mode {
|
switch mode {
|
||||||
@ -1293,7 +1295,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
largeApplicationAnimation: reaction.effectAnimation
|
largeApplicationAnimation: reaction.effectAnimation
|
||||||
),
|
),
|
||||||
targetView: targetView,
|
targetView: targetView,
|
||||||
hideNode: true,
|
|
||||||
completion: { [weak standaloneReactionAnimation] in
|
completion: { [weak standaloneReactionAnimation] in
|
||||||
standaloneReactionAnimation?.removeFromSupernode()
|
standaloneReactionAnimation?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
@ -8268,12 +8269,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
default:
|
default:
|
||||||
nextFolderId = nil
|
nextFolderId = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var updatedChatNavigationStack = strongSelf.chatNavigationStack
|
||||||
|
updatedChatNavigationStack.removeAll(where: { $0 == peer.id})
|
||||||
|
if case let .peer(peerId) = strongSelf.chatLocation {
|
||||||
|
updatedChatNavigationStack.insert(peerId, at: 0)
|
||||||
|
}
|
||||||
|
|
||||||
//Queue.mainQueue().after(1.0, {
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), animated: false, chatListFilter: nextFolderId, chatNavigationStack: updatedChatNavigationStack, completion: { nextController in
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), animated: false, chatListFilter: nextFolderId, completion: { nextController in
|
(nextController as! ChatControllerImpl).animateFromPreviousController(snapshotState: snapshotState)
|
||||||
(nextController as! ChatControllerImpl).animateFromPreviousController(snapshotState: snapshotState)
|
}))
|
||||||
}))
|
|
||||||
//})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8324,6 +8329,56 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
return state.updatedInputMode({ _ in .text })
|
return state.updatedInputMode({ _ in .text })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.chatNavigationStack.isEmpty {
|
||||||
|
self.chatDisplayNode.navigationBar?.backButtonNode.isGestureEnabled = true
|
||||||
|
self.chatDisplayNode.navigationBar?.backButtonNode.activated = { [weak self] gesture, _ in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
gesture.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let chatNavigationStack = strongSelf.chatNavigationStack
|
||||||
|
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
|
||||||
|
return chatNavigationStack.compactMap(transaction.getPeer)
|
||||||
|
}
|
||||||
|
|> deliverOnMainQueue).start(next: { peers in
|
||||||
|
guard let strongSelf = self, let backButtonNode = strongSelf.chatDisplayNode.navigationBar?.backButtonNode else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let avatarSize = CGSize(width: 28.0, height: 28.0)
|
||||||
|
|
||||||
|
var items: [ContextMenuItem] = []
|
||||||
|
for peer in peers {
|
||||||
|
items.append(.action(ContextMenuActionItem(text: EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), icon: { _ in return nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: EnginePeer(peer), size: avatarSize)), action: { _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let strongSelf = self, let navigationController = strongSelf.effectiveNavigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let snapshotState = strongSelf.chatDisplayNode.prepareSnapshotState(
|
||||||
|
titleViewSnapshotState: strongSelf.chatTitleView?.prepareSnapshotState(),
|
||||||
|
avatarSnapshotState: (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.prepareSnapshotState()
|
||||||
|
)
|
||||||
|
|
||||||
|
let nextFolderId: Int32? = strongSelf.currentChatListFilter
|
||||||
|
|
||||||
|
var updatedChatNavigationStack = strongSelf.chatNavigationStack
|
||||||
|
if let index = updatedChatNavigationStack.firstIndex(of: peer.id) {
|
||||||
|
updatedChatNavigationStack.removeSubrange(0 ..< (index + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), animated: false, chatListFilter: nextFolderId, chatNavigationStack: updatedChatNavigationStack, completion: { nextController in
|
||||||
|
(nextController as! ChatControllerImpl).animateFromPreviousController(snapshotState: snapshotState)
|
||||||
|
}))
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .reference(ChatControllerContextReferenceContentSource(controller: strongSelf, sourceNode: backButtonNode, insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 4.0, right: 0.0))), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
|
||||||
|
strongSelf.presentInGlobalOverlay(contextController)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var returnInputViewFocus = false
|
private var returnInputViewFocus = false
|
||||||
|
@ -2595,7 +2595,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
largeApplicationAnimation: reaction.effectAnimation
|
largeApplicationAnimation: reaction.effectAnimation
|
||||||
),
|
),
|
||||||
targetView: targetView,
|
targetView: targetView,
|
||||||
hideNode: true,
|
|
||||||
completion: { [weak standaloneReactionAnimation] in
|
completion: { [weak standaloneReactionAnimation] in
|
||||||
standaloneReactionAnimation?.removeFromSupernode()
|
standaloneReactionAnimation?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
|
@ -1255,14 +1255,14 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||||||
var hasReadReports = false
|
var hasReadReports = false
|
||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if case .group = channel.info {
|
if case .group = channel.info {
|
||||||
if let cachedData = cachedData as? CachedChannelData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 50 {
|
if canViewStats {
|
||||||
hasReadReports = true
|
hasReadReports = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reactionCount = 0
|
reactionCount = 0
|
||||||
}
|
}
|
||||||
} else if let group = peer as? TelegramGroup {
|
} else if let _ = peer as? TelegramGroup {
|
||||||
if group.participantCount <= 50 {
|
if canViewStats {
|
||||||
hasReadReports = true
|
hasReadReports = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,7 +70,7 @@ private final class StatusReactionNode: ASDisplayNode {
|
|||||||
if self.value != value {
|
if self.value != value {
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
let boundingImageSize = CGSize(width: 17.0, height: 17.0)
|
let boundingImageSize = CGSize(width: 14.0, height: 14.0)
|
||||||
let defaultImageSize = CGSize(width: boundingImageSize.width + floor(boundingImageSize.width * 0.5 * 2.0), height: boundingImageSize.height + floor(boundingImageSize.height * 0.5 * 2.0))
|
let defaultImageSize = CGSize(width: boundingImageSize.width + floor(boundingImageSize.width * 0.5 * 2.0), height: boundingImageSize.height + floor(boundingImageSize.height * 0.5 * 2.0))
|
||||||
let imageSize: CGSize
|
let imageSize: CGSize
|
||||||
if let file = file {
|
if let file = file {
|
||||||
@ -809,29 +809,30 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
item.node.layer.animateScale(from: 0.01, to: 1.0, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
item.node.layer.animateScale(from: 0.01, to: 1.0, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
item.node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
item.node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
let itemValue = item.value
|
|
||||||
let itemNode = item.node
|
|
||||||
item.node.isGestureEnabled = true
|
|
||||||
let canViewReactionList = arguments.canViewReactionList
|
|
||||||
item.node.activateAfterCompletion = !canViewReactionList
|
|
||||||
item.node.activated = { [weak itemNode] gesture, _ in
|
|
||||||
guard let strongSelf = self, canViewReactionList else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let itemNode = itemNode else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let openReactionPreview = strongSelf.openReactionPreview {
|
|
||||||
openReactionPreview(gesture, itemNode.containerNode, itemValue)
|
|
||||||
} else {
|
|
||||||
gesture.cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
animation.animator.updateFrame(layer: item.node.layer, frame: CGRect(origin: reactionButtonPosition, size: item.size), completion: nil)
|
animation.animator.updateFrame(layer: item.node.layer, frame: CGRect(origin: reactionButtonPosition, size: item.size), completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let itemValue = item.value
|
||||||
|
let itemNode = item.node
|
||||||
|
item.node.isGestureEnabled = true
|
||||||
|
let canViewReactionList = arguments.canViewReactionList
|
||||||
|
item.node.activateAfterCompletion = !canViewReactionList
|
||||||
|
item.node.activated = { [weak itemNode] gesture, _ in
|
||||||
|
guard let strongSelf = self, canViewReactionList else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let itemNode = itemNode else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let openReactionPreview = strongSelf.openReactionPreview {
|
||||||
|
openReactionPreview(gesture, itemNode.containerNode, itemValue)
|
||||||
|
} else {
|
||||||
|
gesture.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reactionButtonPosition.x += item.size.width + 6.0
|
reactionButtonPosition.x += item.size.width + 6.0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,7 +1053,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let nodeFrame = CGRect(origin: CGPoint(x: reactionOffset, y: backgroundInsets.top + offset + verticalInset - 2.0), size: CGSize(width: reactionSize, height: reactionSize))
|
let nodeFrame = CGRect(origin: CGPoint(x: reactionOffset, y: backgroundInsets.top + offset + verticalInset), size: CGSize(width: reactionSize, height: reactionSize))
|
||||||
if animateNode {
|
if animateNode {
|
||||||
animation.animator.updateFrame(layer: node.layer, frame: nodeFrame, completion: nil)
|
animation.animator.updateFrame(layer: node.layer, frame: nodeFrame, completion: nil)
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,7 @@ final class MessageReactionButtonsNode: ASDisplayNode {
|
|||||||
|
|
||||||
private var bubbleBackgroundNode: WallpaperBubbleBackgroundNode?
|
private var bubbleBackgroundNode: WallpaperBubbleBackgroundNode?
|
||||||
private let container: ReactionButtonsAsyncLayoutContainer
|
private let container: ReactionButtonsAsyncLayoutContainer
|
||||||
private let backgroundMaskView: UIView
|
private var backgroundMaskView: UIView?
|
||||||
private var backgroundMaskButtons: [String: UIView] = [:]
|
private var backgroundMaskButtons: [String: UIView] = [:]
|
||||||
|
|
||||||
var reactionSelected: ((String) -> Void)?
|
var reactionSelected: ((String) -> Void)?
|
||||||
@ -67,7 +67,6 @@ final class MessageReactionButtonsNode: ASDisplayNode {
|
|||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
self.container = ReactionButtonsAsyncLayoutContainer()
|
self.container = ReactionButtonsAsyncLayoutContainer()
|
||||||
self.backgroundMaskView = UIView()
|
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
@ -219,6 +218,10 @@ final class MessageReactionButtonsNode: ASDisplayNode {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strongSelf.backgroundMaskView == nil {
|
||||||
|
strongSelf.backgroundMaskView = UIView()
|
||||||
|
}
|
||||||
|
|
||||||
let backgroundInsets: CGFloat = 10.0
|
let backgroundInsets: CGFloat = 10.0
|
||||||
|
|
||||||
switch type {
|
switch type {
|
||||||
@ -308,29 +311,29 @@ final class MessageReactionButtonsNode: ASDisplayNode {
|
|||||||
item.node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
item.node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
item.node.frame = itemFrame
|
item.node.frame = itemFrame
|
||||||
|
|
||||||
let itemValue = item.value
|
|
||||||
let itemNode = item.node
|
|
||||||
item.node.isGestureEnabled = true
|
|
||||||
let canViewReactionList = canViewMessageReactionList(message: message)
|
|
||||||
item.node.activateAfterCompletion = !canViewReactionList
|
|
||||||
item.node.activated = { [weak itemNode] gesture, _ in
|
|
||||||
guard let strongSelf = self, let itemNode = itemNode else {
|
|
||||||
gesture.cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !canViewReactionList {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongSelf.openReactionPreview?(gesture, itemNode.containerNode, itemValue)
|
|
||||||
}
|
|
||||||
item.node.additionalActivationProgressLayer = itemMaskView.layer
|
|
||||||
} else {
|
} else {
|
||||||
animation.animator.updateFrame(layer: item.node.layer, frame: itemFrame, completion: nil)
|
animation.animator.updateFrame(layer: item.node.layer, frame: itemFrame, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let itemValue = item.value
|
||||||
|
let itemNode = item.node
|
||||||
|
item.node.isGestureEnabled = true
|
||||||
|
let canViewReactionList = canViewMessageReactionList(message: message)
|
||||||
|
item.node.activateAfterCompletion = !canViewReactionList
|
||||||
|
item.node.activated = { [weak itemNode] gesture, _ in
|
||||||
|
guard let strongSelf = self, let itemNode = itemNode else {
|
||||||
|
gesture.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !canViewReactionList {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.openReactionPreview?(gesture, itemNode.containerNode, itemValue)
|
||||||
|
}
|
||||||
|
item.node.additionalActivationProgressLayer = itemMaskView.layer
|
||||||
|
|
||||||
if itemMaskView.superview == nil {
|
if itemMaskView.superview == nil {
|
||||||
strongSelf.backgroundMaskView.addSubview(itemMaskView)
|
strongSelf.backgroundMaskView?.addSubview(itemMaskView)
|
||||||
if animation.isAnimated {
|
if animation.isAnimated {
|
||||||
itemMaskView.layer.animateScale(from: 0.01, to: 1.0, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
itemMaskView.layer.animateScale(from: 0.01, to: 1.0, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
itemMaskView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
itemMaskView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
@ -689,7 +689,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
layoutSize.height += dateAndStatusSize.height
|
layoutSize.height += dateAndStatusSize.height
|
||||||
}
|
}
|
||||||
if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply {
|
if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply {
|
||||||
layoutSize.height += 4.0 + reactionButtonsSizeAndApply.0.height + 4.0
|
layoutSize.height += reactionButtonsSizeAndApply.0.height + 2.0
|
||||||
}
|
}
|
||||||
if let actionButtonsSizeAndApply = actionButtonsSizeAndApply {
|
if let actionButtonsSizeAndApply = actionButtonsSizeAndApply {
|
||||||
layoutSize.height += actionButtonsSizeAndApply.0.height
|
layoutSize.height += actionButtonsSizeAndApply.0.height
|
||||||
@ -986,7 +986,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply {
|
if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply {
|
||||||
let reactionButtonsNode = reactionButtonsSizeAndApply.1(animation)
|
let reactionButtonsNode = reactionButtonsSizeAndApply.1(animation)
|
||||||
var reactionButtonsFrame = CGRect(origin: CGPoint(x: imageFrame.minX, y: imageFrame.maxY - innerImageInset + 4.0), size: reactionButtonsSizeAndApply.0)
|
var reactionButtonsFrame = CGRect(origin: CGPoint(x: imageFrame.minX, y: dateAndStatusFrame.maxY + 6.0), size: reactionButtonsSizeAndApply.0)
|
||||||
if !incoming {
|
if !incoming {
|
||||||
reactionButtonsFrame.origin.x = imageFrame.maxX - innerImageInset - reactionButtonsSizeAndApply.0.width
|
reactionButtonsFrame.origin.x = imageFrame.maxX - innerImageInset - reactionButtonsSizeAndApply.0.width
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter)
|
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter, chatNavigationStack: params.chatNavigationStack)
|
||||||
}
|
}
|
||||||
controller.purposefulAction = params.purposefulAction
|
controller.purposefulAction = params.purposefulAction
|
||||||
if let search = params.activateMessageSearch {
|
if let search = params.activateMessageSearch {
|
||||||
|
@ -55,7 +55,7 @@ objc_library(
|
|||||||
"-DRTC_ENABLE_VP9",
|
"-DRTC_ENABLE_VP9",
|
||||||
"-DTGVOIP_NAMESPACE=tgvoip_webrtc",
|
"-DTGVOIP_NAMESPACE=tgvoip_webrtc",
|
||||||
"-std=c++14",
|
"-std=c++14",
|
||||||
"-DWEBRTC_DISABLE_H265",
|
#"-DWEBRTC_DISABLE_H265",
|
||||||
],
|
],
|
||||||
includes = [
|
includes = [
|
||||||
"PublicHeaders",
|
"PublicHeaders",
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 731818cea9bce6eb7f4ee36f28d62f2ee03bd2b7
|
Subproject commit b2c7f2f226a6c17a587b5fb421963a503855a2b6
|
@ -37,8 +37,8 @@
|
|||||||
@property (nonatomic) int32_t participantsCount;
|
@property (nonatomic) int32_t participantsCount;
|
||||||
@property (nonatomic, strong) NSArray *participants;
|
@property (nonatomic, strong) NSArray *participants;
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds;
|
- (NSArray<NSNumber *> *)involvedUserIds;
|
||||||
- (NSIndexSet *)participantsUserIds;
|
- (NSArray<NSNumber *> *)participantsUserIds;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ typedef NS_ENUM(NSUInteger, TGBridgeMessageDeliveryState) {
|
|||||||
@property (nonatomic, strong) NSArray *media;
|
@property (nonatomic, strong) NSArray *media;
|
||||||
@property (nonatomic) bool forceReply;
|
@property (nonatomic) bool forceReply;
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds;
|
- (NSArray<NSNumber *> *)involvedUserIds;
|
||||||
- (NSArray *)textCheckingResults;
|
- (NSArray *)textCheckingResults;
|
||||||
|
|
||||||
+ (instancetype)temporaryNewMessageForText:(NSString *)text userId:(int32_t)userId;
|
+ (instancetype)temporaryNewMessageForText:(NSString *)text userId:(int32_t)userId;
|
||||||
|
@ -94,13 +94,13 @@ NSString *const TGBridgeChatsArrayKey = @"chats";
|
|||||||
[aCoder encodeObject:self.participants forKey:TGBridgeChatGroupParticipantsKey];
|
[aCoder encodeObject:self.participants forKey:TGBridgeChatGroupParticipantsKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds
|
- (NSArray<NSNumber *> *)involvedUserIds
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *userIds = [[NSMutableSet alloc] init];
|
||||||
if (!self.isGroup && !self.isChannel && self.identifier != 0)
|
if (!self.isGroup && !self.isChannel && self.identifier != 0)
|
||||||
[userIds addIndex:(int32_t)self.identifier];
|
[userIds addObject:[NSNumber numberWithLongLong:self.identifier]];
|
||||||
if ((!self.isChannel || self.isChannelGroup) && self.fromUid != self.identifier && self.fromUid != 0 && !TGPeerIdIsChannel(self.fromUid) && self.fromUid > 0)
|
if ((!self.isChannel || self.isChannelGroup) && self.fromUid != self.identifier && self.fromUid != 0 && !TGPeerIdIsChannel(self.fromUid) && self.fromUid > 0)
|
||||||
[userIds addIndex:(int32_t)self.fromUid];
|
[userIds addObject:[NSNumber numberWithLongLong:self.fromUid]];
|
||||||
|
|
||||||
for (TGBridgeMediaAttachment *attachment in self.media)
|
for (TGBridgeMediaAttachment *attachment in self.media)
|
||||||
{
|
{
|
||||||
@ -108,21 +108,30 @@ NSString *const TGBridgeChatsArrayKey = @"chats";
|
|||||||
{
|
{
|
||||||
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
||||||
if (actionAttachment.actionData[@"uid"] != nil)
|
if (actionAttachment.actionData[@"uid"] != nil)
|
||||||
[userIds addIndex:[actionAttachment.actionData[@"uid"] integerValue]];
|
[userIds addObject:[NSNumber numberWithLongLong:[actionAttachment.actionData[@"uid"] longLongValue]]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userIds;
|
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||||
|
for (NSNumber *object in userIds) {
|
||||||
|
[result addObject:object];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)participantsUserIds
|
- (NSArray<NSNumber *> *)participantsUserIds
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *userIds = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
for (NSNumber *uid in self.participants)
|
for (NSNumber *uid in self.participants) {
|
||||||
[userIds addIndex:uid.unsignedIntegerValue];
|
[userIds addObject:[NSNumber numberWithLongLong:uid.longLongValue]];
|
||||||
|
}
|
||||||
|
|
||||||
return userIds;
|
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||||
|
for (NSNumber *object in userIds) {
|
||||||
|
[result addObject:object];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isEqual:(id)object
|
- (BOOL)isEqual:(id)object
|
||||||
|
@ -60,11 +60,11 @@ NSString *const TGBridgeMessagesArrayKey = @"messages";
|
|||||||
[aCoder encodeBool:self.forceReply forKey:TGBridgeMessageForceReplyKey];
|
[aCoder encodeBool:self.forceReply forKey:TGBridgeMessageForceReplyKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)involvedUserIds
|
- (NSArray<NSNumber *> *)involvedUserIds
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init];
|
NSMutableSet<NSNumber *> *userIds = [[NSMutableSet alloc] init];
|
||||||
if (!TGPeerIdIsChannel(self.fromUid))
|
if (!TGPeerIdIsChannel(self.fromUid))
|
||||||
[userIds addIndex:(int32_t)self.fromUid];
|
[userIds addObject:[NSNumber numberWithLongLong:self.fromUid]];
|
||||||
|
|
||||||
for (TGBridgeMediaAttachment *attachment in self.media)
|
for (TGBridgeMediaAttachment *attachment in self.media)
|
||||||
{
|
{
|
||||||
@ -72,29 +72,33 @@ NSString *const TGBridgeMessagesArrayKey = @"messages";
|
|||||||
{
|
{
|
||||||
TGBridgeContactMediaAttachment *contactAttachment = (TGBridgeContactMediaAttachment *)attachment;
|
TGBridgeContactMediaAttachment *contactAttachment = (TGBridgeContactMediaAttachment *)attachment;
|
||||||
if (contactAttachment.uid != 0)
|
if (contactAttachment.uid != 0)
|
||||||
[userIds addIndex:contactAttachment.uid];
|
[userIds addObject:[NSNumber numberWithLongLong:contactAttachment.uid]];
|
||||||
}
|
}
|
||||||
else if ([attachment isKindOfClass:[TGBridgeForwardedMessageMediaAttachment class]])
|
else if ([attachment isKindOfClass:[TGBridgeForwardedMessageMediaAttachment class]])
|
||||||
{
|
{
|
||||||
TGBridgeForwardedMessageMediaAttachment *forwardAttachment = (TGBridgeForwardedMessageMediaAttachment *)attachment;
|
TGBridgeForwardedMessageMediaAttachment *forwardAttachment = (TGBridgeForwardedMessageMediaAttachment *)attachment;
|
||||||
if (forwardAttachment.peerId != 0 && !TGPeerIdIsChannel(forwardAttachment.peerId))
|
if (forwardAttachment.peerId != 0 && !TGPeerIdIsChannel(forwardAttachment.peerId))
|
||||||
[userIds addIndex:(int32_t)forwardAttachment.peerId];
|
[userIds addObject:[NSNumber numberWithLongLong:forwardAttachment.peerId]];
|
||||||
}
|
}
|
||||||
else if ([attachment isKindOfClass:[TGBridgeReplyMessageMediaAttachment class]])
|
else if ([attachment isKindOfClass:[TGBridgeReplyMessageMediaAttachment class]])
|
||||||
{
|
{
|
||||||
TGBridgeReplyMessageMediaAttachment *replyAttachment = (TGBridgeReplyMessageMediaAttachment *)attachment;
|
TGBridgeReplyMessageMediaAttachment *replyAttachment = (TGBridgeReplyMessageMediaAttachment *)attachment;
|
||||||
if (replyAttachment.message != nil && !TGPeerIdIsChannel(replyAttachment.message.fromUid))
|
if (replyAttachment.message != nil && !TGPeerIdIsChannel(replyAttachment.message.fromUid))
|
||||||
[userIds addIndex:(int32_t)replyAttachment.message.fromUid];
|
[userIds addObject:[NSNumber numberWithLongLong:replyAttachment.message.fromUid]];
|
||||||
}
|
}
|
||||||
else if ([attachment isKindOfClass:[TGBridgeActionMediaAttachment class]])
|
else if ([attachment isKindOfClass:[TGBridgeActionMediaAttachment class]])
|
||||||
{
|
{
|
||||||
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment;
|
||||||
if (actionAttachment.actionData[@"uid"] != nil)
|
if (actionAttachment.actionData[@"uid"] != nil)
|
||||||
[userIds addIndex:(int32_t)[actionAttachment.actionData[@"uid"] intValue]];
|
[userIds addObject:[NSNumber numberWithLongLong:[actionAttachment.actionData[@"uid"] intValue]]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userIds;
|
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||||
|
for (NSNumber *object in userIds) {
|
||||||
|
[result addObject:object];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)textCheckingResults
|
- (NSArray *)textCheckingResults
|
||||||
|
12
third-party/webrtc/BUILD
vendored
12
third-party/webrtc/BUILD
vendored
@ -2940,6 +2940,16 @@ webrtc_sources = [
|
|||||||
"api/wrapping_async_dns_resolver.cc",
|
"api/wrapping_async_dns_resolver.cc",
|
||||||
"modules/video_coding/utility/bandwidth_quality_scaler.cc",
|
"modules/video_coding/utility/bandwidth_quality_scaler.cc",
|
||||||
"rtc_base/experiments/bandwidth_quality_scaler_settings.cc",
|
"rtc_base/experiments/bandwidth_quality_scaler_settings.cc",
|
||||||
|
"common_video/h265/h265_common.cc",
|
||||||
|
"common_video/h265/h265_pps_parser.cc",
|
||||||
|
"common_video/h265/h265_sps_parser.cc",
|
||||||
|
"common_video/h265/h265_vps_parser.cc",
|
||||||
|
"common_video/h265/legacy_bit_buffer.h",
|
||||||
|
"common_video/h265/legacy_bit_buffer.cc",
|
||||||
|
"modules/rtp_rtcp/source/rtp_format_h265.cc",
|
||||||
|
"modules/video_coding/h265_vps_sps_pps_tracker.cc",
|
||||||
|
"modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc",
|
||||||
|
"common_video/h265/h265_bitstream_parser.cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
ios_objc_sources = [
|
ios_objc_sources = [
|
||||||
@ -3201,6 +3211,8 @@ ios_sources = [
|
|||||||
"objc/components/network/RTCNetworkMonitor+Private.h",
|
"objc/components/network/RTCNetworkMonitor+Private.h",
|
||||||
"objc/components/network/RTCNetworkMonitor.mm",
|
"objc/components/network/RTCNetworkMonitor.mm",
|
||||||
"objc/native/src/network_monitor_observer.h",
|
"objc/native/src/network_monitor_observer.h",
|
||||||
|
"objc/components/video_codec/RTCCodecSpecificInfoH265.mm",
|
||||||
|
"objc/components/video_codec/RTCH265ProfileLevelId.mm",
|
||||||
]
|
]
|
||||||
|
|
||||||
common_arm_specific_sources = [webrtc_source_dir + "/" + path for path in [
|
common_arm_specific_sources = [webrtc_source_dir + "/" + path for path in [
|
||||||
|
2
third-party/webrtc/webrtc
vendored
2
third-party/webrtc/webrtc
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 73bf8cd601c83152211321a30e818dcdeec1bbfd
|
Subproject commit 9cd0a24a2e450bcc731fbce6f3fe0fb516c75bc2
|
Loading…
x
Reference in New Issue
Block a user