mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-30 07:50:03 +00:00
Merge commit '672cc0a3fe53dd515718bb6dd1fe21e454a786de'
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
C2366C871E4F403C0097CCFF /* AddressNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C851E4F403C0097CCFF /* AddressNames.swift */; };
|
||||
C2366C891E4F40480097CCFF /* SupportPeerId.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C881E4F40480097CCFF /* SupportPeerId.swift */; };
|
||||
C2366C8A1E4F40480097CCFF /* SupportPeerId.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C881E4F40480097CCFF /* SupportPeerId.swift */; };
|
||||
C239BE971E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift in Sources */ = {isa = PBXBuildFile; fileRef = C239BE961E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift */; };
|
||||
C239BE981E62F0D200C2C453 /* LoadMessagesIfNecessary.swift in Sources */ = {isa = PBXBuildFile; fileRef = C239BE961E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift */; };
|
||||
C239BE9C1E630CA700C2C453 /* UpdatePinnedMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C239BE9B1E630CA700C2C453 /* UpdatePinnedMessage.swift */; };
|
||||
C239BE9D1E630CB300C2C453 /* UpdatePinnedMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C239BE9B1E630CA700C2C453 /* UpdatePinnedMessage.swift */; };
|
||||
C26A37EF1E5E0C41006977AC /* ChannelParticipants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BB7C591E5C8074001527C3 /* ChannelParticipants.swift */; };
|
||||
C2A315C01E2E776A00D89000 /* RequestStartBot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01749581E1092BC0057C89A /* RequestStartBot.swift */; };
|
||||
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CFF1D62255C00955575 /* ChannelState.swift */; };
|
||||
@@ -413,6 +417,8 @@
|
||||
C2366C821E4F3EAA0097CCFF /* GroupReturnAndLeft.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupReturnAndLeft.swift; sourceTree = "<group>"; };
|
||||
C2366C851E4F403C0097CCFF /* AddressNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressNames.swift; sourceTree = "<group>"; };
|
||||
C2366C881E4F40480097CCFF /* SupportPeerId.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SupportPeerId.swift; sourceTree = "<group>"; };
|
||||
C239BE961E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadMessagesIfNecessary.swift; sourceTree = "<group>"; };
|
||||
C239BE9B1E630CA700C2C453 /* UpdatePinnedMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatePinnedMessage.swift; sourceTree = "<group>"; };
|
||||
D003702A1DA42586004308D3 /* PhoneNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhoneNumber.swift; sourceTree = "<group>"; };
|
||||
D00C7CCB1E3620C30080C3D5 /* CachedChannelParticipants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedChannelParticipants.swift; sourceTree = "<group>"; };
|
||||
D00C7CCE1E3628180080C3D5 /* UpdateCachedChannelParticipants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateCachedChannelParticipants.swift; sourceTree = "<group>"; };
|
||||
@@ -942,6 +948,7 @@
|
||||
D02ABC7A1E30058F00CAE539 /* DeleteMessagesInteractively.swift */,
|
||||
D0AAD1A91E32638500D5B9DE /* ApplyMaxReadIndexInteractively.swift */,
|
||||
D00C7CDF1E3785700080C3D5 /* MarkMessageContentAsConsumedInteractively.swift */,
|
||||
C239BE961E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift */,
|
||||
);
|
||||
name = Messages;
|
||||
sourceTree = "<group>";
|
||||
@@ -1081,6 +1088,7 @@
|
||||
D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */,
|
||||
D033FEB21E61F3C000644997 /* ReportPeer.swift */,
|
||||
D033FEB51E61F3F900644997 /* BlockedPeers.swift */,
|
||||
C239BE9B1E630CA700C2C453 /* UpdatePinnedMessage.swift */,
|
||||
);
|
||||
name = Peers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1403,6 +1411,7 @@
|
||||
D0BEAF5D1E54941B00BD963D /* Authorization.swift in Sources */,
|
||||
D0B843831DA6EDB8005F29E1 /* CachedGroupData.swift in Sources */,
|
||||
D0E35A121DE4A25E00BC6096 /* OutgoingChatContextResultMessageAttribute.swift in Sources */,
|
||||
C239BE9C1E630CA700C2C453 /* UpdatePinnedMessage.swift in Sources */,
|
||||
D0B844531DAC0773005F29E1 /* TelegramUserPresence.swift in Sources */,
|
||||
D0B843871DA6F705005F29E1 /* UpdateCachedPeerData.swift in Sources */,
|
||||
D03B0D6D1D631AA300955575 /* ContactManagement.swift in Sources */,
|
||||
@@ -1443,6 +1452,7 @@
|
||||
D03B0E441D631E6600955575 /* NetworkLogging.m in Sources */,
|
||||
D03121021DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift in Sources */,
|
||||
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */,
|
||||
C239BE971E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift in Sources */,
|
||||
D03B0CC11D62235000955575 /* StringFormat.swift in Sources */,
|
||||
D0B843C31DA7FF30005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
|
||||
C2366C861E4F403C0097CCFF /* AddressNames.swift in Sources */,
|
||||
@@ -1477,6 +1487,8 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C239BE9D1E630CB300C2C453 /* UpdatePinnedMessage.swift in Sources */,
|
||||
C239BE981E62F0D200C2C453 /* LoadMessagesIfNecessary.swift in Sources */,
|
||||
C26A37EF1E5E0C41006977AC /* ChannelParticipants.swift in Sources */,
|
||||
D050F26A1E4A5B6D00988324 /* ManagedGlobalNotificationSettings.swift in Sources */,
|
||||
D050F26B1E4A5B6D00988324 /* ApplyMaxReadIndexInteractively.swift in Sources */,
|
||||
|
||||
@@ -317,7 +317,7 @@ public func verifyPassword(_ account: UnauthorizedAccount, password: String) ->
|
||||
data.append(authData.currentSalt!)
|
||||
let currentPasswordHash = sha256(data)
|
||||
|
||||
return account.network.request(Api.functions.auth.checkPassword(passwordHash: Buffer(data: currentPasswordHash)))
|
||||
return account.network.request(Api.functions.auth.checkPassword(passwordHash: Buffer(data: currentPasswordHash)), automaticFloodWait: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -887,20 +887,6 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
|
||||
}
|
||||
}
|
||||
|
||||
private func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]] {
|
||||
var dict: [PeerId: [MessageId]] = [:]
|
||||
|
||||
for id in ids {
|
||||
let peerId = id.peerId
|
||||
if dict[peerId] == nil {
|
||||
dict[peerId] = [id]
|
||||
} else {
|
||||
dict[peerId]!.append(id)
|
||||
}
|
||||
}
|
||||
|
||||
return dict
|
||||
}
|
||||
|
||||
private func resolveAssociatedMessages(account: Account, state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
||||
let missingMessageIds = state.initialState.messageIds.subtracting(state.storedMessages)
|
||||
|
||||
@@ -87,3 +87,33 @@ public func addPeerMember(account: Account, peerId: PeerId, memberId: PeerId) ->
|
||||
}
|
||||
} |> mapError { _ -> AddPeerMemberError in return .generic } |> switchToLatest
|
||||
}
|
||||
|
||||
|
||||
public func addSupergroupMembers(account: Account, peerId: PeerId, memberIds: [PeerId]) -> Signal<Void, Void> {
|
||||
return account.postbox.modify { modifier -> Signal<Void, Void> in
|
||||
|
||||
var memberPeerIds:[PeerId:Peer] = [:]
|
||||
var inputUsers:[Api.InputUser] = []
|
||||
for memberId in memberIds {
|
||||
if let peer = modifier.getPeer(memberId) {
|
||||
memberPeerIds[peerId] = peer
|
||||
if let inputUser = apiInputUser(peer) {
|
||||
inputUsers.append(inputUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let peer = modifier.getPeer(peerId), let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
|
||||
return account.network.request(Api.functions.channels.inviteToChannel(channel: inputChannel, users: inputUsers))
|
||||
|> retryRequest
|
||||
|> mapToSignal { result -> Signal<Void, Void> in
|
||||
account.stateManager.addUpdates(result)
|
||||
return fetchAndUpdateCachedParticipants(peerId: peerId, network:account.network, postbox: account.postbox)
|
||||
}
|
||||
} else {
|
||||
return .fail()
|
||||
}
|
||||
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public func resendAuthorizationCode(account: UnauthorizedAccount) -> Signal<Void
|
||||
switch state.contents {
|
||||
case let .confirmationCodeEntry(number, _, hash, _, nextType):
|
||||
if nextType != nil {
|
||||
return account.network.request(Api.functions.auth.resendCode(phoneNumber: number, phoneCodeHash: hash))
|
||||
return account.network.request(Api.functions.auth.resendCode(phoneNumber: number, phoneCodeHash: hash), automaticFloodWait: false)
|
||||
|> mapError { error -> AuthorizationCodeRequestError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .limitExceeded
|
||||
|
||||
121
TelegramCore/LoadMessagesIfNecessary.swift
Normal file
121
TelegramCore/LoadMessagesIfNecessary.swift
Normal file
@@ -0,0 +1,121 @@
|
||||
import Foundation
|
||||
#if os(macOS)
|
||||
import PostboxMac
|
||||
import SwiftSignalKitMac
|
||||
import MtProtoKitMac
|
||||
#else
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
|
||||
public enum GetMessagesStrategy {
|
||||
case local
|
||||
case cloud
|
||||
}
|
||||
|
||||
public func getMessagesLoadIfNecessary(_ messageIds:[MessageId], postbox:Postbox, network:Network, strategy:GetMessagesStrategy = .cloud) -> Signal <[Message], Void> {
|
||||
|
||||
|
||||
let postboxSignal = postbox.modify { modifier -> ([Message], Set<MessageId>, SimpleDictionary<PeerId, Peer>) in
|
||||
var messages:[Message] = []
|
||||
var missingMessageIds:Set<MessageId> = Set()
|
||||
var supportPeers:SimpleDictionary<PeerId, Peer> = SimpleDictionary()
|
||||
for messageId in messageIds {
|
||||
if let message = modifier.getMessage(messageId) {
|
||||
messages.append(message)
|
||||
} else {
|
||||
missingMessageIds.insert(messageId)
|
||||
if let peer = modifier.getPeer(messageId.peerId) {
|
||||
supportPeers[messageId.peerId] = peer
|
||||
}
|
||||
}
|
||||
}
|
||||
return (messages, missingMessageIds, supportPeers)
|
||||
}
|
||||
|
||||
if strategy == .cloud {
|
||||
return postboxSignal |> mapToSignal { (existMessages, missingMessageIds, supportPeers) in
|
||||
|
||||
var signals: [Signal<([Api.Message], [Api.Chat], [Api.User]), NoError>] = []
|
||||
for (peerId, messageIds) in messagesIdsGroupedByPeerId(missingMessageIds) {
|
||||
if let peer = supportPeers[peerId] {
|
||||
var signal: Signal<Api.messages.Messages, MTRpcError>?
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
signal = network.request(Api.functions.messages.getMessages(id: messageIds.map({ $0.id })))
|
||||
} else if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let inputChannel = apiInputChannel(peer) {
|
||||
signal = network.request(Api.functions.channels.getMessages(channel: inputChannel, id: messageIds.map({ $0.id })))
|
||||
}
|
||||
}
|
||||
if let signal = signal {
|
||||
signals.append(signal |> map { result in
|
||||
switch result {
|
||||
case let .messages(messages, chats, users):
|
||||
return (messages, chats, users)
|
||||
case let .messagesSlice(_, messages, chats, users):
|
||||
return (messages, chats, users)
|
||||
case let .channelMessages(_, _, _, messages, chats, users):
|
||||
return (messages, chats, users)
|
||||
}
|
||||
} |> `catch` { _ in
|
||||
return Signal<([Api.Message], [Api.Chat], [Api.User]), NoError>.single(([], [], []))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return combineLatest(signals) |> mapToSignal { results -> Signal<[Message], Void> in
|
||||
|
||||
return postbox.modify { modifier -> [Message] in
|
||||
|
||||
for (messages, chats, users) in results {
|
||||
if !messages.isEmpty {
|
||||
var storeMessages: [StoreMessage] = []
|
||||
|
||||
for message in messages {
|
||||
if let message = StoreMessage(apiMessage: message) {
|
||||
storeMessages.append(message)
|
||||
}
|
||||
}
|
||||
_ = modifier.addMessages(storeMessages, location: .Random)
|
||||
}
|
||||
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
for chat in chats {
|
||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||
peers.append(groupOrChannel)
|
||||
}
|
||||
}
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
peers.append(telegramUser)
|
||||
if let presence = TelegramUserPresence(apiUser: user) {
|
||||
peerPresences[telegramUser.id] = presence
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(modifier: modifier, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
modifier.updatePeerPresences(peerPresences)
|
||||
}
|
||||
var loadedMessages:[Message] = []
|
||||
for messageId in missingMessageIds {
|
||||
if let message = modifier.getMessage(messageId) {
|
||||
loadedMessages.append(message)
|
||||
}
|
||||
}
|
||||
|
||||
return existMessages + loadedMessages
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
return postboxSignal |> map {$0.0}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,3 +56,19 @@ public extension Message {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]] {
|
||||
var dict: [PeerId: [MessageId]] = [:]
|
||||
|
||||
for id in ids {
|
||||
let peerId = id.peerId
|
||||
if dict[peerId] == nil {
|
||||
dict[peerId] = [id]
|
||||
} else {
|
||||
dict[peerId]!.append(id)
|
||||
}
|
||||
}
|
||||
|
||||
return dict
|
||||
}
|
||||
|
||||
63
TelegramCore/UpdatePinnedMessage.swift
Normal file
63
TelegramCore/UpdatePinnedMessage.swift
Normal file
@@ -0,0 +1,63 @@
|
||||
import Foundation
|
||||
#if os(macOS)
|
||||
import PostboxMac
|
||||
import SwiftSignalKitMac
|
||||
import MtProtoKitMac
|
||||
#else
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
public enum UpdatePinnedMessageError {
|
||||
case generic
|
||||
}
|
||||
|
||||
public func updatePinnedMessage(_ pinnedMessageId:MessageId?, silent:Bool = false, for peerId:PeerId, account:Account) -> Signal<Void, UpdatePinnedMessageError> {
|
||||
return account.postbox.modify { modifier -> Peer? in
|
||||
return modifier.getPeer(peerId)
|
||||
} |> mapError { () -> UpdatePinnedMessageError in
|
||||
return .generic
|
||||
} |> mapToSignal { peer -> Signal<Void, UpdatePinnedMessageError> in
|
||||
if let group = peer as? TelegramChannel {
|
||||
let canUpdate:Bool
|
||||
switch group.role {
|
||||
case .creator, .editor, .moderator:
|
||||
canUpdate = true
|
||||
default:
|
||||
canUpdate = false
|
||||
}
|
||||
|
||||
if canUpdate, let inputChannel = apiInputChannel(group) {
|
||||
|
||||
var flags:Int32 = 0
|
||||
let messageId:Int32 = pinnedMessageId?.id ?? 0
|
||||
if silent {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
|
||||
let request = Api.functions.channels.updatePinnedMessage(flags: flags, channel: inputChannel, id: messageId)
|
||||
|
||||
return account.network.request(request)
|
||||
|> mapError { _ -> UpdatePinnedMessageError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Void, UpdatePinnedMessageError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return account.postbox.modify { modifier in
|
||||
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||
if let current = current as? CachedChannelData {
|
||||
return current.withUpdatedPinnedMessageId(pinnedMessageId)
|
||||
} else {
|
||||
return current
|
||||
}
|
||||
})
|
||||
} |> mapError {_ -> UpdatePinnedMessageError in return .generic}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user