diff --git a/Widget/PeerNode.swift b/Widget/PeerNode.swift index 9600ebe22f..2e731fdd30 100644 --- a/Widget/PeerNode.swift +++ b/Widget/PeerNode.swift @@ -1,7 +1,6 @@ import Foundation -import Postbox -import TelegramCore import UIKit +import WidgetItems private extension UIColor { convenience init(rgb: UInt32) { @@ -53,7 +52,7 @@ private let deviceColorSpace: CGColorSpace = { } }() -private func avatarViewLettersImage(size: CGSize, peerId: PeerId, accountPeerId: PeerId, letters: [String]) -> UIImage? { +private func avatarViewLettersImage(size: CGSize, peerId: Int64, accountPeerId: Int64, letters: [String]) -> UIImage? { UIGraphicsBeginImageContextWithOptions(size, false, 0.0) let context = UIGraphicsGetCurrentContext() @@ -61,7 +60,7 @@ private func avatarViewLettersImage(size: CGSize, peerId: PeerId, accountPeerId: context?.addEllipse(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)) context?.clip() - let colorIndex = abs(Int(accountPeerId.id + peerId.id)) + let colorIndex = abs(Int(accountPeerId + peerId)) let colorsArray = gradientColors[colorIndex % gradientColors.count] var locations: [CGFloat] = [1.0, 0.0] @@ -98,13 +97,13 @@ private func avatarViewLettersImage(size: CGSize, peerId: PeerId, accountPeerId: private let avatarSize = CGSize(width: 50.0, height: 50.0) private final class AvatarView: UIImageView { - init(account: Account, peer: Peer, size: CGSize) { + init(accountPeerId: Int64, peer: WidgetDataPeer, size: CGSize) { super.init(frame: CGRect()) - if let resource = peer.smallProfileImage?.resource, let path = account.postbox.mediaBox.completedResourcePath(resource), let image = UIImage(contentsOfFile: path), let roundImage = avatarRoundImage(size: size, source: image) { + if let path = peer.avatarPath, let image = UIImage(contentsOfFile: path), let roundImage = avatarRoundImage(size: size, source: image) { self.image = roundImage } else { - self.image = avatarViewLettersImage(size: size, peerId: peer.id, accountPeerId: account.peerId, letters: peer.displayLetters) + self.image = avatarViewLettersImage(size: size, peerId: peer.id, accountPeerId: accountPeerId, letters: peer.letters) } } @@ -114,19 +113,20 @@ private final class AvatarView: UIImageView { } final class PeerView: UIView { - let peer: Peer + let peer: WidgetDataPeer private let avatarView: AvatarView private let titleLabel: UILabel private let tapped: () -> Void - init(account: Account, peer: Peer, tapped: @escaping () -> Void) { + init(accountPeerId: Int64, peer: WidgetDataPeer, tapped: @escaping () -> Void) { self.peer = peer self.tapped = tapped - self.avatarView = AvatarView(account: account, peer: peer, size: avatarSize) + self.avatarView = AvatarView(accountPeerId: accountPeerId, peer: peer, size: avatarSize) self.titleLabel = UILabel() - self.titleLabel.text = peer.compactDisplayTitle + let title = peer.name + self.titleLabel.text = title self.titleLabel.textColor = .black self.titleLabel.font = UIFont.systemFont(ofSize: 11.0) self.titleLabel.lineBreakMode = .byTruncatingTail diff --git a/Widget/TodayViewController.swift b/Widget/TodayViewController.swift index dd691a91b5..28de6e77f2 100644 --- a/Widget/TodayViewController.swift +++ b/Widget/TodayViewController.swift @@ -1,57 +1,26 @@ import UIKit -import TelegramCore -import SwiftSignalKit -import Postbox import NotificationCenter import BuildConfig +import WidgetItems -private var installedSharedLogger = false - -private func setupSharedLogger(_ path: String) { - if !installedSharedLogger { - installedSharedLogger = true - Logger.setSharedLogger(Logger(basePath: path)) - } +private func rootPathForBasePath(_ appGroupPath: String) -> String { + return appGroupPath + "/telegram-data" } -private let auxiliaryMethods = AccountAuxiliaryMethods(updatePeerChatInputState: { _, _ in - return nil -}, fetchResource: { _, _, _, _ in - return nil -}, fetchResourceMediaReferenceHash: { _ in - return .single(nil) -}, prepareSecretThumbnailData: { _ in - return nil -}) - @objc(TodayViewController) class TodayViewController: UIViewController, NCWidgetProviding { private var initializedInterface = false - private let disposable = MetaDisposable() private var buildConfig: BuildConfig? - deinit { - self.disposable.dispose() - } - - private var snapshotView: UIImageView? - override func viewDidLoad() { super.viewDidLoad() - self.snapshotView?.removeFromSuperview() - let snapshotView = UIImageView() - if let path = self.getSnapshotPath(), let image = UIImage(contentsOfFile: path) { - snapshotView.image = image - } - self.snapshotView = snapshotView - self.view.addSubview(snapshotView) - if self.initializedInterface { return } self.initializedInterface = true + let appBundleIdentifier = Bundle.main.bundleIdentifier! guard let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else { return @@ -61,9 +30,6 @@ class TodayViewController: UIViewController, NCWidgetProviding { let buildConfig = BuildConfig(baseAppBundleId: baseAppBundleId) self.buildConfig = buildConfig - let apiId: Int32 = buildConfig.apiId - let languagesCategory = "ios" - let appGroupName = "group.\(baseAppBundleId)" let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName) @@ -72,56 +38,11 @@ class TodayViewController: UIViewController, NCWidgetProviding { } let rootPath = rootPathForBasePath(appGroupUrl.path) - performAppGroupUpgrades(appGroupPath: appGroupUrl.path, rootPath: rootPath) + let dataPath = rootPath + "/widget-data" - TempBox.initializeShared(basePath: rootPath, processType: "widget", launchSpecificId: arc4random64()) - - let logsPath = rootPath + "/today-logs" - let _ = try? FileManager.default.createDirectory(atPath: logsPath, withIntermediateDirectories: true, attributes: nil) - - setupSharedLogger(logsPath) - - let account: Signal - let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" - initializeAccountManagement() - let accountManager = AccountManager(basePath: rootPath + "/accounts-metadata") - - let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId) - let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!) - - account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: .single(buildConfig.bundleData(withAppToken: nil))), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: auxiliaryMethods, encryptionParameters: encryptionParameters) - |> mapToSignal { account -> Signal in - if let account = account { - switch account { - case .upgrading: - return .complete() - case let .authorized(account): - return .single(account) - case .unauthorized: - return .complete() - } - } else { - return .complete() - } + if let data = try? Data(contentsOf: URL(fileURLWithPath: dataPath)), let widgetData = try? JSONDecoder().decode(WidgetData.self, from: data) { + self.setWidgetData(widgetData: widgetData) } - - let applicationInterface = account - |> deliverOnMainQueue - |> afterNext { [weak self] account in - let _ = (recentPeers(account: account) - |> deliverOnMainQueue).start(next: { peers in - if let strongSelf = self { - switch peers { - case let .peers(peers): - strongSelf.setPeers(account: account, peers: peers.filter { !$0.isDeleted }) - case .disabled: - strongSelf.setPeers(account: account, peers: []) - } - } - }) - } - - self.disposable.set(applicationInterface.start()) } func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { @@ -133,34 +54,37 @@ class TodayViewController: UIViewController, NCWidgetProviding { } - private var peers: [Peer]? + private var widgetData: WidgetData? - private func setPeers(account: Account, peers: [Peer]) { - self.peers = peers + private func setWidgetData(widgetData: WidgetData) { + self.widgetData = widgetData self.peerViews.forEach { $0.removeFromSuperview() } self.peerViews = [] - for peer in peers { - let peerView = PeerView(account: account, peer: peer, tapped: { [weak self] in - if let strongSelf = self, let buildConfig = strongSelf.buildConfig { - if let url = URL(string: "\(buildConfig.appSpecificUrlScheme)://localpeer?id=\(peer.id.toInt64())") { - strongSelf.extensionContext?.open(url, completionHandler: nil) + switch widgetData { + case .notAuthorized, .disabled: + break + case let .peers(peers): + for peer in peers.peers { + let peerView = PeerView(accountPeerId: peers.accountPeerId, peer: peer, tapped: { [weak self] in + if let strongSelf = self, let buildConfig = strongSelf.buildConfig { + if let url = URL(string: "\(buildConfig.appSpecificUrlScheme)://localpeer?id=\(peer.id)") { + strongSelf.extensionContext?.open(url, completionHandler: nil) + } } - } - }) - self.view.addSubview(peerView) - self.peerViews.append(peerView) + }) + self.view.addSubview(peerView) + self.peerViews.append(peerView) + } } - self.validSnapshotSize = nil if let size = self.validLayout { self.updateLayout(size: size) } } private var validLayout: CGSize? - private var validSnapshotSize: CGSize? private var peerViews: [PeerView] = [] @@ -173,11 +97,6 @@ class TodayViewController: UIViewController, NCWidgetProviding { private func updateLayout(size: CGSize) { self.validLayout = size - if let image = self.snapshotView?.image { - let scale = UIScreen.main.scale - self.snapshotView?.frame = CGRect(origin: CGPoint(), size: CGSize(width: image.size.width / scale, height: image.size.height / scale)) - } - let peerSize = CGSize(width: 70.0, height: 100.0) var peerFrames: [CGRect] = [] @@ -205,49 +124,5 @@ class TodayViewController: UIViewController, NCWidgetProviding { peerView.updateLayout(size: peerFrames[i].size) offset += peerFrames[i].width + spacing } - - if self.peers != nil { - self.snapshotView?.removeFromSuperview() - if self.validSnapshotSize != size { - self.validSnapshotSize = size - self.updateSnapshot() - } - } - } - - private func updateSnapshot() { - if let path = self.getSnapshotPath() { - DispatchQueue.main.async { - UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, false, 0.0) - self.view.drawHierarchy(in: self.view.bounds, afterScreenUpdates: false) - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - if let image = image, let data = image.pngData() { - let _ = try? FileManager.default.removeItem(atPath: path) - do { - try data.write(to: URL(fileURLWithPath: path)) - } catch let e { - print("\(e)") - } - } - } - } - } - - private func getSnapshotPath() -> String? { - let appBundleIdentifier = Bundle.main.bundleIdentifier! - guard let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else { - return nil - } - - let appGroupName = "group.\(appBundleIdentifier[..