Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2021-02-20 15:56:09 +04:00
commit b19e3d3a66
8 changed files with 32512 additions and 32336 deletions

View File

@ -248,6 +248,7 @@ static void reportMemory() {
int32_t fileDatacenterId = 0; int32_t fileDatacenterId = 0;
Api1_InputFileLocation *inputFileLocation = nil; Api1_InputFileLocation *inputFileLocation = nil;
int32_t progressiveFileLimit = -1;
NSString *fetchResourceId = nil; NSString *fetchResourceId = nil;
bool isPng = false; bool isPng = false;
@ -257,14 +258,27 @@ static void reportMemory() {
if ([parsedAttachment isKindOfClass:[Api1_Photo_photo class]]) { if ([parsedAttachment isKindOfClass:[Api1_Photo_photo class]]) {
Api1_Photo_photo *photo = parsedAttachment; Api1_Photo_photo *photo = parsedAttachment;
isExpandableMedia = true; isExpandableMedia = true;
for (id size in photo.sizes) {
if ([size isKindOfClass:[Api1_PhotoSize_photoSize class]]) { /*for (id size in photo.sizes) {
Api1_PhotoSize_photoSize *sizeValue = size; if ([size isKindOfClass:[Api1_PhotoSize_photoSizeProgressive class]]) {
if ([sizeValue.type isEqualToString:@"m"]) { Api1_PhotoSize_photoSizeProgressive *sizeValue = size;
inputFileLocation = [Api1_InputFileLocation inputPhotoFileLocationWithPid:photo.pid accessHash:photo.accessHash fileReference:photo.fileReference thumbSize:sizeValue.type]; inputFileLocation = [Api1_InputFileLocation inputPhotoFileLocationWithPid:photo.pid accessHash:photo.accessHash fileReference:photo.fileReference thumbSize:sizeValue.type];
fileDatacenterId = [photo.dcId intValue]; fileDatacenterId = [photo.dcId intValue];
fetchResourceId = [NSString stringWithFormat:@"telegram-cloud-photo-size-%@-%@-%@", photo.dcId, photo.pid, sizeValue.type]; fetchResourceId = [NSString stringWithFormat:@"telegram-cloud-photo-size-%@-%@-%@", photo.dcId, photo.pid, sizeValue.type];
break; break;
}
}*/
if (inputFileLocation == nil) {
for (id size in photo.sizes) {
if ([size isKindOfClass:[Api1_PhotoSize_photoSize class]]) {
Api1_PhotoSize_photoSize *sizeValue = size;
if ([sizeValue.type isEqualToString:@"m"]) {
inputFileLocation = [Api1_InputFileLocation inputPhotoFileLocationWithPid:photo.pid accessHash:photo.accessHash fileReference:photo.fileReference thumbSize:sizeValue.type];
fileDatacenterId = [photo.dcId intValue];
fetchResourceId = [NSString stringWithFormat:@"telegram-cloud-photo-size-%@-%@-%@", photo.dcId, photo.pid, sizeValue.type];
break;
}
} }
} }
} }

View File

@ -279,7 +279,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1147422299] = { return Api.Update.parse_updatePeerHistoryTTL($0) } dict[-1147422299] = { return Api.Update.parse_updatePeerHistoryTTL($0) }
dict[1620733652] = { return Api.Update.parse_updateChatParticipant($0) } dict[1620733652] = { return Api.Update.parse_updateChatParticipant($0) }
dict[1708307556] = { return Api.Update.parse_updateChannelParticipant($0) } dict[1708307556] = { return Api.Update.parse_updateChannelParticipant($0) }
dict[820801212] = { return Api.Update.parse_updateBotStopped($0) } dict[133777546] = { return Api.Update.parse_updateBotStopped($0) }
dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) } dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
@ -620,6 +620,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1272375192] = { return Api.MessageMedia.parse_messageMediaPoll($0) } dict[1272375192] = { return Api.MessageMedia.parse_messageMediaPoll($0) }
dict[1065280907] = { return Api.MessageMedia.parse_messageMediaDice($0) } dict[1065280907] = { return Api.MessageMedia.parse_messageMediaDice($0) }
dict[-842892769] = { return Api.PaymentSavedCredentials.parse_paymentSavedCredentialsCard($0) } dict[-842892769] = { return Api.PaymentSavedCredentials.parse_paymentSavedCredentialsCard($0) }
dict[-1571952873] = { return Api.messages.CheckedHistoryImportPeer.parse_checkedHistoryImportPeer($0) }
dict[1923290508] = { return Api.auth.CodeType.parse_codeTypeSms($0) } dict[1923290508] = { return Api.auth.CodeType.parse_codeTypeSms($0) }
dict[1948046307] = { return Api.auth.CodeType.parse_codeTypeCall($0) } dict[1948046307] = { return Api.auth.CodeType.parse_codeTypeCall($0) }
dict[577556219] = { return Api.auth.CodeType.parse_codeTypeFlashCall($0) } dict[577556219] = { return Api.auth.CodeType.parse_codeTypeFlashCall($0) }
@ -1364,6 +1365,8 @@ public struct Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.PaymentSavedCredentials: case let _1 as Api.PaymentSavedCredentials:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.messages.CheckedHistoryImportPeer:
_1.serialize(buffer, boxed)
case let _1 as Api.auth.CodeType: case let _1 as Api.auth.CodeType:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.DocumentAttribute: case let _1 as Api.DocumentAttribute:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -181,42 +181,58 @@ public enum ChatHistoryImport {
} }
} }
public enum CheckPeerImportResult {
case allowed
case alert(String)
}
public enum CheckPeerImportError { public enum CheckPeerImportError {
case generic case generic
case chatAdminRequired
case invalidChatType
case userBlocked
case limitExceeded
case userIsNotMutualContact case userIsNotMutualContact
} }
public static func checkPeerImport(account: Account, peerId: PeerId) -> Signal<Never, CheckPeerImportError> { public static func checkPeerImport(account: Account, peerId: PeerId) -> Signal<CheckPeerImportResult, CheckPeerImportError> {
return account.postbox.transaction { transaction -> Peer? in return account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId) return transaction.getPeer(peerId)
} }
|> castError(CheckPeerImportError.self) |> castError(CheckPeerImportError.self)
|> mapToSignal { peer -> Signal<Never, CheckPeerImportError> in |> mapToSignal { peer -> Signal<CheckPeerImportResult, CheckPeerImportError> in
guard let peer = peer else { guard let peer = peer else {
return .fail(.generic) return .fail(.generic)
} }
if let inputUser = apiInputUser(peer) { guard let inputPeer = apiInputPeer(peer) else {
return account.network.request(Api.functions.users.getUsers(id: [inputUser])) return .fail(.generic)
|> mapError { _ -> CheckPeerImportError in }
return account.network.request(Api.functions.messages.checkHistoryImportPeer(peer: inputPeer))
|> mapError { error -> CheckPeerImportError in
if error.errorDescription == "CHAT_ADMIN_REQUIRED" {
return .chatAdminRequired
} else if error.errorDescription == "IMPORT_PEER_TYPE_INVALID" {
return .invalidChatType
} else if error.errorDescription == "USER_IS_BLOCKED" {
return .userBlocked
} else if error.errorDescription == "USER_NOT_MUTUAL_CONTACT" {
return .userBlocked
} else if error.errorDescription == "FLOOD_WAIT" {
return .limitExceeded
} else {
return .generic return .generic
} }
|> mapToSignal { result -> Signal<Never, CheckPeerImportError> in }
guard let apiUser = result.first else { |> map { result -> CheckPeerImportResult in
return .fail(.generic) switch result {
} case let .checkedHistoryImportPeer(confirmText):
switch apiUser { if confirmText.isEmpty {
case let .user(flags, _, _, _, _, _, _, _, _, _, _, _, _): return .allowed
if (flags & (1 << 12)) == 0 { } else {
// not mutual contact return .alert(confirmText)
return .fail(.userIsNotMutualContact)
}
return .complete()
case.userEmpty:
return .fail(.generic)
} }
} }
} else {
return .complete()
} }
} }
} }

View File

@ -679,18 +679,78 @@ public class ShareRootControllerImpl {
})]) })])
strongSelf.mainWindow?.present(controller, on: .root) strongSelf.mainWindow?.present(controller, on: .root)
} else { } else {
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 } controller.inProgress = true
let text: String let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id)
if let groupTitle = groupTitle { |> deliverOnMainQueue).start(next: { result in
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).0 controller.inProgress = false
} else {
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).0 let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { var errorText: String?
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: { if let channel = peer as? TelegramChannel {
beginWithPeer(peer.id) if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
})], parseMarkdown: true) } else {
strongSelf.mainWindow?.present(controller, on: .root) errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
}
} else if let group = peer as? TelegramGroup {
switch group.role {
case .creator:
break
default:
errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
}
} else if let _ = peer as? TelegramUser {
} else {
errorText = presentationData.strings.ChatImport_SelectionErrorGroupGeneric
}
if let errorText = errorText {
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
})])
strongSelf.mainWindow?.present(controller, on: .root)
} else {
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let text: String
switch result {
case .allowed:
if let groupTitle = groupTitle {
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).0
} else {
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).0
}
case let .alert(textValue):
text = textValue
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
beginWithPeer(peer.id)
})], parseMarkdown: true)
strongSelf.mainWindow?.present(controller, on: .root)
}
}, error: { error in
controller.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let errorText: String
switch error {
case .generic:
errorText = presentationData.strings.Login_UnknownError
case .chatAdminRequired:
errorText = presentationData.strings.ChatImportActivity_ErrorNotAdmin
case .invalidChatType:
errorText = presentationData.strings.ChatImportActivity_ErrorInvalidChatType
case .userBlocked:
errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
case .limitExceeded:
errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
case .userIsNotMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
})])
strongSelf.mainWindow?.present(controller, on: .root)
})
} }
} }
@ -772,7 +832,27 @@ public class ShareRootControllerImpl {
attemptSelectionImpl = { [weak controller] peer in attemptSelectionImpl = { [weak controller] peer in
controller?.inProgress = true controller?.inProgress = true
let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id) let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id)
|> deliverOnMainQueue).start(error: { error in |> deliverOnMainQueue).start(next: { result in
controller?.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let text: String
switch result {
case .allowed:
if let title = title {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
} else {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
}
case let .alert(textValue):
text = textValue
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
beginWithPeer(peer.id)
})], parseMarkdown: true)
strongSelf.mainWindow?.present(controller, on: .root)
}, error: { error in
controller?.inProgress = false controller?.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 } let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
@ -780,27 +860,20 @@ public class ShareRootControllerImpl {
switch error { switch error {
case .generic: case .generic:
errorText = presentationData.strings.Login_UnknownError errorText = presentationData.strings.Login_UnknownError
case .chatAdminRequired:
errorText = presentationData.strings.ChatImportActivity_ErrorNotAdmin
case .invalidChatType:
errorText = presentationData.strings.ChatImportActivity_ErrorInvalidChatType
case .userBlocked:
errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
case .limitExceeded:
errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
case .userIsNotMutualContact: case .userIsNotMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual errorText = presentationData.strings.ChatImport_UserErrorNotMutual
} }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
})]) })])
strongSelf.mainWindow?.present(controller, on: .root) strongSelf.mainWindow?.present(controller, on: .root)
}, completed: {
controller?.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let text: String
if let title = title {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
} else {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
beginWithPeer(peer.id)
})], parseMarkdown: true)
strongSelf.mainWindow?.present(controller, on: .root)
}) })
} }
@ -834,21 +907,7 @@ public class ShareRootControllerImpl {
attemptSelectionImpl = { [weak controller] peer in attemptSelectionImpl = { [weak controller] peer in
controller?.inProgress = true controller?.inProgress = true
let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id) let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id)
|> deliverOnMainQueue).start(error: { error in |> deliverOnMainQueue).start(next: { result in
controller?.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let errorText: String
switch error {
case .generic:
errorText = presentationData.strings.Login_UnknownError
case .userIsNotMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
})])
strongSelf.mainWindow?.present(controller, on: .root)
}, completed: {
controller?.inProgress = false controller?.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 } let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
@ -880,10 +939,15 @@ public class ShareRootControllerImpl {
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 } let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
if let user = peer as? TelegramUser { if let user = peer as? TelegramUser {
let text: String let text: String
if let title = peerTitle { switch result {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0 case .allowed:
} else { if let title = peerTitle {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0 text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
} else {
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
}
case let .alert(textValue):
text = textValue
} }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: { }), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
@ -892,10 +956,15 @@ public class ShareRootControllerImpl {
strongSelf.mainWindow?.present(controller, on: .root) strongSelf.mainWindow?.present(controller, on: .root)
} else { } else {
let text: String let text: String
if let groupTitle = peerTitle { switch result {
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).0 case .allowed:
} else { if let groupTitle = peerTitle {
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).0 text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).0
} else {
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).0
}
case let .alert(textValue):
text = textValue
} }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: { }), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
@ -904,6 +973,28 @@ public class ShareRootControllerImpl {
strongSelf.mainWindow?.present(controller, on: .root) strongSelf.mainWindow?.present(controller, on: .root)
} }
} }
}, error: { error in
controller?.inProgress = false
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
let errorText: String
switch error {
case .generic:
errorText = presentationData.strings.Login_UnknownError
case .chatAdminRequired:
errorText = presentationData.strings.ChatImportActivity_ErrorNotAdmin
case .invalidChatType:
errorText = presentationData.strings.ChatImportActivity_ErrorInvalidChatType
case .userBlocked:
errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
case .limitExceeded:
errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
case .userIsNotMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual
}
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
})])
strongSelf.mainWindow?.present(controller, on: .root)
}) })
} }