diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index f523a1e944..36216f995c 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -818,9 +818,9 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId, } let peersDisablingAddressNameAssignment = Promise<[Peer]?>() - peersDisablingAddressNameAssignment.set(.single(nil) |> then(channelAddressNameAssignmentAvailability(account: context.account, peerId: peerId.namespace == Namespaces.Peer.CloudChannel ? peerId : nil) |> mapToSignal { result -> Signal<[Peer]?, NoError> in + peersDisablingAddressNameAssignment.set(.single(nil) |> then(context.engine.peerNames.channelAddressNameAssignmentAvailability(peerId: peerId.namespace == Namespaces.Peer.CloudChannel ? peerId : nil) |> mapToSignal { result -> Signal<[Peer]?, NoError> in if case .addressNameLimitReached = result { - return adminedPublicChannels(account: context.account, scope: .all) + return context.engine.peerNames.adminedPublicChannels(scope: .all) |> map(Optional.init) } else { return .single([]) @@ -871,7 +871,7 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId, return state.withUpdatedEditingPublicLinkText(text) } - checkAddressNameDisposable.set((validateAddressNameInteractive(account: context.account, domain: .peer(peerId), name: text) + checkAddressNameDisposable.set((context.engine.peerNames.validateAddressNameInteractive(domain: .peer(peerId), name: text) |> deliverOnMainQueue).start(next: { result in updateState { state in return state.withUpdatedAddressNameValidationStatus(result) @@ -893,7 +893,7 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId, return state.withUpdatedRevokingPeerId(peerId) } - revokeAddressNameDisposable.set((updateAddressName(account: context.account, domain: .peer(peerId), name: nil) |> deliverOnMainQueue).start(error: { _ in + revokeAddressNameDisposable.set((context.engine.peerNames.updateAddressName(domain: .peer(peerId), name: nil) |> deliverOnMainQueue).start(error: { _ in updateState { state in return state.withUpdatedRevokingPeerId(nil) } @@ -1101,7 +1101,7 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId, } _ = ApplicationSpecificNotice.markAsSeenSetPublicChannelLink(accountManager: context.sharedContext.accountManager).start() - updateAddressNameDisposable.set((updateAddressName(account: context.account, domain: .peer(peerId), name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) |> timeout(10, queue: Queue.mainQueue(), alternate: .fail(.generic)) + updateAddressNameDisposable.set((context.engine.peerNames.updateAddressName(domain: .peer(peerId), name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) |> timeout(10, queue: Queue.mainQueue(), alternate: .fail(.generic)) |> deliverOnMainQueue).start(error: { _ in updateState { state in return state.withUpdatedUpdatingAddressName(false) @@ -1173,7 +1173,7 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId, let signal = convertGroupToSupergroup(account: context.account, peerId: peerId) |> mapToSignal { upgradedPeerId -> Signal in - return updateAddressName(account: context.account, domain: .peer(upgradedPeerId), name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) + return context.engine.peerNames.updateAddressName(domain: .peer(upgradedPeerId), name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) |> `catch` { _ -> Signal in return .complete() } diff --git a/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift b/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift index 54f8184c47..4296059d10 100644 --- a/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift +++ b/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift @@ -512,7 +512,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController { cancelImpl = { checkCreationAvailabilityDisposable.set(nil) } - checkCreationAvailabilityDisposable.set((checkPublicChannelCreationAvailability(account: context.account, location: true) + checkCreationAvailabilityDisposable.set((context.engine.peerNames.checkPublicChannelCreationAvailability(location: true) |> afterDisposed { Queue.mainQueue().async { progressDisposable.dispose() diff --git a/submodules/SettingsUI/Sources/UsernameSetupController.swift b/submodules/SettingsUI/Sources/UsernameSetupController.swift index cede57928c..abeabcbc0e 100644 --- a/submodules/SettingsUI/Sources/UsernameSetupController.swift +++ b/submodules/SettingsUI/Sources/UsernameSetupController.swift @@ -260,7 +260,7 @@ public func usernameSetupController(context: AccountContext) -> ViewController { return state.withUpdatedEditingPublicLinkText(text) } - checkAddressNameDisposable.set((validateAddressNameInteractive(account: context.account, domain: .account, name: text) + checkAddressNameDisposable.set((context.engine.peerNames.validateAddressNameInteractive(domain: .account, name: text) |> deliverOnMainQueue).start(next: { result in updateState { state in return state.withUpdatedAddressNameValidationStatus(result) @@ -325,7 +325,7 @@ public func usernameSetupController(context: AccountContext) -> ViewController { } if let updatedAddressNameValue = updatedAddressNameValue { - updateAddressNameDisposable.set((updateAddressName(account: context.account, domain: .account, name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) + updateAddressNameDisposable.set((context.engine.peerNames.updateAddressName(domain: .account, name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) |> deliverOnMainQueue).start(error: { _ in updateState { state in return state.withUpdatedUpdatingAddressName(false) diff --git a/submodules/TelegramCore/Sources/AddPeerMember.swift b/submodules/TelegramCore/Sources/AddPeerMember.swift index 5edaa1c553..cd8654b78a 100644 --- a/submodules/TelegramCore/Sources/AddPeerMember.swift +++ b/submodules/TelegramCore/Sources/AddPeerMember.swift @@ -57,7 +57,7 @@ public func addGroupMember(account: Account, peerId: PeerId, memberId: PeerId) - }) } } - |> mapError { _ -> AddGroupMemberError in return .generic } + |> mapError { _ -> AddGroupMemberError in } } } else { return .fail(.generic) @@ -65,7 +65,7 @@ public func addGroupMember(account: Account, peerId: PeerId, memberId: PeerId) - } else { return .fail(.generic) } - } |> mapError { _ -> AddGroupMemberError in return .generic } |> switchToLatest + } |> mapError { _ -> AddGroupMemberError in } |> switchToLatest } public enum AddChannelMemberError { @@ -82,7 +82,6 @@ public enum AddChannelMemberError { public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), AddChannelMemberError> { return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId) |> mapError { error -> AddChannelMemberError in - return .generic } |> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant), AddChannelMemberError> in return account.postbox.transaction { transaction -> Signal<(ChannelParticipant?, RenderedChannelParticipant), AddChannelMemberError> in @@ -158,7 +157,7 @@ public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) if let presence = transaction.getPeerPresence(peerId: memberPeer.id) { presences[memberPeer.id] = presence } - if case let .member(_, _, maybeAdminInfo, maybeBannedInfo, _) = updatedParticipant { + if case let .member(_, _, maybeAdminInfo, _, _) = updatedParticipant { if let adminInfo = maybeAdminInfo { if let peer = transaction.getPeer(adminInfo.promotedBy) { peers[peer.id] = peer @@ -167,7 +166,7 @@ public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) } return (currentParticipant, RenderedChannelParticipant(participant: updatedParticipant, peer: memberPeer, peers: peers, presences: presences)) } - |> mapError { _ -> AddChannelMemberError in return .generic } + |> mapError { _ -> AddChannelMemberError in } } } else { return .fail(.generic) @@ -176,7 +175,7 @@ public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) return .fail(.generic) } } - |> mapError { _ -> AddChannelMemberError in return .generic } + |> mapError { _ -> AddChannelMemberError in } |> switchToLatest } } diff --git a/submodules/TelegramCore/Sources/BankCards.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BankCards.swift similarity index 94% rename from submodules/TelegramCore/Sources/BankCards.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Payments/BankCards.swift index b600491d83..f756b95b71 100644 --- a/submodules/TelegramCore/Sources/BankCards.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BankCards.swift @@ -5,17 +5,7 @@ import SyncCore import MtProtoKit import SwiftSignalKit -public struct BankCardUrl { - public let title: String - public let url: String -} - -public struct BankCardInfo { - public let title: String - public let urls: [BankCardUrl] -} - -public func getBankCardInfo(account: Account, cardNumber: String) -> Signal { +func _internal_getBankCardInfo(account: Account, cardNumber: String) -> Signal { return currentWebDocumentsHostDatacenterId(postbox: account.postbox, isTestingEnvironment: false) |> mapToSignal { datacenterId in let signal: Signal @@ -38,6 +28,16 @@ public func getBankCardInfo(account: Account, cardNumber: String) -> Signal Signal { + return _internal_getBankCardInfo(account: self.account, cardNumber: cardNumber) + } + } +} diff --git a/submodules/TelegramCore/Sources/AddressNames.swift b/submodules/TelegramCore/Sources/TelegramEngine/PeerNames/AddressNames.swift similarity index 91% rename from submodules/TelegramCore/Sources/AddressNames.swift rename to submodules/TelegramCore/Sources/TelegramEngine/PeerNames/AddressNames.swift index 4f14c18d00..017cd4ba21 100644 --- a/submodules/TelegramCore/Sources/AddressNames.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/PeerNames/AddressNames.swift @@ -26,7 +26,7 @@ public enum AddressNameDomain { case theme(TelegramTheme) } -public func checkAddressNameFormat(_ value: String, canEmpty: Bool = false) -> AddressNameFormatError? { +func _internal_checkAddressNameFormat(_ value: String, canEmpty: Bool = false) -> AddressNameFormatError? { var index = 0 let length = value.count for char in value { @@ -52,7 +52,7 @@ public func checkAddressNameFormat(_ value: String, canEmpty: Bool = false) -> A return nil } -public func addressNameAvailability(account: Account, domain: AddressNameDomain, name: String) -> Signal { +func _internal_addressNameAvailability(account: Account, domain: AddressNameDomain, name: String) -> Signal { return account.postbox.transaction { transaction -> Signal in switch domain { case .account: @@ -120,7 +120,7 @@ public enum UpdateAddressNameError { case generic } -public func updateAddressName(account: Account, domain: AddressNameDomain, name: String?) -> Signal { +func _internal_updateAddressName(account: Account, domain: AddressNameDomain, name: String?) -> Signal { return account.postbox.transaction { transaction -> Signal in switch domain { case .account: @@ -134,7 +134,7 @@ public func updateAddressName(account: Account, domain: AddressNameDomain, name: updatePeers(transaction: transaction, peers: [user], update: { _, updated in return updated }) - } |> mapError { _ -> UpdateAddressNameError in return .generic } + } |> mapError { _ -> UpdateAddressNameError in } } case let .peer(peerId): if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) { @@ -155,7 +155,7 @@ public func updateAddressName(account: Account, domain: AddressNameDomain, name: }) } } - } |> mapError { _ -> UpdateAddressNameError in return .generic } + } |> mapError { _ -> UpdateAddressNameError in } } } else { return .fail(.generic) @@ -170,10 +170,10 @@ public func updateAddressName(account: Account, domain: AddressNameDomain, name: return Void() } } - } |> mapError { _ -> UpdateAddressNameError in return .generic } |> switchToLatest + } |> mapError { _ -> UpdateAddressNameError in } |> switchToLatest } -public func checkPublicChannelCreationAvailability(account: Account, location: Bool = false) -> Signal { +func _internal_checkPublicChannelCreationAvailability(account: Account, location: Bool = false) -> Signal { var flags: Int32 = (1 << 1) if location { flags |= (1 << 0) @@ -194,7 +194,7 @@ public enum AdminedPublicChannelsScope { case forVoiceChat } -public func adminedPublicChannels(account: Account, scope: AdminedPublicChannelsScope = .all) -> Signal<[Peer], NoError> { +func _internal_adminedPublicChannels(account: Account, scope: AdminedPublicChannelsScope = .all) -> Signal<[Peer], NoError> { var flags: Int32 = 0 switch scope { case .all: @@ -238,7 +238,7 @@ public enum ChannelAddressNameAssignmentAvailability { case addressNameLimitReached } -public func channelAddressNameAssignmentAvailability(account: Account, peerId: PeerId?) -> Signal { +func _internal_channelAddressNameAssignmentAvailability(account: Account, peerId: PeerId?) -> Signal { return account.postbox.transaction { transaction -> Signal in var inputChannel: Api.InputChannel? if let peerId = peerId { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/PeerNames/TelegramEnginePeerNames.swift b/submodules/TelegramCore/Sources/TelegramEngine/PeerNames/TelegramEnginePeerNames.swift new file mode 100644 index 0000000000..71a1f8f629 --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/PeerNames/TelegramEnginePeerNames.swift @@ -0,0 +1,53 @@ +import SwiftSignalKit +import Postbox + +public enum AddressNameValidationStatus: Equatable { + case checking + case invalidFormat(AddressNameFormatError) + case availability(AddressNameAvailability) +} + +public extension TelegramEngine { + final class PeerNames { + private let account: Account + + init(account: Account) { + self.account = account + } + + public func addressNameAvailability(domain: AddressNameDomain, name: String) -> Signal { + return _internal_addressNameAvailability(account: self.account, domain: domain, name: name) + } + + public func updateAddressName(domain: AddressNameDomain, name: String?) -> Signal { + return _internal_updateAddressName(account: self.account, domain: domain, name: name) + } + + public func checkPublicChannelCreationAvailability(location: Bool = false) -> Signal { + return _internal_checkPublicChannelCreationAvailability(account: self.account, location: location) + } + + public func adminedPublicChannels(scope: AdminedPublicChannelsScope = .all) -> Signal<[Peer], NoError> { + return _internal_adminedPublicChannels(account: self.account, scope: scope) + } + + public func channelAddressNameAssignmentAvailability(peerId: PeerId?) -> Signal { + return _internal_channelAddressNameAssignmentAvailability(account: self.account, peerId: peerId) + } + + public func validateAddressNameInteractive(domain: AddressNameDomain, name: String) -> Signal { + if let error = _internal_checkAddressNameFormat(name) { + return .single(.invalidFormat(error)) + } else { + return .single(.checking) + |> then( + self.addressNameAvailability(domain: domain, name: name) + |> delay(0.3, queue: Queue.concurrentDefaultQueue()) + |> map { result -> AddressNameValidationStatus in + .availability(result) + } + ) + } + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift b/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift index eb622a8f0c..6e8daecad9 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift @@ -15,4 +15,12 @@ public final class TelegramEngine { public lazy var peersNearby: PeersNearby = { return PeersNearby(account: self.account) }() + + public lazy var payments: Payments = { + return Payments(account: self.account) + }() + + public lazy var peerNames: PeerNames = { + return PeerNames(account: self.account) + }() } diff --git a/submodules/TelegramCore/Sources/Unixtime.swift b/submodules/TelegramCore/Sources/Unixtime.swift deleted file mode 100644 index 090a84723b..0000000000 --- a/submodules/TelegramCore/Sources/Unixtime.swift +++ /dev/null @@ -1,126 +0,0 @@ -import Foundation - -public struct DateTime { - public let seconds: Int32 // 0 ... 59 - public let minutes: Int32 // 0 ... 59 - public let hours: Int32 // 0 ... 23 - public let dayOfMonth: Int32 // 1 ... 31 - public let month: Int32 // 0 ... 11 - public let year: Int32 // since 1900 - public let dayOfWeek: Int32 // 0 ... 6 - public let dayOfYear: Int32 // 0 ... 365 -} - -private let daysSinceJan1st: [[UInt32]] = -[ - [0,31,59,90,120,151,181,212,243,273,304,334,365], // 365 days, non-leap - [0,31,60,91,121,152,182,213,244,274,305,335,366] // 366 days, leap -] - -public func secondsSinceEpochToDateTime(_ secondsSinceEpoch: Int64) -> DateTime { - var sec: UInt64 - let quadricentennials: UInt32 - var centennials: UInt32 - var quadrennials: UInt32 - var annuals: UInt32 - let year: UInt32 - let leap: UInt32 - let yday: UInt32 - let hour: UInt32 - let min: UInt32 - var month: UInt32 - var mday: UInt32 - let wday: UInt32 - - /* - 400 years: - - 1st hundred, starting immediately after a leap year that's a multiple of 400: - n n n l \ - n n n l } 24 times - ... / - n n n l / - n n n n - - 2nd hundred: - n n n l \ - n n n l } 24 times - ... / - n n n l / - n n n n - - 3rd hundred: - n n n l \ - n n n l } 24 times - ... / - n n n l / - n n n n - - 4th hundred: - n n n l \ - n n n l } 24 times - ... / - n n n l / - n n n L <- 97'th leap year every 400 years - */ - - // Re-bias from 1970 to 1601: - // 1970 - 1601 = 369 = 3*100 + 17*4 + 1 years (incl. 89 leap days) = - // (3*100*(365+24/100) + 17*4*(365+1/4) + 1*365)*24*3600 seconds - sec = UInt64(secondsSinceEpoch) + (11644473600 as UInt64) - - wday = (uint)((sec / 86400 + 1) % 7); // day of week - - // Remove multiples of 400 years (incl. 97 leap days) - quadricentennials = UInt32((UInt64(sec) / (12622780800 as UInt64))) // 400*365.2425*24*3600 - sec %= 12622780800 as UInt64 - - // Remove multiples of 100 years (incl. 24 leap days), can't be more than 3 - // (because multiples of 4*100=400 years (incl. leap days) have been removed) - centennials = UInt32(UInt64(sec) / (3155673600 as UInt64)) // 100*(365+24/100)*24*3600 - if centennials > 3 { - centennials = 3 - } - sec -= UInt64(centennials) * (3155673600 as UInt64) - - // Remove multiples of 4 years (incl. 1 leap day), can't be more than 24 - // (because multiples of 25*4=100 years (incl. leap days) have been removed) - quadrennials = UInt32((UInt64(sec) / (126230400 as UInt64))) // 4*(365+1/4)*24*3600 - if quadrennials > 24 { - quadrennials = 24 - } - sec -= UInt64(quadrennials) * (126230400 as UInt64) - - // Remove multiples of years (incl. 0 leap days), can't be more than 3 - // (because multiples of 4 years (incl. leap days) have been removed) - annuals = UInt32(sec / (31536000 as UInt64)) // 365*24*3600 - if annuals > 3 { - annuals = 3 - } - sec -= UInt64(annuals) * (31536000 as UInt64) - - // Calculate the year and find out if it's leap - year = 1601 + quadricentennials * 400 + centennials * 100 + quadrennials * 4 + annuals; - leap = (!(year % UInt32(4) != 0) && ((year % UInt32(100) != 0) || !(year % UInt32(400) != 0))) ? 1 : 0 - - // Calculate the day of the year and the time - yday = UInt32(sec / (86400 as UInt64)) - sec %= 86400; - hour = UInt32(sec / 3600); - sec %= 3600; - min = UInt32(sec / 60); - sec %= 60; - - mday = 1 - month = 1 - while month < 13 { - if (yday < daysSinceJan1st[Int(leap)][Int(month)]) { - mday += yday - daysSinceJan1st[Int(leap)][Int(month - 1)] - break - } - - month += 1 - } - - return DateTime(seconds: Int32(sec), minutes: Int32(min), hours: Int32(hour), dayOfMonth: Int32(mday), month: Int32(month - 1), year: Int32(year - 1900), dayOfWeek: Int32(wday), dayOfYear: Int32(yday)) -} diff --git a/submodules/TelegramCore/Sources/ValidateAddressNameInteractive.swift b/submodules/TelegramCore/Sources/ValidateAddressNameInteractive.swift deleted file mode 100644 index 2b45f63e2e..0000000000 --- a/submodules/TelegramCore/Sources/ValidateAddressNameInteractive.swift +++ /dev/null @@ -1,24 +0,0 @@ -import Foundation -import Postbox -import SwiftSignalKit - -public enum AddressNameValidationStatus: Equatable { - case checking - case invalidFormat(AddressNameFormatError) - case availability(AddressNameAvailability) -} - -public func validateAddressNameInteractive(account: Account, domain: AddressNameDomain, name: String) -> Signal { - if let error = checkAddressNameFormat(name) { - return .single(.invalidFormat(error)) - } else { - return .single(.checking) - |> then( - addressNameAvailability(account: account, domain: domain, name: name) - |> delay(0.3, queue: Queue.concurrentDefaultQueue()) - |> map { result -> AddressNameValidationStatus in - .availability(result) - } - ) - } -} diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 0b0aa52040..48f8d436e2 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -1753,7 +1753,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - var signal = getBankCardInfo(account: strongSelf.context.account, cardNumber: number) + var signal = strongSelf.context.engine.payments.getBankCardInfo(cardNumber: number) let disposable: MetaDisposable if let current = strongSelf.bankCardDisposable { disposable = current