mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Widget improvements
This commit is contained in:
parent
c526024286
commit
c38f6502d4
@ -54,7 +54,7 @@ enum IntentHandlingError {
|
|||||||
|
|
||||||
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
|
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
|
||||||
@objc(IntentHandler)
|
@objc(IntentHandler)
|
||||||
class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling, INSearchCallHistoryIntentHandling, SelectFriendsIntentHandling {
|
class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling, INSearchCallHistoryIntentHandling {
|
||||||
private let accountPromise = Promise<Account?>()
|
private let accountPromise = Promise<Account?>()
|
||||||
private let allAccounts = Promise<[(AccountRecordId, PeerId, Bool)]>()
|
private let allAccounts = Promise<[(AccountRecordId, PeerId, Bool)]>()
|
||||||
|
|
||||||
@ -198,6 +198,8 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
if #available(iOSApplicationExtension 12.0, iOS 12.0, *) {
|
if #available(iOSApplicationExtension 12.0, iOS 12.0, *) {
|
||||||
if intent is SelectAvatarFriendsIntent {
|
if intent is SelectAvatarFriendsIntent {
|
||||||
return AvatarsIntentHandler()
|
return AvatarsIntentHandler()
|
||||||
|
} else if intent is SelectFriendsIntent {
|
||||||
|
return FriendsIntentHandler()
|
||||||
} else {
|
} else {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
@ -845,34 +847,21 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
|
private final class WidgetIntentHandler {
|
||||||
@objc(AvatarsIntentHandler)
|
|
||||||
class AvatarsIntentHandler: NSObject, SelectAvatarFriendsIntentHandling {
|
|
||||||
private let accountPromise = Promise<Account?>()
|
|
||||||
private let allAccounts = Promise<[(AccountRecordId, PeerId, Bool)]>()
|
private let allAccounts = Promise<[(AccountRecordId, PeerId, Bool)]>()
|
||||||
|
|
||||||
private let resolvePersonsDisposable = MetaDisposable()
|
|
||||||
private let actionDisposable = MetaDisposable()
|
|
||||||
private let searchDisposable = MetaDisposable()
|
private let searchDisposable = MetaDisposable()
|
||||||
|
|
||||||
private var rootPath: String?
|
private var rootPath: String?
|
||||||
private var accountManager: AccountManager?
|
|
||||||
private var encryptionParameters: ValueBoxEncryptionParameters?
|
private var encryptionParameters: ValueBoxEncryptionParameters?
|
||||||
private var appGroupUrl: URL?
|
private var appGroupUrl: URL?
|
||||||
|
|
||||||
override init() {
|
init() {
|
||||||
super.init()
|
|
||||||
|
|
||||||
guard let appBundleIdentifier = Bundle.main.bundleIdentifier, let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else {
|
guard let appBundleIdentifier = Bundle.main.bundleIdentifier, let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let baseAppBundleId = String(appBundleIdentifier[..<lastDotRange.lowerBound])
|
let baseAppBundleId = String(appBundleIdentifier[..<lastDotRange.lowerBound])
|
||||||
let buildConfig = BuildConfig(baseAppBundleId: baseAppBundleId)
|
|
||||||
|
|
||||||
let apiId: Int32 = buildConfig.apiId
|
|
||||||
let apiHash: String = buildConfig.apiHash
|
|
||||||
let languagesCategory = "ios"
|
|
||||||
|
|
||||||
let appGroupName = "group.\(baseAppBundleId)"
|
let appGroupName = "group.\(baseAppBundleId)"
|
||||||
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
|
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
|
||||||
@ -895,106 +884,60 @@ class AvatarsIntentHandler: NSObject, SelectAvatarFriendsIntentHandling {
|
|||||||
|
|
||||||
setupSharedLogger(rootPath: rootPath, path: logsPath)
|
setupSharedLogger(rootPath: rootPath, path: logsPath)
|
||||||
|
|
||||||
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
|
||||||
|
|
||||||
initializeAccountManagement()
|
initializeAccountManagement()
|
||||||
let accountManager = AccountManager(basePath: rootPath + "/accounts-metadata", isTemporary: true)
|
|
||||||
self.accountManager = accountManager
|
|
||||||
|
|
||||||
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
|
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
|
||||||
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
||||||
self.encryptionParameters = encryptionParameters
|
self.encryptionParameters = encryptionParameters
|
||||||
|
|
||||||
self.allAccounts.set(accountManager.accountRecords()
|
let view = AccountManager.getCurrentRecords(basePath: rootPath + "/accounts-metadata")
|
||||||
|> take(1)
|
|
||||||
|> map { view -> [(AccountRecordId, PeerId, Bool)] in
|
var result: [(AccountRecordId, Int, PeerId, Bool)] = []
|
||||||
var result: [(AccountRecordId, Int, PeerId, Bool)] = []
|
for record in view.records {
|
||||||
for record in view.records {
|
let isLoggedOut = record.attributes.contains(where: { attribute in
|
||||||
let isLoggedOut = record.attributes.contains(where: { attribute in
|
return attribute is LoggedOutAccountAttribute
|
||||||
return attribute is LoggedOutAccountAttribute
|
})
|
||||||
})
|
if isLoggedOut {
|
||||||
if isLoggedOut {
|
continue
|
||||||
continue
|
}
|
||||||
}
|
var backupData: AccountBackupData?
|
||||||
/*let isTestingEnvironment = record.attributes.contains(where: { attribute in
|
var sortIndex: Int32 = 0
|
||||||
if let attribute = attribute as? AccountEnvironmentAttribute, case .test = attribute.environment {
|
for attribute in record.attributes {
|
||||||
return true
|
if let attribute = attribute as? AccountSortOrderAttribute {
|
||||||
} else {
|
sortIndex = attribute.order
|
||||||
return false
|
} else if let attribute = attribute as? AccountBackupDataAttribute {
|
||||||
}
|
backupData = attribute.data
|
||||||
})*/
|
|
||||||
var backupData: AccountBackupData?
|
|
||||||
var sortIndex: Int32 = 0
|
|
||||||
for attribute in record.attributes {
|
|
||||||
if let attribute = attribute as? AccountSortOrderAttribute {
|
|
||||||
sortIndex = attribute.order
|
|
||||||
} else if let attribute = attribute as? AccountBackupDataAttribute {
|
|
||||||
backupData = attribute.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let backupData = backupData {
|
|
||||||
result.append((record.id, Int(sortIndex), PeerId(backupData.peerId), view.currentRecord?.id == record.id))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.sort(by: { lhs, rhs in
|
if let backupData = backupData {
|
||||||
if lhs.1 != rhs.1 {
|
result.append((record.id, Int(sortIndex), PeerId(backupData.peerId), view.currentId == record.id))
|
||||||
return lhs.1 < rhs.1
|
}
|
||||||
} else {
|
}
|
||||||
return lhs.0 < rhs.0
|
result.sort(by: { lhs, rhs in
|
||||||
}
|
if lhs.1 != rhs.1 {
|
||||||
})
|
return lhs.1 < rhs.1
|
||||||
return result.map { record -> (AccountRecordId, PeerId, Bool) in
|
} else {
|
||||||
return (record.0, record.2, record.3)
|
return lhs.0 < rhs.0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
self.allAccounts.set(.single(result.map { record -> (AccountRecordId, PeerId, Bool) in
|
||||||
let account: Signal<Account?, NoError>
|
return (record.0, record.2, record.3)
|
||||||
if let accountCache = accountCache {
|
}))
|
||||||
account = .single(accountCache)
|
|
||||||
} else {
|
|
||||||
account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters)
|
|
||||||
|> mapToSignal { account -> Signal<Account?, NoError> in
|
|
||||||
if let account = account {
|
|
||||||
switch account {
|
|
||||||
case .upgrading:
|
|
||||||
return .complete()
|
|
||||||
case let .authorized(account):
|
|
||||||
return applicationSettings(accountManager: accountManager)
|
|
||||||
|> deliverOnMainQueue
|
|
||||||
|> map { settings -> Account in
|
|
||||||
accountCache = account
|
|
||||||
Logger.shared.logToFile = settings.logging.logToFile
|
|
||||||
Logger.shared.logToConsole = settings.logging.logToConsole
|
|
||||||
|
|
||||||
Logger.shared.redactSensitiveData = settings.logging.redactSensitiveData
|
|
||||||
return account
|
|
||||||
}
|
|
||||||
case .unauthorized:
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .single(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> take(1)
|
|
||||||
}
|
|
||||||
self.accountPromise.set(account)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.resolvePersonsDisposable.dispose()
|
|
||||||
self.actionDisposable.dispose()
|
|
||||||
self.searchDisposable.dispose()
|
self.searchDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
func provideFriendsOptionsCollection(for intent: SelectAvatarFriendsIntent, searchTerm: String?, with completion: @escaping (INObjectCollection<Friend>?, Error?) -> Void) {
|
func provideFriendsOptionsCollection(searchTerm: String?, with completion: @escaping (INObjectCollection<Friend>?, Error?) -> Void) {
|
||||||
guard let rootPath = self.rootPath, let _ = self.accountManager, let encryptionParameters = self.encryptionParameters else {
|
guard let rootPath = self.rootPath, let encryptionParameters = self.encryptionParameters else {
|
||||||
completion(nil, nil)
|
completion(nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
|
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
|
||||||
|
//TODO:localize
|
||||||
let error = NSError(domain: "Locked", code: 1, userInfo: [
|
let error = NSError(domain: "Locked", code: 1, userInfo: [
|
||||||
NSLocalizedDescriptionKey: "Open Telegram and enter passcode to edit widget."
|
NSLocalizedDescriptionKey: "Open Telegram and enter passcode to edit widget."
|
||||||
])
|
])
|
||||||
@ -1071,8 +1014,8 @@ class AvatarsIntentHandler: NSObject, SelectAvatarFriendsIntentHandling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
func defaultFriends(for intent: SelectAvatarFriendsIntent) -> [Friend]? {
|
func defaultFriends() -> [Friend]? {
|
||||||
guard let rootPath = self.rootPath, let _ = self.accountManager, let encryptionParameters = self.encryptionParameters else {
|
guard let rootPath = self.rootPath, let encryptionParameters = self.encryptionParameters else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,6 +1083,45 @@ class AvatarsIntentHandler: NSObject, SelectAvatarFriendsIntentHandling {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
|
||||||
|
@objc(FriendsIntentHandler)
|
||||||
|
class FriendsIntentHandler: NSObject, SelectFriendsIntentHandling {
|
||||||
|
private let handler: WidgetIntentHandler
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
self.handler = WidgetIntentHandler()
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
|
func provideFriendsOptionsCollection(for intent: SelectFriendsIntent, searchTerm: String?, with completion: @escaping (INObjectCollection<Friend>?, Error?) -> Void) {
|
||||||
|
self.handler.provideFriendsOptionsCollection(searchTerm: searchTerm, with: completion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
|
||||||
|
@objc(AvatarsIntentHandler)
|
||||||
|
class AvatarsIntentHandler: NSObject, SelectAvatarFriendsIntentHandling {
|
||||||
|
private let handler: WidgetIntentHandler
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
self.handler = WidgetIntentHandler()
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
|
func provideFriendsOptionsCollection(for intent: SelectAvatarFriendsIntent, searchTerm: String?, with completion: @escaping (INObjectCollection<Friend>?, Error?) -> Void) {
|
||||||
|
self.handler.provideFriendsOptionsCollection(searchTerm: searchTerm, with: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
|
func defaultFriends(for intent: SelectAvatarFriendsIntent) -> [Friend]? {
|
||||||
|
return self.handler.defaultFriends()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func avatarRoundImage(size: CGSize, source: UIImage) -> UIImage? {
|
private func avatarRoundImage(size: CGSize, source: UIImage) -> UIImage? {
|
||||||
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
||||||
let context = UIGraphicsGetCurrentContext()
|
let context = UIGraphicsGetCurrentContext()
|
||||||
|
@ -199,7 +199,7 @@ struct Provider: IntentTimelineProvider {
|
|||||||
var mappedMessage: WidgetDataPeer.Message?
|
var mappedMessage: WidgetDataPeer.Message?
|
||||||
if let index = transaction.getTopPeerMessageIndex(peerId: peer.id) {
|
if let index = transaction.getTopPeerMessageIndex(peerId: peer.id) {
|
||||||
if let message = transaction.getMessage(index.id) {
|
if let message = transaction.getMessage(index.id) {
|
||||||
mappedMessage = WidgetDataPeer.Message(message: message)
|
mappedMessage = WidgetDataPeer.Message(accountPeerId: state.peerId, message: message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ struct AvatarsProvider: IntentTimelineProvider {
|
|||||||
var mappedMessage: WidgetDataPeer.Message?
|
var mappedMessage: WidgetDataPeer.Message?
|
||||||
if let index = transaction.getTopPeerMessageIndex(peerId: peer.id) {
|
if let index = transaction.getTopPeerMessageIndex(peerId: peer.id) {
|
||||||
if let message = transaction.getMessage(index.id) {
|
if let message = transaction.getMessage(index.id) {
|
||||||
mappedMessage = WidgetDataPeer.Message(message: message)
|
mappedMessage = WidgetDataPeer.Message(accountPeerId: state.peerId, message: message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,15 +459,20 @@ struct WidgetView: View {
|
|||||||
} else {
|
} else {
|
||||||
dateText = ""
|
dateText = ""
|
||||||
}
|
}
|
||||||
chatTitle = AnyView(Text(peer.peer.name)
|
var formattedName = peer.peer.name
|
||||||
|
if let lastName = peer.peer.lastName {
|
||||||
|
formattedName.append(" \(lastName)")
|
||||||
|
}
|
||||||
|
chatTitle = AnyView(Text(formattedName)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.font(Font.system(size: 16.0, weight: .medium, design: .default))
|
.font(Font.system(size: 16.0, weight: .medium, design: .default))
|
||||||
.foregroundColor(.primary))
|
.foregroundColor(.primary))
|
||||||
date = Text(dateText)
|
date = Text(dateText)
|
||||||
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary)
|
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary)
|
||||||
case let .preview(index):
|
case let .preview(index):
|
||||||
|
let titleText = index == 0 ? "News Channel" : "Duck"
|
||||||
dateText = index == 0 ? "9:00" : "8:42"
|
dateText = index == 0 ? "9:00" : "8:42"
|
||||||
chatTitle = AnyView(Text("News Channel")
|
chatTitle = AnyView(Text(titleText)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.font(Font.system(size: 16.0, weight: .medium, design: .default))
|
.font(Font.system(size: 16.0, weight: .medium, design: .default))
|
||||||
.foregroundColor(.primary))
|
.foregroundColor(.primary))
|
||||||
@ -517,6 +522,7 @@ struct WidgetView: View {
|
|||||||
switch content {
|
switch content {
|
||||||
case let .peer(peer):
|
case let .peer(peer):
|
||||||
if let message = peer.peer.message {
|
if let message = peer.peer.message {
|
||||||
|
text = message.text
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
switch message.content {
|
switch message.content {
|
||||||
case .text:
|
case .text:
|
||||||
|
@ -53,6 +53,18 @@ final class AccountManagerImpl {
|
|||||||
private var noticeEntryViews = Bag<(MutableNoticeEntryView, ValuePipe<NoticeEntryView>)>()
|
private var noticeEntryViews = Bag<(MutableNoticeEntryView, ValuePipe<NoticeEntryView>)>()
|
||||||
private var accessChallengeDataViews = Bag<(MutableAccessChallengeDataView, ValuePipe<AccessChallengeDataView>)>()
|
private var accessChallengeDataViews = Bag<(MutableAccessChallengeDataView, ValuePipe<AccessChallengeDataView>)>()
|
||||||
|
|
||||||
|
static func getCurrentRecords(basePath: String) -> (records: [AccountRecord], currentId: AccountRecordId?) {
|
||||||
|
let atomicStatePath = "\(basePath)/atomic-state"
|
||||||
|
do {
|
||||||
|
let data = try Data(contentsOf: URL(fileURLWithPath: atomicStatePath))
|
||||||
|
let atomicState = try JSONDecoder().decode(AccountManagerAtomicState.self, from: data)
|
||||||
|
return (atomicState.records.sorted(by: { $0.key.int64 < $1.key.int64 }).map({ $1 }), atomicState.currentRecordId)
|
||||||
|
} catch let e {
|
||||||
|
postboxLog("decode atomic state error: \(e)")
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fileprivate init?(queue: Queue, basePath: String, isTemporary: Bool, temporarySessionId: Int64) {
|
fileprivate init?(queue: Queue, basePath: String, isTemporary: Bool, temporarySessionId: Int64) {
|
||||||
let startTime = CFAbsoluteTimeGetCurrent()
|
let startTime = CFAbsoluteTimeGetCurrent()
|
||||||
|
|
||||||
@ -78,7 +90,6 @@ final class AccountManagerImpl {
|
|||||||
do {
|
do {
|
||||||
let data = try Data(contentsOf: URL(fileURLWithPath: self.atomicStatePath))
|
let data = try Data(contentsOf: URL(fileURLWithPath: self.atomicStatePath))
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let atomicState = try JSONDecoder().decode(AccountManagerAtomicState.self, from: data)
|
let atomicState = try JSONDecoder().decode(AccountManagerAtomicState.self, from: data)
|
||||||
self.currentAtomicState = atomicState
|
self.currentAtomicState = atomicState
|
||||||
} catch let e {
|
} catch let e {
|
||||||
@ -311,7 +322,6 @@ final class AccountManagerImpl {
|
|||||||
return (.single(AccountRecordsView(mutableView))
|
return (.single(AccountRecordsView(mutableView))
|
||||||
|> then(pipe.signal()))
|
|> then(pipe.signal()))
|
||||||
|> `catch` { _ -> Signal<AccountRecordsView, NoError> in
|
|> `catch` { _ -> Signal<AccountRecordsView, NoError> in
|
||||||
return .complete()
|
|
||||||
}
|
}
|
||||||
|> afterDisposed { [weak self] in
|
|> afterDisposed { [weak self] in
|
||||||
queue.async {
|
queue.async {
|
||||||
@ -331,7 +341,6 @@ final class AccountManagerImpl {
|
|||||||
return (.single(AccountSharedDataView(mutableView))
|
return (.single(AccountSharedDataView(mutableView))
|
||||||
|> then(pipe.signal()))
|
|> then(pipe.signal()))
|
||||||
|> `catch` { _ -> Signal<AccountSharedDataView, NoError> in
|
|> `catch` { _ -> Signal<AccountSharedDataView, NoError> in
|
||||||
return .complete()
|
|
||||||
}
|
}
|
||||||
|> afterDisposed { [weak self] in
|
|> afterDisposed { [weak self] in
|
||||||
queue.async {
|
queue.async {
|
||||||
@ -351,7 +360,6 @@ final class AccountManagerImpl {
|
|||||||
return (.single(NoticeEntryView(mutableView))
|
return (.single(NoticeEntryView(mutableView))
|
||||||
|> then(pipe.signal()))
|
|> then(pipe.signal()))
|
||||||
|> `catch` { _ -> Signal<NoticeEntryView, NoError> in
|
|> `catch` { _ -> Signal<NoticeEntryView, NoError> in
|
||||||
return .complete()
|
|
||||||
}
|
}
|
||||||
|> afterDisposed { [weak self] in
|
|> afterDisposed { [weak self] in
|
||||||
queue.async {
|
queue.async {
|
||||||
@ -371,7 +379,6 @@ final class AccountManagerImpl {
|
|||||||
return (.single(AccessChallengeDataView(mutableView))
|
return (.single(AccessChallengeDataView(mutableView))
|
||||||
|> then(pipe.signal()))
|
|> then(pipe.signal()))
|
||||||
|> `catch` { _ -> Signal<AccessChallengeDataView, NoError> in
|
|> `catch` { _ -> Signal<AccessChallengeDataView, NoError> in
|
||||||
return .complete()
|
|
||||||
}
|
}
|
||||||
|> afterDisposed { [weak self] in
|
|> afterDisposed { [weak self] in
|
||||||
queue.async {
|
queue.async {
|
||||||
@ -457,6 +464,10 @@ public final class AccountManager {
|
|||||||
private let impl: QueueLocalObject<AccountManagerImpl>
|
private let impl: QueueLocalObject<AccountManagerImpl>
|
||||||
public let temporarySessionId: Int64
|
public let temporarySessionId: Int64
|
||||||
|
|
||||||
|
public static func getCurrentRecords(basePath: String) -> (records: [AccountRecord], currentId: AccountRecordId?) {
|
||||||
|
return AccountManagerImpl.getCurrentRecords(basePath: basePath)
|
||||||
|
}
|
||||||
|
|
||||||
public init(basePath: String, isTemporary: Bool) {
|
public init(basePath: String, isTemporary: Bool) {
|
||||||
self.queue = sharedQueue
|
self.queue = sharedQueue
|
||||||
self.basePath = basePath
|
self.basePath = basePath
|
||||||
|
@ -208,7 +208,27 @@ final class WidgetDataContext {
|
|||||||
}
|
}
|
||||||
var result: [WidgetDataPeer] = []
|
var result: [WidgetDataPeer] = []
|
||||||
for (peerId, message) in topMessages.messages {
|
for (peerId, message) in topMessages.messages {
|
||||||
result.append(WidgetDataPeer(id: peerId.toInt64(), name: "", lastName: "", letters: [], avatarPath: nil, badge: nil, message: WidgetDataPeer.Message(message: message)))
|
guard let peer = message.peers[message.id.peerId] else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var name: String = ""
|
||||||
|
var lastName: String?
|
||||||
|
|
||||||
|
if let user = peer as? TelegramUser {
|
||||||
|
if let firstName = user.firstName {
|
||||||
|
name = firstName
|
||||||
|
lastName = user.lastName
|
||||||
|
} else if let lastName = user.lastName {
|
||||||
|
name = lastName
|
||||||
|
} else if let phone = user.phone, !phone.isEmpty {
|
||||||
|
name = phone
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name = peer.debugDisplayTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append(WidgetDataPeer(id: peerId.toInt64(), name: name, lastName: lastName, letters: [], avatarPath: nil, badge: nil, message: WidgetDataPeer.Message(accountPeerId: account.peerId, message: message)))
|
||||||
}
|
}
|
||||||
result.sort(by: { lhs, rhs in
|
result.sort(by: { lhs, rhs in
|
||||||
return lhs.id < rhs.id
|
return lhs.id < rhs.id
|
||||||
|
@ -6,7 +6,7 @@ import TelegramCore
|
|||||||
import WidgetItems
|
import WidgetItems
|
||||||
|
|
||||||
public extension WidgetDataPeer.Message {
|
public extension WidgetDataPeer.Message {
|
||||||
init(message: Message) {
|
init(accountPeerId: PeerId, message: Message) {
|
||||||
var content: WidgetDataPeer.Message.Content = .text
|
var content: WidgetDataPeer.Message.Content = .text
|
||||||
for media in message.media {
|
for media in message.media {
|
||||||
switch media {
|
switch media {
|
||||||
@ -58,11 +58,11 @@ public extension WidgetDataPeer.Message {
|
|||||||
var author: Author?
|
var author: Author?
|
||||||
if let _ = message.peers[message.id.peerId] as? TelegramGroup {
|
if let _ = message.peers[message.id.peerId] as? TelegramGroup {
|
||||||
if let authorPeer = message.author {
|
if let authorPeer = message.author {
|
||||||
author = Author(isMe: false, title: authorPeer.debugDisplayTitle)
|
author = Author(isMe: authorPeer.id == accountPeerId, title: authorPeer.debugDisplayTitle)
|
||||||
}
|
}
|
||||||
} else if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .group = channel.info {
|
} else if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .group = channel.info {
|
||||||
if let authorPeer = message.author {
|
if let authorPeer = message.author {
|
||||||
author = Author(isMe: false, title: authorPeer.debugDisplayTitle)
|
author = Author(isMe: authorPeer.id == accountPeerId, title: authorPeer.debugDisplayTitle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user