mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-06 13:12:49 +00:00
Fixed peers nearby updates
This commit is contained in:
@@ -19,8 +19,6 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlackIcon</string>
|
||||
<string>BlackIconIpad</string>
|
||||
<string>BlackIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
@@ -30,8 +28,6 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlackClassicIcon</string>
|
||||
<string>BlackClassicIconIpad</string>
|
||||
<string>BlackClassicIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
@@ -41,8 +37,6 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlackFilledIcon</string>
|
||||
<string>BlackFilledIconIpad</string>
|
||||
<string>BlackFilledIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
@@ -52,8 +46,6 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlueIcon</string>
|
||||
<string>BlueIconIpad</string>
|
||||
<string>BlueIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
@@ -63,8 +55,6 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlueClassicIcon</string>
|
||||
<string>BlueClassicIconIpad</string>
|
||||
<string>BlueClassicIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
@@ -74,8 +64,6 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlueFilledIcon</string>
|
||||
<string>BlueFilledIconIpad</string>
|
||||
<string>BlueFilledIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
@@ -98,6 +86,88 @@
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict>
|
||||
<key>CFBundleAlternateIcons</key>
|
||||
<dict>
|
||||
<key>Black</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlackIconIpad</string>
|
||||
<string>BlackIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>BlackClassic</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlackClassicIconIpad</string>
|
||||
<string>BlackClassicIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>BlackFilled</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlackFilledIconIpad</string>
|
||||
<string>BlackFilledIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Blue</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlueIconIpad</string>
|
||||
<string>BlueIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>BlueClassic</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlueClassicIconIpad</string>
|
||||
<string>BlueClassicIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>BlueFilled</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>BlueFilledIconIpad</string>
|
||||
<string>BlueFilledIconLargeIpad</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>WhiteFilled</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>WhiteFilledIcon</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIconLLC</string>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
|
||||
@@ -13,18 +13,24 @@ public struct PeerNearby {
|
||||
public let distance: Int32
|
||||
}
|
||||
|
||||
public func peersNearby(network: Network, accountStateManager: AccountStateManager, coordinate: (latitude: Double, longitude: Double)) -> Signal<[PeerNearby], NoError> {
|
||||
let inputGeoPoint = Api.InputGeoPoint.inputGeoPoint(lat: coordinate.latitude, long: coordinate.longitude)
|
||||
public final class PeersNearbyContext {
|
||||
private let queue: Queue = Queue.mainQueue()
|
||||
private var subscribers = Bag<([PeerNearby]) -> Void>()
|
||||
private let disposable = MetaDisposable()
|
||||
private var timer: SwiftSignalKit.Timer?
|
||||
|
||||
return network.request(Api.functions.contacts.getLocated(geoPoint: inputGeoPoint))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { updates in
|
||||
var peersNearby: [PeerNearby] = []
|
||||
if let updates = updates {
|
||||
switch updates {
|
||||
private var entries: [PeerNearby] = []
|
||||
|
||||
public init(network: Network, accountStateManager: AccountStateManager, coordinate: (latitude: Double, longitude: Double)) {
|
||||
self.disposable.set((network.request(Api.functions.contacts.getLocated(geoPoint: .inputGeoPoint(lat: coordinate.latitude, long: coordinate.longitude)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<[PeerNearby], NoError> in
|
||||
var peersNearby: [PeerNearby] = []
|
||||
if let updates = updates {
|
||||
switch updates {
|
||||
case let .updates(updates, _, _, _, _):
|
||||
for update in updates {
|
||||
if case let .updatePeerLocated(peers) = update {
|
||||
@@ -35,13 +41,77 @@ public func peersNearby(network: Network, accountStateManager: AccountStateManag
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
accountStateManager.addUpdates(updates)
|
||||
}
|
||||
return .single(peersNearby)
|
||||
|> then(accountStateManager.updatedPeersNearby())
|
||||
}).start(next: { [weak self] updatedEntries in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
accountStateManager.addUpdates(updates)
|
||||
}
|
||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||
var entries = strongSelf.entries.filter { Double($0.expires) > timestamp }
|
||||
let updatedEntries = updatedEntries.filter { Double($0.expires) > timestamp }
|
||||
|
||||
var existingPeerIds: [PeerId: Int] = [:]
|
||||
for i in 0 ..< entries.count {
|
||||
existingPeerIds[entries[i].id] = i
|
||||
}
|
||||
|
||||
for entry in updatedEntries {
|
||||
if let index = existingPeerIds[entry.id] {
|
||||
entries[index] = entry
|
||||
} else {
|
||||
entries.append(entry)
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.entries = entries
|
||||
|
||||
for subscriber in strongSelf.subscribers.copyItems() {
|
||||
subscriber(strongSelf.entries)
|
||||
}
|
||||
}))
|
||||
|
||||
return .single(peersNearby)
|
||||
|> then(accountStateManager.updatedPeersNearby())
|
||||
self.timer = SwiftSignalKit.Timer(timeout: 5.0, repeat: true, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||
strongSelf.entries = strongSelf.entries.filter { Double($0.expires) > timestamp }
|
||||
}, queue: self.queue)
|
||||
self.timer?.start()
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable.dispose()
|
||||
self.timer?.invalidate()
|
||||
}
|
||||
|
||||
public func get() -> Signal<[PeerNearby], NoError> {
|
||||
let queue = self.queue
|
||||
return Signal { [weak self] subscriber in
|
||||
if let strongSelf = self {
|
||||
subscriber.putNext(strongSelf.entries)
|
||||
|
||||
let index = strongSelf.subscribers.add({ entries in
|
||||
subscriber.putNext(entries)
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
queue.async {
|
||||
if let strongSelf = self {
|
||||
strongSelf.subscribers.remove(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return EmptyDisposable
|
||||
}
|
||||
} |> runOn(queue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -468,7 +468,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
||||
entries.append(.transfer(presentationData.theme, isGroup ? presentationData.strings.Group_EditAdmin_TransferOwnership : presentationData.strings.Channel_EditAdmin_TransferOwnership))
|
||||
}
|
||||
|
||||
if let initialParticipant = initialParticipant, case let .member(participant) = initialParticipant, let adminInfo = participant.adminInfo, !adminInfo.rights.flags.isEmpty {
|
||||
if let initialParticipant = initialParticipant, case let .member(participant) = initialParticipant, let adminInfo = participant.adminInfo, !adminInfo.rights.flags.isEmpty && admin.id != accountPeerId {
|
||||
var canDismiss = false
|
||||
if channel.flags.contains(.isCreator) {
|
||||
canDismiss = true
|
||||
@@ -538,7 +538,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
||||
entries.append(.transfer(presentationData.theme, presentationData.strings.Group_EditAdmin_TransferOwnership))
|
||||
}
|
||||
|
||||
if let initialParticipant = initialParticipant, case let .member(participant) = initialParticipant, let adminInfo = participant.adminInfo, !adminInfo.rights.flags.isEmpty {
|
||||
if let initialParticipant = initialParticipant, case let .member(participant) = initialParticipant, let adminInfo = participant.adminInfo, !adminInfo.rights.flags.isEmpty && admin.id != accountPeerId {
|
||||
entries.append(.dismiss(presentationData.theme, presentationData.strings.Channel_Moderator_AccessLevelRevoke))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ public func channelAdminsController(context: AccountContext, peerId: PeerId, loa
|
||||
guard let peer = peer, let user = user else {
|
||||
return
|
||||
}
|
||||
presentControllerImpl?(UndoOverlayController(context: context, content: .succeed(text: presentationData.strings.Channel_OwnershipTransfer_TransferCompleted(peer.displayTitle, user.displayTitle).0), elevatedLayout: false, action: { _ in }), nil)
|
||||
presentControllerImpl?(UndoOverlayController(context: context, content: .succeed(text: presentationData.strings.Channel_OwnershipTransfer_TransferCompleted(user.displayTitle, peer.displayTitle).0), elevatedLayout: false, action: { _ in }), nil)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -410,6 +410,10 @@ private func commitChannelOwnershipTransferController(context: AccountContext, p
|
||||
proceedImpl?()
|
||||
})])
|
||||
|
||||
contentNode.complete = {
|
||||
proceedImpl?()
|
||||
}
|
||||
|
||||
let controller = AlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), contentNode: contentNode)
|
||||
let presentationDataDisposable = context.sharedContext.presentationData.start(next: { [weak controller, weak contentNode] presentationData in
|
||||
controller?.theme = AlertControllerTheme(presentationTheme: presentationData.theme)
|
||||
|
||||
@@ -105,7 +105,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
self.consumableContentNode = ASImageNode()
|
||||
|
||||
super.init()
|
||||
|
||||
self.backgroundColor = UIColor.red.withAlphaComponent(0.5)
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.descriptionNode)
|
||||
self.addSubnode(self.fetchingTextNode)
|
||||
@@ -489,6 +489,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
if hasStreamingProgress {
|
||||
fittedLayoutSize.width += streamingProgressDiameter + 6.0
|
||||
}
|
||||
fittedLayoutSize.width = max(fittedLayoutSize.width, boundingWidth + 2.0)
|
||||
} else {
|
||||
streamingCacheStatusFrame = CGRect()
|
||||
}
|
||||
@@ -633,8 +634,6 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private func updateStatus(animated: Bool) {
|
||||
|
||||
|
||||
guard let resourceStatus = self.resourceStatus else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ final class PeerPresenceStatusManager {
|
||||
}
|
||||
|
||||
func reset(presence: TelegramUserPresence) {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
self.timer?.invalidate()
|
||||
self.timer = nil
|
||||
|
||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||
let timeout = userPresenceStringRefreshTimeout(presence, relativeTo: Int32(timestamp))
|
||||
|
||||
@@ -305,28 +305,39 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
guard let coordinate = coordinate else {
|
||||
return .single(nil)
|
||||
}
|
||||
let poll = peersNearby(network: context.account.network, accountStateManager: context.account.stateManager, coordinate: (latitude: coordinate.latitude, longitude: coordinate.longitude))
|
||||
|> mapToSignal { peersNearby -> Signal<PeersNearbyData?, NoError> in
|
||||
return context.account.postbox.transaction { transaction -> PeersNearbyData? in
|
||||
var users: [PeerNearbyEntry] = []
|
||||
var groups: [PeerNearbyEntry] = []
|
||||
for peerNearby in peersNearby {
|
||||
if peerNearby.id != context.account.peerId, let peer = transaction.getPeer(peerNearby.id) {
|
||||
if peerNearby.id.namespace == Namespaces.Peer.CloudUser {
|
||||
users.append(PeerNearbyEntry(peer: (peer, nil), expires: peerNearby.expires, distance: peerNearby.distance))
|
||||
} else {
|
||||
let cachedData = transaction.getPeerCachedData(peerId: peerNearby.id) as? CachedChannelData
|
||||
groups.append(PeerNearbyEntry(peer: (peer, cachedData), expires: peerNearby.expires, distance: peerNearby.distance))
|
||||
|
||||
return Signal { subscriber in
|
||||
let peersNearbyContext = PeersNearbyContext(network: context.account.network, accountStateManager: context.account.stateManager, coordinate: (latitude: coordinate.latitude, longitude: coordinate.longitude))
|
||||
|
||||
let disposable = (peersNearbyContext.get()
|
||||
|> mapToSignal { peersNearby -> Signal<PeersNearbyData?, NoError> in
|
||||
return context.account.postbox.transaction { transaction -> PeersNearbyData? in
|
||||
var users: [PeerNearbyEntry] = []
|
||||
var groups: [PeerNearbyEntry] = []
|
||||
for peerNearby in peersNearby {
|
||||
if peerNearby.id != context.account.peerId, let peer = transaction.getPeer(peerNearby.id) {
|
||||
if peerNearby.id.namespace == Namespaces.Peer.CloudUser {
|
||||
users.append(PeerNearbyEntry(peer: (peer, nil), expires: peerNearby.expires, distance: peerNearby.distance))
|
||||
} else {
|
||||
let cachedData = transaction.getPeerCachedData(peerId: peerNearby.id) as? CachedChannelData
|
||||
groups.append(PeerNearbyEntry(peer: (peer, cachedData), expires: peerNearby.expires, distance: peerNearby.distance))
|
||||
}
|
||||
}
|
||||
}
|
||||
return PeersNearbyData(users: users, groups: groups, channels: [])
|
||||
}
|
||||
return PeersNearbyData(users: users, groups: groups, channels: [])
|
||||
}).start(next: { data in
|
||||
subscriber.putNext(data)
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
disposable.dispose()
|
||||
let _ = peersNearbyContext.get()
|
||||
}
|
||||
}
|
||||
return (poll |> then(.complete() |> suspendAwareDelay(25.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||
}
|
||||
|
||||
dataPromise.set(dataSignal)
|
||||
dataPromise.set((dataSignal |> then(.complete() |> suspendAwareDelay(25.0, queue: Queue.concurrentDefaultQueue()))) |> restart)
|
||||
|
||||
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), dataPromise.get())
|
||||
|> deliverOnMainQueue
|
||||
|
||||
Reference in New Issue
Block a user