Simplify widget data loading

This commit is contained in:
Peter 2019-10-11 16:22:09 +04:00
parent 8665208520
commit 846e16c235
5 changed files with 140 additions and 3 deletions

4
BUCK
View File

@ -241,10 +241,8 @@ apple_binary(
"@executable_path/../../Frameworks",
],
deps = [
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
"//submodules/TelegramCore:TelegramCore#shared",
"//submodules/Postbox:Postbox#shared",
"//submodules/BuildConfig:BuildConfig",
"//submodules/WidgetItems:WidgetItems",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/UIKit.framework",

View File

@ -143,6 +143,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
private let displayUpgradeProgress: (Float?) -> Void
private var widgetDataContext: WidgetDataContext?
public init(mainWindow: Window1?, basePath: String, encryptionParameters: ValueBoxEncryptionParameters, accountManager: AccountManager, applicationBindings: TelegramApplicationBindings, initialPresentationDataAndSettings: InitialPresentationDataAndSettings, networkArguments: NetworkInitializationArguments, rootPath: String, legacyBasePath: String?, legacyCache: LegacyCache?, apsNotificationToken: Signal<Data?, NoError>, voipNotificationToken: Signal<Data?, NoError>, setNotificationCall: @escaping (PresentationCall?) -> Void, navigateToChat: @escaping (AccountRecordId, PeerId, MessageId?) -> Void, displayUpgradeProgress: @escaping (Float?) -> Void = { _ in }) {
assert(Queue.mainQueue().isCurrent())
@ -609,6 +611,11 @@ public final class SharedAccountContextImpl: SharedAccountContext {
let _ = managedCleanupAccounts(networkArguments: networkArguments, accountManager: self.accountManager, rootPath: rootPath, auxiliaryMethods: telegramAccountAuxiliaryMethods, encryptionParameters: encryptionParameters).start()
self.updateNotificationTokensRegistration()
self.widgetDataContext = WidgetDataContext(basePath: self.basePath, activeAccount: self.activeAccounts
|> map { primary, _, _ in
return primary
})
}
deinit {

View File

@ -0,0 +1,49 @@
import Foundation
import SwiftSignalKit
import Postbox
import TelegramCore
import WidgetItems
final class WidgetDataContext {
private var currentAccount: Account?
private var currentAccountDisposable: Disposable?
init(basePath: String, activeAccount: Signal<Account?, NoError>) {
self.currentAccountDisposable = (activeAccount
|> distinctUntilChanged(isEqual: { lhs, rhs in
return lhs === rhs
})
|> mapToSignal { account -> Signal<WidgetData, NoError> in
guard let account = account else {
return .single(.notAuthorized)
}
return recentPeers(account: account)
|> map { result -> WidgetData in
switch result {
case .disabled:
return .disabled
case let .peers(peers):
return .peers(WidgetDataPeers(accountPeerId: account.peerId.toInt64(), peers: peers.compactMap { peer -> WidgetDataPeer? in
guard let user = peer as? TelegramUser else {
return nil
}
return WidgetDataPeer(id: user.id.toInt64(), name: user.shortNameOrPhone ?? "", letters: user.displayLetters, avatarPath: smallestImageRepresentation(user.photo).flatMap { representation in
return account.postbox.mediaBox.resourcePath(representation.resource)
})
}))
}
}
}).start(next: { widgetData in
let path = basePath + "/widget-data"
if let data = try? JSONEncoder().encode(widgetData) {
let _ = try? data.write(to: URL(fileURLWithPath: path), options: [.atomic])
} else {
let _ = try? FileManager.default.removeItem(atPath: path)
}
})
}
deinit {
self.currentAccountDisposable?.dispose()
}
}

View File

@ -0,0 +1,11 @@
load("//Config:buck_rule_macros.bzl", "static_library")
static_library(
name = "WidgetItems",
srcs = glob([
"Sources/**/*.swift",
]),
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
],
)

View File

@ -0,0 +1,72 @@
import Foundation
public enum WidgetCodingError: Error {
case generic
}
public struct WidgetDataPeer: Codable, Equatable {
public var id: Int64
public var name: String
public var letters: [String]
public var avatarPath: String?
public init(id: Int64, name: String, letters: [String], avatarPath: String?) {
self.id = id
self.name = name
self.letters = letters
self.avatarPath = avatarPath
}
}
public struct WidgetDataPeers: Codable, Equatable {
public var accountPeerId: Int64
public var peers: [WidgetDataPeer]
public init(accountPeerId: Int64, peers: [WidgetDataPeer]) {
self.accountPeerId = accountPeerId
self.peers = peers
}
}
public enum WidgetData: Codable, Equatable {
private enum CodingKeys: CodingKey {
case discriminator
case peers
}
private enum Cases: Int32, Codable {
case notAuthorized
case disabled
case peers
}
case notAuthorized
case disabled
case peers(WidgetDataPeers)
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let discriminator = try container.decode(Cases.self, forKey: .discriminator)
switch discriminator {
case .notAuthorized:
self = .notAuthorized
case .disabled:
self = .disabled
case .peers:
self = .peers(try container.decode(WidgetDataPeers.self, forKey: .peers))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .notAuthorized:
try container.encode(Cases.notAuthorized, forKey: .discriminator)
case .disabled:
try container.encode(Cases.disabled, forKey: .discriminator)
case let .peers(peers):
try container.encode(Cases.peers, forKey: .discriminator)
try container.encode(peers, forKey: .peers)
}
}
}