Various fixes

This commit is contained in:
Ilya Laktyushin 2023-07-27 16:49:40 +02:00
parent cd551f1a5e
commit d98e2779a0
4 changed files with 77 additions and 27 deletions

View File

@ -37,6 +37,7 @@ swift_library(
"//submodules/TelegramUI/Components/LottieComponent", "//submodules/TelegramUI/Components/LottieComponent",
"//submodules/TelegramUI/Components/SwitchComponent", "//submodules/TelegramUI/Components/SwitchComponent",
"//submodules/TooltipUI", "//submodules/TooltipUI",
"//submodules/OverlayStatusController",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -22,6 +22,7 @@ import LocalizedPeerData
import PeerListItemComponent import PeerListItemComponent
import LottieComponent import LottieComponent
import TooltipUI import TooltipUI
import OverlayStatusController
final class ShareWithPeersScreenComponent: Component { final class ShareWithPeersScreenComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment typealias EnvironmentType = ViewControllerComponentContainer.Environment
@ -561,6 +562,7 @@ final class ShareWithPeersScreenComponent: Component {
controller.present(tooltipScreen, in: .window(.root)) controller.present(tooltipScreen, in: .window(.root))
} }
private weak var progressController: ViewController?
private func toggleGroupPeer(_ peer: EnginePeer) { private func toggleGroupPeer(_ peer: EnginePeer) {
guard let component = self.component, let environment = self.environment, let controller = self.environment?.controller() else { guard let component = self.component, let environment = self.environment, let controller = self.environment?.controller() else {
return return
@ -604,11 +606,33 @@ final class ShareWithPeersScreenComponent: Component {
append = true append = true
} }
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkPresentationTheme)
let progressSignal = Signal<Never, NoError> { [weak self, weak controller] subscriber in
let progressController = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
controller?.present(progressController, in: .window(.root))
self?.progressController = progressController
return ActionDisposable { [weak progressController, weak self] in
Queue.mainQueue().async() {
progressController?.dismiss()
self?.progressController = nil
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.15, queue: Queue.mainQueue())
let progressDisposable = progressSignal.start()
let processPeers: ([EnginePeer]) -> Void = { [weak self] peers in let processPeers: ([EnginePeer]) -> Void = { [weak self] peers in
guard let self else { guard let self else {
return return
} }
progressDisposable.dispose()
var peerIds = Set<EnginePeer.Id>() var peerIds = Set<EnginePeer.Id>()
for peer in peers { for peer in peers {
self.peersMap[peer.id] = peer self.peersMap[peer.id] = peer
@ -649,7 +673,13 @@ final class ShareWithPeersScreenComponent: Component {
|> map { peers in |> map { peers in
var result: [EnginePeer] = [] var result: [EnginePeer] = []
for participant in participants { for participant in participants {
if let peer = peers[participant.peerId], let peer, peer.id != context.account.peerId { if let peer = peers[participant.peerId], let peer {
if peer.id == context.account.peerId {
continue
}
if case let .user(user) = peer, user.botInfo != nil {
continue
}
result.append(peer) result.append(peer)
} }
} }
@ -666,9 +696,15 @@ final class ShareWithPeersScreenComponent: Component {
}) })
} else if peer.id.namespace == Namespaces.Peer.CloudChannel { } else if peer.id.namespace == Namespaces.Peer.CloudChannel {
let participants: Signal<[EnginePeer], NoError> = Signal { subscriber in let participants: Signal<[EnginePeer], NoError> = Signal { subscriber in
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peer.id, requestUpdate: true, updated: { list in let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peer.id, requestUpdate: true, count: 200, updated: { list in
var peers: [EnginePeer] = [] var peers: [EnginePeer] = []
for item in list.list { for item in list.list {
if item.peer.id == context.account.peerId {
continue
}
if let user = item.peer as? TelegramUser, user.botInfo != nil {
continue
}
peers.append(EnginePeer(item.peer)) peers.append(EnginePeer(item.peer))
} }
if !peers.isEmpty { if !peers.isEmpty {
@ -2017,17 +2053,18 @@ public class ShareWithPeersScreen: ViewControllerComponentContainer {
case .chats: case .chats:
self.stateDisposable = (combineLatest( self.stateDisposable = (combineLatest(
context.engine.messages.chatList(group: .root, count: 200) |> take(1), context.engine.messages.chatList(group: .root, count: 200) |> take(1),
context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: true)) context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: true)),
context.engine.data.get(EngineDataMap(Array(self.initialPeerIds).map(TelegramEngine.EngineData.Item.Peer.Peer.init)))
) )
|> mapToSignal { chatList, contacts -> Signal<(EngineChatList, EngineContactList, [EnginePeer.Id: Optional<Int>]), NoError> in |> mapToSignal { chatList, contacts, initialPeers -> Signal<(EngineChatList, EngineContactList, [EnginePeer.Id: Optional<EnginePeer>], [EnginePeer.Id: Optional<Int>]), NoError> in
return context.engine.data.subscribe( return context.engine.data.subscribe(
EngineDataMap(chatList.items.map(\.renderedPeer.peerId).map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init)) EngineDataMap(chatList.items.map(\.renderedPeer.peerId).map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init))
) )
|> map { participantCountMap -> (EngineChatList, EngineContactList, [EnginePeer.Id: Optional<Int>]) in |> map { participantCountMap -> (EngineChatList, EngineContactList, [EnginePeer.Id: Optional<EnginePeer>], [EnginePeer.Id: Optional<Int>]) in
return (chatList, contacts, participantCountMap) return (chatList, contacts, initialPeers, participantCountMap)
} }
} }
|> deliverOnMainQueue).start(next: { [weak self] chatList, contacts, participantCounts in |> deliverOnMainQueue).start(next: { [weak self] chatList, contacts, initialPeers, participantCounts in
guard let self else { guard let self else {
return return
} }
@ -2048,6 +2085,13 @@ public class ShareWithPeersScreen: ViewControllerComponentContainer {
} }
} }
for peerId in self.initialPeerIds {
if !existingIds.contains(peerId), let maybePeer = initialPeers[peerId], let peer = maybePeer {
selectedPeers.append(peer)
existingIds.insert(peerId)
}
}
var presences: [EnginePeer.Id: EnginePeer.Presence] = [:] var presences: [EnginePeer.Id: EnginePeer.Presence] = [:]
for item in chatList.items { for item in chatList.items {
presences[item.renderedPeer.peerId] = item.presence presences[item.renderedPeer.peerId] = item.presence

View File

@ -108,6 +108,7 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor
private let network: Network private let network: Network
private let accountPeerId: PeerId private let accountPeerId: PeerId
private let peerId: PeerId private let peerId: PeerId
private let batchCount: Int32?
private let category: ChannelMemberListCategory private let category: ChannelMemberListCategory
var listStateValue: ChannelMemberListState { var listStateValue: ChannelMemberListState {
@ -153,12 +154,13 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor
private var headUpdateTimer: SwiftSignalKit.Timer? private var headUpdateTimer: SwiftSignalKit.Timer?
init(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, category: ChannelMemberListCategory) { init(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, batchCount: Int32?, category: ChannelMemberListCategory) {
self.engine = engine self.engine = engine
self.postbox = postbox self.postbox = postbox
self.network = network self.network = network
self.accountPeerId = accountPeerId self.accountPeerId = accountPeerId
self.peerId = peerId self.peerId = peerId
self.batchCount = batchCount
self.category = category self.category = category
self.listStateValue = ChannelMemberListState(list: [], peerStoryStats: [:], loadingState: .ready(hasMore: true)) self.listStateValue = ChannelMemberListState(list: [], peerStoryStats: [:], loadingState: .ready(hasMore: true))
@ -183,9 +185,9 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor
let loadCount: Int32 let loadCount: Int32
if case .ready(true) = self.listStateValue.loadingState, self.listStateValue.list.isEmpty { if case .ready(true) = self.listStateValue.loadingState, self.listStateValue.list.isEmpty {
loadCount = initialBatchSize loadCount = self.batchCount ?? initialBatchSize
} else { } else {
loadCount = requestBatchSize loadCount = self.batchCount ?? requestBatchSize
} }
self.listStateValue.loadingState = .loading(initial: initial) self.listStateValue.loadingState = .loading(initial: initial)
@ -201,8 +203,9 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor
} else { } else {
var list = self.listStateValue.list var list = self.listStateValue.list
var loadingState: ChannelMemberListLoadingState = .ready(hasMore: true) var loadingState: ChannelMemberListLoadingState = .ready(hasMore: true)
if list.count > Int(initialBatchSize) && !force { let batchSize = self.batchCount ?? initialBatchSize
list.removeSubrange(Int(initialBatchSize) ..< list.count) if list.count > Int(batchSize) && !force {
list.removeSubrange(Int(batchSize) ..< list.count)
loadingState = .ready(hasMore: true) loadingState = .ready(hasMore: true)
} }
@ -331,13 +334,13 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor
} }
var acc: UInt64 = 0 var acc: UInt64 = 0
let batchSize = strongSelf.batchCount ?? initialBatchSize
for i in 0 ..< min(strongSelf.listStateValue.list.count, Int(initialBatchSize)) { for i in 0 ..< min(strongSelf.listStateValue.list.count, Int(batchSize)) {
let peerId = strongSelf.listStateValue.list[i].peer.id let peerId = strongSelf.listStateValue.list[i].peer.id
combineInt64Hash(&acc, with: peerId) combineInt64Hash(&acc, with: peerId)
} }
let hashResult = finalizeInt64Hash(acc) let hashResult = finalizeInt64Hash(acc)
strongSelf.headUpdateDisposable.set((strongSelf.loadSignal(offset: 0, count: initialBatchSize, hash: hashResult) strongSelf.headUpdateDisposable.set((strongSelf.loadSignal(offset: 0, count: batchSize, hash: hashResult)
|> deliverOnMainQueue).start(next: { members in |> deliverOnMainQueue).start(next: { members in
self?.updateHeadMembers(members) self?.updateHeadMembers(members)
})) }))
@ -617,7 +620,7 @@ private final class ChannelMemberMultiCategoryListContext: ChannelMemberCategory
init(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, categories: [ChannelMemberListCategory]) { init(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, categories: [ChannelMemberListCategory]) {
self.contexts = categories.map { category in self.contexts = categories.map { category in
return ChannelMemberSingleCategoryListContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, category: category) return ChannelMemberSingleCategoryListContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, batchCount: nil, category: category)
} }
} }
@ -732,16 +735,18 @@ final class PeerChannelMemberCategoriesContext {
private let network: Network private let network: Network
private let accountPeerId: PeerId private let accountPeerId: PeerId
private let peerId: PeerId private let peerId: PeerId
private let batchCount: Int32?
private var becameEmpty: (Bool) -> Void private var becameEmpty: (Bool) -> Void
private var contexts: [PeerChannelMemberContextKey: PeerChannelMemberContextWithSubscribers] = [:] private var contexts: [PeerChannelMemberContextKey: PeerChannelMemberContextWithSubscribers] = [:]
init(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, becameEmpty: @escaping (Bool) -> Void) { init(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, batchCount: Int32?, becameEmpty: @escaping (Bool) -> Void) {
self.engine = engine self.engine = engine
self.postbox = postbox self.postbox = postbox
self.network = network self.network = network
self.accountPeerId = accountPeerId self.accountPeerId = accountPeerId
self.peerId = peerId self.peerId = peerId
self.batchCount = batchCount
self.becameEmpty = becameEmpty self.becameEmpty = becameEmpty
} }
@ -786,13 +791,13 @@ final class PeerChannelMemberCategoriesContext {
default: default:
mappedCategory = .recent mappedCategory = .recent
} }
context = ChannelMemberSingleCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, category: mappedCategory) context = ChannelMemberSingleCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, batchCount: self.batchCount, category: mappedCategory)
case let .restrictedAndBanned(query): case let .restrictedAndBanned(query):
context = ChannelMemberMultiCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, categories: [.restricted(query), .banned(query)]) context = ChannelMemberMultiCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, categories: [.restricted(query), .banned(query)])
case let .restricted(query): case let .restricted(query):
context = ChannelMemberSingleCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, category: .restricted(query)) context = ChannelMemberSingleCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, batchCount: nil, category: .restricted(query))
case let .banned(query): case let .banned(query):
context = ChannelMemberSingleCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, category: .banned(query)) context = ChannelMemberSingleCategoryListContext(engine: self.engine, postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, peerId: self.peerId, batchCount: nil, category: .banned(query))
} }
let contextWithSubscribers = PeerChannelMemberContextWithSubscribers(context: context, emptyTimeout: emptyTimeout, becameEmpty: { [weak self] in let contextWithSubscribers = PeerChannelMemberContextWithSubscribers(context: context, emptyTimeout: emptyTimeout, becameEmpty: { [weak self] in
assert(Queue.mainQueue().isCurrent()) assert(Queue.mainQueue().isCurrent())

View File

@ -56,12 +56,12 @@ private final class PeerChannelMemberCategoriesContextsManagerImpl {
fileprivate var profileDataPreloadContexts: [PeerId: ProfileDataPreloadContext] = [:] fileprivate var profileDataPreloadContexts: [PeerId: ProfileDataPreloadContext] = [:]
fileprivate var profileDataPhotoPreloadContexts: [PeerId: ProfileDataPhotoPreloadContext] = [:] fileprivate var profileDataPhotoPreloadContexts: [PeerId: ProfileDataPhotoPreloadContext] = [:]
func getContext(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, key: PeerChannelMemberContextKey, requestUpdate: Bool, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl) { func getContext(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, key: PeerChannelMemberContextKey, requestUpdate: Bool, count: Int32? = nil, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl) {
if let current = self.contexts[peerId] { if let current = self.contexts[peerId] {
return current.getContext(key: key, requestUpdate: requestUpdate, updated: updated) return current.getContext(key: key, requestUpdate: requestUpdate, updated: updated)
} else { } else {
var becameEmptyImpl: ((Bool) -> Void)? var becameEmptyImpl: ((Bool) -> Void)?
let context = PeerChannelMemberCategoriesContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, becameEmpty: { value in let context = PeerChannelMemberCategoriesContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, batchCount: count, becameEmpty: { value in
becameEmptyImpl?(value) becameEmptyImpl?(value)
}) })
becameEmptyImpl = { [weak self, weak context] value in becameEmptyImpl = { [weak self, weak context] value in
@ -297,10 +297,10 @@ public final class PeerChannelMemberCategoriesContextsManager {
} }
} }
private func getContext(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, key: PeerChannelMemberContextKey, requestUpdate: Bool, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) { private func getContext(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, key: PeerChannelMemberContextKey, requestUpdate: Bool, count: Int32? = nil, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) {
assert(Queue.mainQueue().isCurrent()) assert(Queue.mainQueue().isCurrent())
let (disposable, control) = self.impl.syncWith({ impl in let (disposable, control) = self.impl.syncWith({ impl in
return impl.getContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: key, requestUpdate: requestUpdate, updated: updated) return impl.getContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: key, requestUpdate: requestUpdate, count: count, updated: updated)
}) })
return (disposable, control) return (disposable, control)
} }
@ -325,14 +325,14 @@ public final class PeerChannelMemberCategoriesContextsManager {
} }
} }
public func recent(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, searchQuery: String? = nil, requestUpdate: Bool = true, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) { public func recent(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, searchQuery: String? = nil, requestUpdate: Bool = true, count: Int32? = nil, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) {
let key: PeerChannelMemberContextKey let key: PeerChannelMemberContextKey
if let searchQuery = searchQuery { if let searchQuery = searchQuery {
key = .recentSearch(searchQuery) key = .recentSearch(searchQuery)
} else { } else {
key = .recent key = .recent
} }
return self.getContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: key, requestUpdate: requestUpdate, updated: updated) return self.getContext(engine: engine, postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: key, requestUpdate: requestUpdate, count: count, updated: updated)
} }
public func mentions(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, threadMessageId: MessageId?, searchQuery: String? = nil, requestUpdate: Bool = true, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) { public func mentions(engine: TelegramEngine, postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, threadMessageId: MessageId?, searchQuery: String? = nil, requestUpdate: Bool = true, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) {