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
1b3512c698
@ -718,6 +718,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
jsonParams: nil,
|
||||
joinTimestamp: strongSelf.temporaryJoinTimestamp,
|
||||
activityTimestamp: nil,
|
||||
activityRank: nil,
|
||||
muteState: GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false),
|
||||
volume: nil
|
||||
))
|
||||
|
@ -1202,12 +1202,12 @@ public class Account {
|
||||
}
|
||||
}
|
||||
|
||||
public func allPeerInputActivities() -> Signal<[PeerActivitySpace: [PeerId: PeerInputActivity]], NoError> {
|
||||
public func allPeerInputActivities() -> Signal<[PeerActivitySpace: [(PeerId, PeerInputActivity)]], NoError> {
|
||||
return self.peerInputActivityManager.allActivities()
|
||||
|> map { activities in
|
||||
var result: [PeerActivitySpace: [PeerId: PeerInputActivity]] = [:]
|
||||
var result: [PeerActivitySpace: [(PeerId, PeerInputActivity)]] = [:]
|
||||
for (chatPeerId, chatActivities) in activities {
|
||||
result[chatPeerId] = chatActivities.mapValues({ $0.activity })
|
||||
result[chatPeerId] = chatActivities.map { ($0.0, $0.1.activity) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
|
||||
jsonParams: jsonParams,
|
||||
joinTimestamp: date,
|
||||
activityTimestamp: activeDate.flatMap(Double.init),
|
||||
activityRank: nil,
|
||||
muteState: muteState,
|
||||
volume: volume
|
||||
))
|
||||
@ -264,6 +265,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
|
||||
jsonParams: jsonParams,
|
||||
joinTimestamp: date,
|
||||
activityTimestamp: activeDate.flatMap(Double.init),
|
||||
activityRank: nil,
|
||||
muteState: muteState,
|
||||
volume: volume
|
||||
))
|
||||
@ -271,6 +273,8 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
|
||||
}
|
||||
}
|
||||
|
||||
parsedParticipants.sort()
|
||||
|
||||
return GroupCallParticipantsContext.State(
|
||||
participants: parsedParticipants,
|
||||
nextParticipantsFetchOffset: nextParticipantsFetchOffset,
|
||||
@ -311,7 +315,6 @@ public func joinGroupCall(account: Account, peerId: PeerId, callId: Int64, acces
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<JoinGroupCallResult, JoinGroupCallError> in
|
||||
|
||||
let admins: Signal<(Set<PeerId>, [Api.User]), JoinGroupCallError>
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
admins = account.postbox.transaction { transaction -> Api.InputChannel? in
|
||||
@ -592,6 +595,7 @@ public final class GroupCallParticipantsContext {
|
||||
public var jsonParams: String?
|
||||
public var joinTimestamp: Int32
|
||||
public var activityTimestamp: Double?
|
||||
public var activityRank: Int?
|
||||
public var muteState: MuteState?
|
||||
public var volume: Int32?
|
||||
|
||||
@ -601,6 +605,7 @@ public final class GroupCallParticipantsContext {
|
||||
jsonParams: String?,
|
||||
joinTimestamp: Int32,
|
||||
activityTimestamp: Double?,
|
||||
activityRank: Int?,
|
||||
muteState: MuteState?,
|
||||
volume: Int32?
|
||||
) {
|
||||
@ -609,6 +614,7 @@ public final class GroupCallParticipantsContext {
|
||||
self.jsonParams = jsonParams
|
||||
self.joinTimestamp = joinTimestamp
|
||||
self.activityTimestamp = activityTimestamp
|
||||
self.activityRank = activityRank
|
||||
self.muteState = muteState
|
||||
self.volume = volume
|
||||
}
|
||||
@ -626,6 +632,9 @@ public final class GroupCallParticipantsContext {
|
||||
if lhs.activityTimestamp != rhs.activityTimestamp {
|
||||
return false
|
||||
}
|
||||
if lhs.activityRank != rhs.activityRank {
|
||||
return false
|
||||
}
|
||||
if lhs.muteState != rhs.muteState {
|
||||
return false
|
||||
}
|
||||
@ -636,6 +645,16 @@ public final class GroupCallParticipantsContext {
|
||||
}
|
||||
|
||||
public static func <(lhs: Participant, rhs: Participant) -> Bool {
|
||||
if let lhsActivityRank = lhs.activityRank, let rhsActivityRank = rhs.activityRank {
|
||||
if lhsActivityRank != rhsActivityRank {
|
||||
return lhsActivityRank < rhsActivityRank
|
||||
}
|
||||
} else if lhs.activityRank != nil {
|
||||
return true
|
||||
} else if rhs.activityRank != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if let lhsActivityTimestamp = lhs.activityTimestamp, let rhsActivityTimestamp = rhs.activityTimestamp {
|
||||
if lhsActivityTimestamp != rhsActivityTimestamp {
|
||||
return lhsActivityTimestamp > rhsActivityTimestamp
|
||||
@ -823,6 +842,9 @@ public final class GroupCallParticipantsContext {
|
||||
private var shouldResetStateFromServer: Bool = false
|
||||
private var missingSsrcs = Set<UInt32>()
|
||||
|
||||
private var nextActivityRank: Int = 0
|
||||
private var activityRankResetTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private let updateDefaultMuteDisposable = MetaDisposable()
|
||||
|
||||
public init(account: Account, peerId: PeerId, id: Int64, accessHash: Int64, state: State) {
|
||||
@ -912,6 +934,36 @@ public final class GroupCallParticipantsContext {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.activityRankResetTimer = SwiftSignalKit.Timer(timeout: 10.0, repeat: true, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
var updated = false
|
||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||
|
||||
for i in 0 ..< strongSelf.stateValue.state.participants.count {
|
||||
if strongSelf.stateValue.state.participants[i].activityRank != nil {
|
||||
var clearRank = false
|
||||
if let activityTimestamp = strongSelf.stateValue.state.participants[i].activityTimestamp {
|
||||
if activityTimestamp < timestamp - 60.0 {
|
||||
clearRank = true
|
||||
}
|
||||
} else {
|
||||
clearRank = true
|
||||
}
|
||||
if clearRank {
|
||||
updated = true
|
||||
strongSelf.stateValue.state.participants[i].activityRank = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
strongSelf.stateValue.state.participants.sort()
|
||||
}
|
||||
}, queue: .mainQueue())
|
||||
self.activityRankResetTimer?.start()
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -919,6 +971,7 @@ public final class GroupCallParticipantsContext {
|
||||
self.updatesDisposable.dispose()
|
||||
self.activitiesDisposable?.dispose()
|
||||
self.updateDefaultMuteDisposable.dispose()
|
||||
self.activityRankResetTimer?.invalidate()
|
||||
}
|
||||
|
||||
public func addUpdates(updates: [Update]) {
|
||||
@ -937,6 +990,12 @@ public final class GroupCallParticipantsContext {
|
||||
}
|
||||
}
|
||||
|
||||
private func takeNextActivityRank() -> Int {
|
||||
let value = self.nextActivityRank
|
||||
self.nextActivityRank += 1
|
||||
return value
|
||||
}
|
||||
|
||||
public func reportSpeakingParticipants(ids: [PeerId: UInt32]) {
|
||||
if !ids.isEmpty {
|
||||
self.hasReceivedSpeakingParticipantsReport = true
|
||||
@ -965,6 +1024,9 @@ public final class GroupCallParticipantsContext {
|
||||
}
|
||||
if updateTimestamp {
|
||||
updatedParticipants[index].activityTimestamp = timestamp
|
||||
if updatedParticipants[index].activityRank == nil {
|
||||
updatedParticipants[index].activityRank = self.takeNextActivityRank()
|
||||
}
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
@ -1040,19 +1102,7 @@ public final class GroupCallParticipantsContext {
|
||||
|
||||
var updatedState = strongSelf.stateValue.state
|
||||
|
||||
var existingParticipantIds = Set<PeerId>()
|
||||
for participant in updatedState.participants {
|
||||
existingParticipantIds.insert(participant.peer.id)
|
||||
}
|
||||
for participant in state.participants {
|
||||
if existingParticipantIds.contains(participant.peer.id) {
|
||||
continue
|
||||
}
|
||||
existingParticipantIds.insert(participant.peer.id)
|
||||
updatedState.participants.append(participant)
|
||||
}
|
||||
|
||||
updatedState.participants.sort()
|
||||
updatedState.participants = mergeAndSortParticipants(current: updatedState.participants, with: state.participants)
|
||||
|
||||
updatedState.totalCount = max(updatedState.totalCount, state.totalCount)
|
||||
updatedState.version = max(updatedState.version, updatedState.version)
|
||||
@ -1138,8 +1188,10 @@ public final class GroupCallParticipantsContext {
|
||||
continue
|
||||
}
|
||||
var previousActivityTimestamp: Double?
|
||||
var previousActivityRank: Int?
|
||||
if let index = updatedParticipants.firstIndex(where: { $0.peer.id == participantUpdate.peerId }) {
|
||||
previousActivityTimestamp = updatedParticipants[index].activityTimestamp
|
||||
previousActivityRank = updatedParticipants[index].activityRank
|
||||
updatedParticipants.remove(at: index)
|
||||
} else if case .joined = participantUpdate.participationStatusChange {
|
||||
updatedTotalCount += 1
|
||||
@ -1159,6 +1211,7 @@ public final class GroupCallParticipantsContext {
|
||||
jsonParams: participantUpdate.jsonParams,
|
||||
joinTimestamp: participantUpdate.joinTimestamp,
|
||||
activityTimestamp: activityTimestamp,
|
||||
activityRank: previousActivityRank,
|
||||
muteState: participantUpdate.muteState,
|
||||
volume: participantUpdate.volume
|
||||
)
|
||||
@ -1179,14 +1232,6 @@ public final class GroupCallParticipantsContext {
|
||||
let defaultParticipantsAreMuted = strongSelf.stateValue.state.defaultParticipantsAreMuted
|
||||
|
||||
updatedParticipants.sort()
|
||||
/*for i in 0 ..< updatedParticipants.count {
|
||||
if updatedParticipants[i].peer.id == strongSelf.account.peerId {
|
||||
let member = updatedParticipants[i]
|
||||
updatedParticipants.remove(at: i)
|
||||
updatedParticipants.insert(member, at: 0)
|
||||
break
|
||||
}
|
||||
}*/
|
||||
|
||||
strongSelf.stateValue = InternalState(
|
||||
state: State(
|
||||
@ -1344,17 +1389,7 @@ public final class GroupCallParticipantsContext {
|
||||
|
||||
var updatedState = strongSelf.stateValue.state
|
||||
|
||||
var existingParticipantIds = Set<PeerId>()
|
||||
for participant in updatedState.participants {
|
||||
existingParticipantIds.insert(participant.peer.id)
|
||||
}
|
||||
for participant in state.participants {
|
||||
if existingParticipantIds.contains(participant.peer.id) {
|
||||
continue
|
||||
}
|
||||
existingParticipantIds.insert(participant.peer.id)
|
||||
updatedState.participants.append(participant)
|
||||
}
|
||||
updatedState.participants = mergeAndSortParticipants(current: updatedState.participants, with: state.participants)
|
||||
|
||||
updatedState.nextParticipantsFetchOffset = state.nextParticipantsFetchOffset
|
||||
updatedState.totalCount = max(updatedState.totalCount, state.totalCount)
|
||||
@ -1513,3 +1548,23 @@ public func updatedCurrentPeerGroupCall(account: Account, peerId: PeerId) -> Sig
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func mergeAndSortParticipants(current currentParticipants: [GroupCallParticipantsContext.Participant], with updatedParticipants: [GroupCallParticipantsContext.Participant]) -> [GroupCallParticipantsContext.Participant] {
|
||||
var mergedParticipants = currentParticipants
|
||||
|
||||
var existingParticipantIndices: [PeerId: Int] = [:]
|
||||
for i in 0 ..< mergedParticipants.count {
|
||||
existingParticipantIndices[mergedParticipants[i].peer.id] = i
|
||||
}
|
||||
for participant in updatedParticipants {
|
||||
if let _ = existingParticipantIndices[participant.peer.id] {
|
||||
} else {
|
||||
existingParticipantIndices[participant.peer.id] = mergedParticipants.count
|
||||
mergedParticipants.append(participant)
|
||||
}
|
||||
}
|
||||
|
||||
mergedParticipants.sort()
|
||||
|
||||
return mergedParticipants
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ struct PeerInputActivityRecord: Equatable {
|
||||
private final class ManagedLocalTypingActivitiesContext {
|
||||
private var disposables: [PeerActivitySpace: (PeerInputActivityRecord, MetaDisposable)] = [:]
|
||||
|
||||
func update(activities: [PeerActivitySpace: [PeerId: PeerInputActivityRecord]]) -> (start: [(PeerActivitySpace, PeerInputActivityRecord?, MetaDisposable)], dispose: [MetaDisposable]) {
|
||||
func update(activities: [PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]]) -> (start: [(PeerActivitySpace, PeerInputActivityRecord?, MetaDisposable)], dispose: [MetaDisposable]) {
|
||||
var start: [(PeerActivitySpace, PeerInputActivityRecord?, MetaDisposable)] = []
|
||||
var dispose: [MetaDisposable] = []
|
||||
|
||||
var validPeerIds = Set<PeerActivitySpace>()
|
||||
for (peerId, record) in activities {
|
||||
if let activity = record.values.first {
|
||||
if let activity = record.first?.1 {
|
||||
validPeerIds.insert(peerId)
|
||||
|
||||
let currentRecord = self.disposables[peerId]
|
||||
@ -76,7 +76,7 @@ private final class ManagedLocalTypingActivitiesContext {
|
||||
}
|
||||
}
|
||||
|
||||
func managedLocalTypingActivities(activities: Signal<[PeerActivitySpace: [PeerId: PeerInputActivityRecord]], NoError>, postbox: Postbox, network: Network, accountPeerId: PeerId) -> Signal<Void, NoError> {
|
||||
func managedLocalTypingActivities(activities: Signal<[PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]], NoError>, postbox: Postbox, network: Network, accountPeerId: PeerId) -> Signal<Void, NoError> {
|
||||
return Signal { subscriber in
|
||||
let context = Atomic(value: ManagedLocalTypingActivitiesContext())
|
||||
let disposable = activities.start(next: { activities in
|
||||
|
@ -178,9 +178,9 @@ private final class PeerInputActivityContext {
|
||||
}
|
||||
|
||||
private final class PeerGlobalInputActivityContext {
|
||||
private let subscribers = Bag<([PeerActivitySpace: [PeerId: PeerInputActivityRecord]]) -> Void>()
|
||||
private let subscribers = Bag<([PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]]) -> Void>()
|
||||
|
||||
func addSubscriber(_ subscriber: @escaping ([PeerActivitySpace: [PeerId: PeerInputActivityRecord]]) -> Void) -> Int {
|
||||
func addSubscriber(_ subscriber: @escaping ([PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]]) -> Void) -> Int {
|
||||
return self.subscribers.add(subscriber)
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ private final class PeerGlobalInputActivityContext {
|
||||
return self.subscribers.isEmpty
|
||||
}
|
||||
|
||||
func notify(_ activities: [PeerActivitySpace: [PeerId: PeerInputActivityRecord]]) {
|
||||
func notify(_ activities: [PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]]) {
|
||||
for subscriber in self.subscribers.copyItems() {
|
||||
subscriber(activities)
|
||||
}
|
||||
@ -256,21 +256,17 @@ final class PeerInputActivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
private func collectActivities() -> [PeerActivitySpace: [PeerId: PeerInputActivityRecord]] {
|
||||
private func collectActivities() -> [PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]] {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
var dict: [PeerActivitySpace: [PeerId: PeerInputActivityRecord]] = [:]
|
||||
var dict: [PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]] = [:]
|
||||
for (chatPeerId, context) in self.contexts {
|
||||
var chatDict: [PeerId: PeerInputActivityRecord] = [:]
|
||||
for (peerId, activity) in context.topActivities() {
|
||||
chatDict[peerId] = activity
|
||||
}
|
||||
dict[chatPeerId] = chatDict
|
||||
dict[chatPeerId] = context.topActivities()
|
||||
}
|
||||
return dict
|
||||
}
|
||||
|
||||
func allActivities() -> Signal<[PeerActivitySpace: [PeerId: PeerInputActivityRecord]], NoError> {
|
||||
func allActivities() -> Signal<[PeerActivitySpace: [(PeerId, PeerInputActivityRecord)]], NoError> {
|
||||
let queue = self.queue
|
||||
return Signal { [weak self] subscriber in
|
||||
let disposable = MetaDisposable()
|
||||
|
@ -10250,10 +10250,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case .upperBound:
|
||||
searchLocation = .index(MessageIndex.upperBound(peerId: self.chatLocation.peerId))
|
||||
}
|
||||
var historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(location: searchLocation, count: 50, highlight: true), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: [])
|
||||
#if DEBUG
|
||||
historyView = historyView |> delay(1.0, queue: .mainQueue())
|
||||
#endif
|
||||
let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(location: searchLocation, count: 50, highlight: true), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: [])
|
||||
|
||||
let signal = historyView
|
||||
|> mapToSignal { historyView -> Signal<(MessageIndex?, Bool), NoError> in
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5ab60bbb78f2a71c945cd8ea82810d22f95cf9cd
|
||||
Subproject commit d2b15b9edfe2eeaaa9862adb0ae38f8e6308b5fb
|
Loading…
x
Reference in New Issue
Block a user