mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
142 lines
4.7 KiB
Swift
142 lines
4.7 KiB
Swift
import Foundation
|
|
import Postbox
|
|
import SwiftSignalKit
|
|
import TelegramApi
|
|
import MtProtoKit
|
|
|
|
public final class TelegramBirthday: Codable, Equatable {
|
|
private enum CodingKeys: String, CodingKey {
|
|
case day
|
|
case month
|
|
case year
|
|
}
|
|
|
|
public let day: Int32
|
|
public let month: Int32
|
|
public let year: Int32?
|
|
|
|
public init(day: Int32, month: Int32, year: Int32?) {
|
|
self.day = day
|
|
self.month = month
|
|
self.year = year
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
|
|
self.day = try container.decode(Int32.self, forKey: .day)
|
|
self.month = try container.decode(Int32.self, forKey: .month)
|
|
self.year = try container.decodeIfPresent(Int32.self, forKey: .year)
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
|
|
try container.encode(self.day, forKey: .day)
|
|
try container.encode(self.month, forKey: .month)
|
|
try container.encodeIfPresent(self.year, forKey: .year)
|
|
}
|
|
|
|
public static func ==(lhs: TelegramBirthday, rhs: TelegramBirthday) -> Bool {
|
|
if lhs === rhs {
|
|
return true
|
|
}
|
|
|
|
if lhs.day != rhs.day {
|
|
return false
|
|
}
|
|
if lhs.month != rhs.month {
|
|
return false
|
|
}
|
|
if lhs.year != rhs.year {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
}
|
|
|
|
extension TelegramBirthday {
|
|
convenience init(apiBirthday: Api.Birthday) {
|
|
switch apiBirthday {
|
|
case let .birthday(_, day, month, year):
|
|
self.init(
|
|
day: day,
|
|
month: month,
|
|
year: year
|
|
)
|
|
}
|
|
}
|
|
|
|
var apiBirthday: Api.Birthday {
|
|
var flags: Int32 = 0
|
|
if let _ = self.year {
|
|
flags |= (1 << 0)
|
|
}
|
|
return .birthday(flags: flags, day: self.day, month: self.month, year: self.year)
|
|
}
|
|
}
|
|
|
|
public enum UpdateBirthdayError {
|
|
case generic
|
|
case flood
|
|
}
|
|
|
|
func _internal_updateBirthday(account: Account, birthday: TelegramBirthday?) -> Signal<Never, UpdateBirthdayError> {
|
|
var flags: Int32 = 0
|
|
if let _ = birthday {
|
|
flags |= (1 << 0)
|
|
}
|
|
return account.network.request(Api.functions.account.updateBirthday(flags: flags, birthday: birthday?.apiBirthday), automaticFloodWait: false)
|
|
|> mapError { error -> UpdateBirthdayError in
|
|
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
|
return .flood
|
|
} else {
|
|
return .generic
|
|
}
|
|
}
|
|
|> mapToSignal { result -> Signal<Never, UpdateBirthdayError> in
|
|
return account.postbox.transaction { transaction -> Void in
|
|
if case .boolTrue = result {
|
|
transaction.updatePeerCachedData(peerIds: Set([account.peerId]), update: { _, current in
|
|
if let current = current as? CachedUserData {
|
|
return current.withUpdatedBirthday(birthday)
|
|
} else {
|
|
return current
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|> mapError { _ -> UpdateBirthdayError in }
|
|
|> ignoreValues
|
|
}
|
|
}
|
|
|
|
func managedContactBirthdays(stateManager: AccountStateManager) -> Signal<Never, NoError> {
|
|
let poll = stateManager.network.request(Api.functions.contacts.getBirthdays())
|
|
|> retryRequest
|
|
|> mapToSignal { result -> Signal<Never, NoError> in
|
|
return stateManager.postbox.transaction { transaction -> Void in
|
|
if case let .contactBirthdays(contactBirthdays, users) = result {
|
|
updatePeers(transaction: transaction, accountPeerId: stateManager.accountPeerId, peers: AccumulatedPeers(users: users))
|
|
|
|
var birthdays: [EnginePeer.Id: TelegramBirthday] = [:]
|
|
for contactBirthday in contactBirthdays {
|
|
if case let .contactBirthday(contactId, birthday) = contactBirthday {
|
|
let peerId = EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(contactId))
|
|
if peerId == stateManager.accountPeerId {
|
|
continue
|
|
}
|
|
birthdays[peerId] = TelegramBirthday(apiBirthday: birthday)
|
|
}
|
|
}
|
|
stateManager.modifyContactBirthdays({ _ in
|
|
return birthdays
|
|
})
|
|
}
|
|
}
|
|
|> ignoreValues
|
|
}
|
|
return (poll |> then(.complete() |> suspendAwareDelay(8.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
|
}
|