mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-02-01 08:45:48 +00:00
Merge commit '05ad028aa3495bed3af10212777bfc1986d3d295'
This commit is contained in:
@@ -7,6 +7,12 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
C2366C831E4F3EAA0097CCFF /* GroupReturnAndLeft.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C821E4F3EAA0097CCFF /* GroupReturnAndLeft.swift */; };
|
||||
C2366C841E4F3EAA0097CCFF /* GroupReturnAndLeft.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C821E4F3EAA0097CCFF /* GroupReturnAndLeft.swift */; };
|
||||
C2366C861E4F403C0097CCFF /* UsernameAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C851E4F403C0097CCFF /* UsernameAvailability.swift */; };
|
||||
C2366C871E4F403C0097CCFF /* UsernameAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C851E4F403C0097CCFF /* UsernameAvailability.swift */; };
|
||||
C2366C891E4F40480097CCFF /* SupportPeerId.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C881E4F40480097CCFF /* SupportPeerId.swift */; };
|
||||
C2366C8A1E4F40480097CCFF /* SupportPeerId.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2366C881E4F40480097CCFF /* SupportPeerId.swift */; };
|
||||
C2A315C01E2E776A00D89000 /* RequestStartBot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01749581E1092BC0057C89A /* RequestStartBot.swift */; };
|
||||
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CFF1D62255C00955575 /* ChannelState.swift */; };
|
||||
D001F3E91E128A1C007A8C60 /* SecretChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0177B7A1DF8A16C00A5083A /* SecretChatState.swift */; };
|
||||
@@ -372,6 +378,9 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
C2366C821E4F3EAA0097CCFF /* GroupReturnAndLeft.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupReturnAndLeft.swift; sourceTree = "<group>"; };
|
||||
C2366C851E4F403C0097CCFF /* UsernameAvailability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UsernameAvailability.swift; sourceTree = "<group>"; };
|
||||
C2366C881E4F40480097CCFF /* SupportPeerId.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SupportPeerId.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>"; };
|
||||
@@ -997,6 +1006,9 @@
|
||||
D0BC387A1E40D2880044D6FE /* TogglePeerChatPinned.swift */,
|
||||
D049EAEA1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift */,
|
||||
D050F2501E4A59C200988324 /* JoinLink.swift */,
|
||||
C2366C821E4F3EAA0097CCFF /* GroupReturnAndLeft.swift */,
|
||||
C2366C851E4F403C0097CCFF /* UsernameAvailability.swift */,
|
||||
C2366C881E4F40480097CCFF /* SupportPeerId.swift */,
|
||||
);
|
||||
name = Peers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1225,6 +1237,7 @@
|
||||
D073CE601DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift in Sources */,
|
||||
D03B0D6B1D631A9D00955575 /* Phonebook.swift in Sources */,
|
||||
D0AAD1A81E32602500D5B9DE /* AutoremoveTimeoutMessageAttribute.swift in Sources */,
|
||||
C2366C831E4F3EAA0097CCFF /* GroupReturnAndLeft.swift in Sources */,
|
||||
D03B0D3D1D6319E200955575 /* Fetch.swift in Sources */,
|
||||
D0DF0C931D81AD09008AEB01 /* MessageUtils.swift in Sources */,
|
||||
D03B0D681D631A8B00955575 /* RecentPeers.swift in Sources */,
|
||||
@@ -1271,6 +1284,7 @@
|
||||
D0E35A101DE49E1C00BC6096 /* OutgoingMessageWithChatContextResult.swift in Sources */,
|
||||
D049EAD81E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
|
||||
D0448C991E268F9A005A61A7 /* SecretApiLayer46.swift in Sources */,
|
||||
C2366C891E4F40480097CCFF /* SupportPeerId.swift in Sources */,
|
||||
D003702B1DA42586004308D3 /* PhoneNumber.swift in Sources */,
|
||||
D03B0CF91D62250800955575 /* TelegramMediaMap.swift in Sources */,
|
||||
D0BC38791E40BAF20044D6FE /* SynchronizePinnedChatsOperation.swift in Sources */,
|
||||
@@ -1346,6 +1360,7 @@
|
||||
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */,
|
||||
D03B0CC11D62235000955575 /* StringFormat.swift in Sources */,
|
||||
D0B843C31DA7FF30005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
|
||||
C2366C861E4F403C0097CCFF /* UsernameAvailability.swift in Sources */,
|
||||
D0B843C11DA7FF30005F29E1 /* NBPhoneMetaData.m in Sources */,
|
||||
D0FA8BA41E1FA341001E855B /* SecretChatKeychain.swift in Sources */,
|
||||
D01749601E118FC30057C89A /* AccountIntermediateState.swift in Sources */,
|
||||
@@ -1396,6 +1411,7 @@
|
||||
D00D97CB1E32917C00E5C2B6 /* PeerInputActivityManager.swift in Sources */,
|
||||
D0B844491DAB91FD005F29E1 /* ManagedChatListHoles.swift in Sources */,
|
||||
D03C53711DAD5CA9004C17B3 /* CachedGroupParticipants.swift in Sources */,
|
||||
C2366C841E4F3EAA0097CCFF /* GroupReturnAndLeft.swift in Sources */,
|
||||
D03C53671DAD5CA9004C17B3 /* ApiUtils.swift in Sources */,
|
||||
D0AAD1B91E326FE200D5B9DE /* ManagedAutoremoveMessageOperations.swift in Sources */,
|
||||
D001F3F21E128A1C007A8C60 /* UpdateGroup.swift in Sources */,
|
||||
@@ -1442,6 +1458,7 @@
|
||||
D0448C8F1E22993C005A61A7 /* ProcessSecretChatIncomingDecryptedOperations.swift in Sources */,
|
||||
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
||||
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */,
|
||||
C2366C8A1E4F40480097CCFF /* SupportPeerId.swift in Sources */,
|
||||
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
|
||||
D050F2601E4A5AD500988324 /* AutoremoveTimeoutMessageAttribute.swift in Sources */,
|
||||
D049EAD91E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
|
||||
@@ -1517,6 +1534,7 @@
|
||||
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
|
||||
D001F3F51E128A1C007A8C60 /* PendingMessageManager.swift in Sources */,
|
||||
D001F3F61E128A1C007A8C60 /* PendingMessageUploadedContent.swift in Sources */,
|
||||
C2366C871E4F403C0097CCFF /* UsernameAvailability.swift in Sources */,
|
||||
D02ABC7F1E3109F000CAE539 /* CloudChatRemoveMessagesOperation.swift in Sources */,
|
||||
D0FA8BA51E1FA341001E855B /* SecretChatKeychain.swift in Sources */,
|
||||
D0F7B1E71E045C87007EB8A5 /* JoinChannel.swift in Sources */,
|
||||
|
||||
46
TelegramCore/GroupReturnAndLeft.swift
Normal file
46
TelegramCore/GroupReturnAndLeft.swift
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
#if os(macOS)
|
||||
import PostboxMac
|
||||
import SwiftSignalKitMac
|
||||
import MtProtoKitMac
|
||||
#else
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
|
||||
public func returnGroup(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
||||
return account.postbox.loadedPeerWithId(account.peerId)
|
||||
|> take(1)
|
||||
|> mapToSignal { peer -> Signal<Void, NoError> in
|
||||
if let inputUser = apiInputUser(peer) {
|
||||
return account.network.request(Api.functions.messages.addChatUser(chatId: peerId.id, userId: inputUser, fwdLimit: 50))
|
||||
|> retryRequest
|
||||
|> mapToSignal { updates -> Signal<Void, NoError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func leftGroup(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
||||
return account.postbox.loadedPeerWithId(account.peerId)
|
||||
|> take(1)
|
||||
|> mapToSignal { peer -> Signal<Void, NoError> in
|
||||
if let inputUser = apiInputUser(peer) {
|
||||
return account.network.request(Api.functions.messages .deleteChatUser(chatId: peerId.id, userId: inputUser))
|
||||
|> retryRequest
|
||||
|> mapToSignal { updates -> Signal<Void, NoError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
TelegramCore/SupportPeerId.swift
Normal file
34
TelegramCore/SupportPeerId.swift
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
#if os(macOS)
|
||||
import PostboxMac
|
||||
import SwiftSignalKitMac
|
||||
import MtProtoKitMac
|
||||
#else
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
|
||||
public func supportPeerId(account:Account) -> Signal<PeerId?, Void> {
|
||||
return account.network.request(Api.functions.help.getSupport())
|
||||
|> map { Optional($0) }
|
||||
|> `catch` { _ in
|
||||
return Signal<Api.help.Support?, NoError>.single(nil)
|
||||
}
|
||||
|> mapToSignal { support -> Signal<PeerId?, NoError> in
|
||||
if let support = support {
|
||||
switch support {
|
||||
case let .support(phoneNumber: _, user: user):
|
||||
let user = TelegramUser(user: user)
|
||||
return account.postbox.modify { modifier -> PeerId in
|
||||
updatePeers(modifier: modifier, peers: [user], update: { (previous, updated) -> Peer? in
|
||||
return updated
|
||||
})
|
||||
return user.id
|
||||
}
|
||||
}
|
||||
}
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
179
TelegramCore/UsernameAvailability.swift
Normal file
179
TelegramCore/UsernameAvailability.swift
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
#if os(macOS)
|
||||
import PostboxMac
|
||||
import SwiftSignalKitMac
|
||||
import MtProtoKitMac
|
||||
#else
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
|
||||
public enum UsernameAvailabilityError {
|
||||
case underscopeStart
|
||||
case underscopeEnd
|
||||
case digitStart
|
||||
case invalid
|
||||
case short
|
||||
case alreadyTaken
|
||||
}
|
||||
|
||||
public enum UsernameAvailabilityState : Equatable {
|
||||
case none(username: String?)
|
||||
case success(username: String?)
|
||||
case progress(username: String?)
|
||||
case fail(username: String?, error: UsernameAvailabilityError)
|
||||
|
||||
public var username:String? {
|
||||
switch self {
|
||||
case let .none(username:username):
|
||||
return username
|
||||
case let .success(username:username):
|
||||
return username
|
||||
case let .progress(username:username):
|
||||
return username
|
||||
case let .fail(fail):
|
||||
return fail.username
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public func ==(lhs:UsernameAvailabilityState, rhs:UsernameAvailabilityState) -> Bool {
|
||||
switch lhs {
|
||||
case let .none(username:lhsName):
|
||||
if case let .none(username:rhsName) = rhs, lhsName == rhsName {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case let .success(username:lhsName):
|
||||
if case let .success(username:rhsName) = rhs, lhsName == rhsName {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case let .progress(username:lhsName):
|
||||
if case let .progress(username:rhsName) = rhs, lhsName == rhsName {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case let .fail(lhsText):
|
||||
if case let .fail(rhsText) = rhs, lhsText.error == rhsText.error && lhsText.username == rhsText.username {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func usernameAvailability(account:Account, def:String?, current:String) -> Signal<UsernameAvailabilityState,Void> {
|
||||
|
||||
return Signal { subscriber in
|
||||
|
||||
let none = { () -> Disposable in
|
||||
subscriber.putNext(.none(username: current))
|
||||
subscriber.putCompletion()
|
||||
return EmptyDisposable
|
||||
}
|
||||
|
||||
let success = { () -> Disposable in
|
||||
subscriber.putNext(.success(username: current))
|
||||
subscriber.putCompletion()
|
||||
return EmptyDisposable
|
||||
}
|
||||
|
||||
let fail:(UsernameAvailabilityError)->Disposable = { (value) -> Disposable in
|
||||
subscriber.putNext(.fail(username: current, error:value))
|
||||
subscriber.putCompletion()
|
||||
return EmptyDisposable
|
||||
}
|
||||
|
||||
if def == current {
|
||||
return success()
|
||||
}
|
||||
|
||||
for char in current.characters {
|
||||
if char == "_" {
|
||||
if char == current.characters.first {
|
||||
return fail(.underscopeStart);
|
||||
} else if char == current.characters.last {
|
||||
return fail(current.characters.count < 5 ? .short : .underscopeEnd);
|
||||
}
|
||||
|
||||
}
|
||||
if char == current.characters.first && char >= "0" && char <= "9" {
|
||||
return fail(.digitStart);
|
||||
}
|
||||
if (!((char >= "a" && char <= "z") || (char >= "A" && char <= "Z") || (char >= "0" && char <= "9"))) {
|
||||
return fail(.invalid);
|
||||
}
|
||||
}
|
||||
|
||||
if current.characters.count < 5 {
|
||||
if current.isEmpty {
|
||||
return none()
|
||||
}
|
||||
return fail(.short)
|
||||
}
|
||||
|
||||
|
||||
subscriber.putNext(.progress(username: current))
|
||||
|
||||
let disposable:Disposable
|
||||
|
||||
let req = account.network.request(Api.functions.account.checkUsername(username: current)) |> delay(0.3, queue: Queue.concurrentDefaultQueue()) |> map {result in
|
||||
switch result {
|
||||
case .boolFalse:
|
||||
return .fail(username: current, error:.alreadyTaken)
|
||||
case .boolTrue:
|
||||
return .success(username: current)
|
||||
}
|
||||
}
|
||||
|> `catch` { error -> Signal<UsernameAvailabilityState, MTRpcError> in
|
||||
return Signal <UsernameAvailabilityState,MTRpcError> { subscriber in
|
||||
subscriber.putNext(.fail(username: current, error:.invalid))
|
||||
subscriber.putCompletion()
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
|> retryRequest
|
||||
|
||||
|
||||
disposable = req.start(next: { (status) in
|
||||
subscriber.putNext(status)
|
||||
}, completed:{
|
||||
subscriber.putCompletion()
|
||||
})
|
||||
|
||||
return disposable
|
||||
}
|
||||
}
|
||||
|
||||
public func updateUsername(account:Account, username:String) -> Signal<Bool,Void> {
|
||||
|
||||
return account.network.request(Api.functions.account.updateUsername(username: username)) |> map { result in
|
||||
return TelegramUser(user: result)
|
||||
}
|
||||
|> `catch` { error -> Signal<TelegramUser?, MTRpcError> in
|
||||
return Signal <TelegramUser?,MTRpcError> { subscriber in
|
||||
subscriber.putNext(nil)
|
||||
subscriber.putCompletion()
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
|> retryRequest
|
||||
|> mapToSignal({ (user) -> Signal<Bool, Void> in
|
||||
if let user = user {
|
||||
return account.postbox.modify { modifier -> Void in
|
||||
updatePeers(modifier: modifier, peers: [user], update: { (previous, updated) -> Peer? in
|
||||
return updated
|
||||
})
|
||||
} |> map({true})
|
||||
} else {
|
||||
return .single(false)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user