mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Added app update info screen
This commit is contained in:
parent
7a71806cf9
commit
971892f941
@ -230,7 +230,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
postboxLog("Opening \(path), exists: \(exists)")
|
||||
if exists {
|
||||
do {
|
||||
let data = try Data(contentsOf: URL(fileURLWithPath: path))
|
||||
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
|
||||
postboxLog("\(path) size: \(data.count)")
|
||||
} catch let e {
|
||||
postboxLog("Couldn't open database: \(e)")
|
||||
@ -240,7 +240,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
postboxLog("Opening \(path)-wal, exists: \(walExists)")
|
||||
if walExists {
|
||||
do {
|
||||
let data = try Data(contentsOf: URL(fileURLWithPath: path + "-wal"))
|
||||
let data = try Data(contentsOf: URL(fileURLWithPath: path + "-wal"), options: .mappedIfSafe)
|
||||
postboxLog("\(path)-wal size: \(data.count)")
|
||||
} catch let e {
|
||||
postboxLog("Couldn't open database: \(e)")
|
||||
|
@ -101,7 +101,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[997055186] = { return Api.PollAnswerVoters.parse_pollAnswerVoters($0) }
|
||||
dict[-1705233435] = { return Api.account.PasswordSettings.parse_passwordSettings($0) }
|
||||
dict[-288727837] = { return Api.LangPackLanguage.parse_langPackLanguage($0) }
|
||||
dict[-1987579119] = { return Api.help.AppUpdate.parse_appUpdate($0) }
|
||||
dict[497489295] = { return Api.help.AppUpdate.parse_appUpdate($0) }
|
||||
dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) }
|
||||
dict[-209337866] = { return Api.LangPackDifference.parse_langPackDifference($0) }
|
||||
dict[-1590738760] = { return Api.WallPaperSettings.parse_wallPaperSettings($0) }
|
||||
|
@ -1295,19 +1295,26 @@ public struct contacts {
|
||||
public extension Api {
|
||||
public struct help {
|
||||
public enum AppUpdate: TypeConstructorDescription {
|
||||
case appUpdate(id: Int32, critical: Api.Bool, url: String, text: String)
|
||||
case appUpdate(flags: Int32, id: Int32, version: String, text: String, entities: [Api.MessageEntity], document: Api.Document?, url: String?)
|
||||
case noAppUpdate
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .appUpdate(let id, let critical, let url, let text):
|
||||
case .appUpdate(let flags, let id, let version, let text, let entities, let document, let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1987579119)
|
||||
buffer.appendInt32(497489295)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
critical.serialize(buffer, true)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeString(version, buffer: buffer, boxed: false)
|
||||
serializeString(text, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities.count))
|
||||
for item in entities {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 1) != 0 {document!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .noAppUpdate:
|
||||
if boxed {
|
||||
@ -1320,8 +1327,8 @@ public struct help {
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .appUpdate(let id, let critical, let url, let text):
|
||||
return ("appUpdate", [("id", id), ("critical", critical), ("url", url), ("text", text)])
|
||||
case .appUpdate(let flags, let id, let version, let text, let entities, let document, let url):
|
||||
return ("appUpdate", [("flags", flags), ("id", id), ("version", version), ("text", text), ("entities", entities), ("document", document), ("url", url)])
|
||||
case .noAppUpdate:
|
||||
return ("noAppUpdate", [])
|
||||
}
|
||||
@ -1330,20 +1337,31 @@ public struct help {
|
||||
public static func parse_appUpdate(_ reader: BufferReader) -> AppUpdate? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Bool?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
}
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: String?
|
||||
_4 = parseString(reader)
|
||||
var _5: [Api.MessageEntity]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
}
|
||||
var _6: Api.Document?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_7 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.help.AppUpdate.appUpdate(id: _1!, critical: _2!, url: _3!, text: _4!)
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 2) == 0) || _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.help.AppUpdate.appUpdate(flags: _1!, id: _2!, version: _3!, text: _4!, entities: _5!, document: _6, url: _7)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -68,6 +68,8 @@ public final class PresentationCallManager {
|
||||
private var callSettings: VoiceCallSettings?
|
||||
private var callSettingsDisposable: Disposable?
|
||||
|
||||
public var callRequested: ((_ accountPeerId: PeerId, _ peerId: PeerId) -> Void)?
|
||||
|
||||
public static var voipMaxLayer: Int32 {
|
||||
return OngoingCallContext.maxLayer
|
||||
}
|
||||
@ -314,6 +316,8 @@ public final class PresentationCallManager {
|
||||
} else {
|
||||
begin()
|
||||
}
|
||||
|
||||
self.callRequested?(account.peerId, peerId)
|
||||
} else {
|
||||
let begin: () -> Void = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
@ -329,6 +333,7 @@ public final class PresentationCallManager {
|
||||
} else {
|
||||
begin()
|
||||
}
|
||||
self.callRequested?(account.peerId, peerId)
|
||||
}
|
||||
return .requested
|
||||
}
|
||||
|
@ -1297,6 +1297,7 @@ public class Account {
|
||||
self.managedOperationsDisposable.add(managedAppConfigurationUpdates(postbox: self.postbox, network: self.network).start())
|
||||
self.managedOperationsDisposable.add(managedAutodownloadSettingsUpdates(accountManager: accountManager, network: self.network).start())
|
||||
self.managedOperationsDisposable.add(managedTermsOfServiceUpdates(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||
self.managedOperationsDisposable.add(managedAppUpdateInfo(network: self.network, stateManager: self.stateManager).start())
|
||||
self.managedOperationsDisposable.add(managedAppChangelog(postbox: self.postbox, network: self.network, stateManager: self.stateManager, appVersion: self.networkArguments.appVersion).start())
|
||||
self.managedOperationsDisposable.add(managedProxyInfoUpdates(postbox: self.postbox, network: self.network, viewTracker: self.viewTracker).start())
|
||||
self.managedOperationsDisposable.add(managedLocalizationUpdatesOperations(accountManager: accountManager, postbox: self.postbox, network: self.network).start())
|
||||
|
@ -127,6 +127,12 @@ public final class AccountStateManager {
|
||||
return self.termsOfServiceUpdatePromise.get()
|
||||
}
|
||||
|
||||
private let appUpdateInfoValue = Atomic<AppUpdateInfo?>(value: nil)
|
||||
private let appUpdateInfoPromise = Promise<AppUpdateInfo?>(nil)
|
||||
public var appUpdateInfo: Signal<AppUpdateInfo?, NoError> {
|
||||
return self.appUpdateInfoPromise.get()
|
||||
}
|
||||
|
||||
private let appliedIncomingReadMessagesPipe = ValuePipe<[MessageId]>()
|
||||
public var appliedIncomingReadMessages: Signal<[MessageId], NoError> {
|
||||
return self.appliedIncomingReadMessagesPipe.signal()
|
||||
@ -934,6 +940,17 @@ public final class AccountStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
func modifyAppUpdateInfo(_ f: @escaping (AppUpdateInfo?) -> (AppUpdateInfo?)) {
|
||||
self.queue.async {
|
||||
let current = self.appUpdateInfoValue.with { $0 }
|
||||
let updated = f(current)
|
||||
if (current != updated) {
|
||||
let _ = self.appUpdateInfoValue.swap(updated)
|
||||
self.appUpdateInfoPromise.set(.single(updated))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func updatedPeersNearby() -> Signal<[PeerNearby], NoError> {
|
||||
let queue = self.queue
|
||||
return Signal { [weak self] subscriber in
|
||||
|
@ -1122,37 +1122,37 @@ public final class AccountViewTracker {
|
||||
})
|
||||
|
||||
return managed
|
||||
|> map { view -> CallListView in
|
||||
var entries: [CallListViewEntry] = []
|
||||
if !view.entries.isEmpty {
|
||||
var currentMessages: [Message] = []
|
||||
for entry in view.entries {
|
||||
switch entry {
|
||||
case let .hole(index):
|
||||
|> map { view -> CallListView in
|
||||
var entries: [CallListViewEntry] = []
|
||||
if !view.entries.isEmpty {
|
||||
var currentMessages: [Message] = []
|
||||
for entry in view.entries {
|
||||
switch entry {
|
||||
case let .hole(index):
|
||||
if !currentMessages.isEmpty {
|
||||
entries.append(.message(currentMessages[currentMessages.count - 1], currentMessages))
|
||||
currentMessages.removeAll()
|
||||
}
|
||||
//entries.append(.hole(index))
|
||||
case let .message(message):
|
||||
if currentMessages.isEmpty || groupingPredicate(message, currentMessages[currentMessages.count - 1]) {
|
||||
currentMessages.append(message)
|
||||
} else {
|
||||
if !currentMessages.isEmpty {
|
||||
entries.append(.message(currentMessages[currentMessages.count - 1], currentMessages))
|
||||
currentMessages.removeAll()
|
||||
}
|
||||
//entries.append(.hole(index))
|
||||
case let .message(message):
|
||||
if currentMessages.isEmpty || groupingPredicate(message, currentMessages[currentMessages.count - 1]) {
|
||||
currentMessages.append(message)
|
||||
} else {
|
||||
if !currentMessages.isEmpty {
|
||||
entries.append(.message(currentMessages[currentMessages.count - 1], currentMessages))
|
||||
currentMessages.removeAll()
|
||||
}
|
||||
currentMessages.append(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !currentMessages.isEmpty {
|
||||
entries.append(.message(currentMessages[currentMessages.count - 1], currentMessages))
|
||||
currentMessages.removeAll()
|
||||
currentMessages.append(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
return CallListView(entries: entries, earlier: view.earlier, later: view.later)
|
||||
if !currentMessages.isEmpty {
|
||||
entries.append(.message(currentMessages[currentMessages.count - 1], currentMessages))
|
||||
currentMessages.removeAll()
|
||||
}
|
||||
}
|
||||
return CallListView(entries: entries, earlier: view.earlier, later: view.later)
|
||||
}
|
||||
} else {
|
||||
return .never()
|
||||
}
|
||||
|
51
submodules/TelegramCore/TelegramCore/AppUpdate.swift
Normal file
51
submodules/TelegramCore/TelegramCore/AppUpdate.swift
Normal file
@ -0,0 +1,51 @@
|
||||
import Foundation
|
||||
#if os(macOS)
|
||||
import PostboxMac
|
||||
import SwiftSignalKitMac
|
||||
import MtProtoKitMac
|
||||
import TelegramApiMac
|
||||
#else
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
import SwiftSignalKit
|
||||
#if BUCK
|
||||
import MtProtoKit
|
||||
#else
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
#endif
|
||||
|
||||
public struct AppUpdateInfo: Equatable {
|
||||
public let popup: Bool
|
||||
public let version: String
|
||||
public let text: String
|
||||
public let entities: [MessageTextEntity]
|
||||
}
|
||||
|
||||
extension AppUpdateInfo {
|
||||
init?(apiAppUpdate: Api.help.AppUpdate) {
|
||||
switch apiAppUpdate {
|
||||
case let .appUpdate(flags, _, version, text, entities, _, _):
|
||||
self.popup = (flags & (1 << 0)) != 0
|
||||
self.version = version
|
||||
self.text = text
|
||||
self.entities = messageTextEntitiesFromApiEntities(entities)
|
||||
case .noAppUpdate:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func managedAppUpdateInfo(network: Network, stateManager: AccountStateManager) -> Signal<Never, NoError> {
|
||||
let poll = network.request(Api.functions.help.getAppUpdate())
|
||||
|> retryRequest
|
||||
|> mapToSignal { [weak stateManager] result -> Signal<Never, NoError> in
|
||||
let updated = AppUpdateInfo(apiAppUpdate: result)
|
||||
stateManager?.modifyAppUpdateInfo { _ in
|
||||
return updated
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
|
||||
return (poll |> then(.complete() |> suspendAwareDelay(12.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||
}
|
@ -58,15 +58,15 @@ private func createChannel(account: Account, title: String, description: String?
|
||||
account.stateManager.addUpdates(updates)
|
||||
if let message = updates.messages.first, let peerId = apiMessagePeerId(message) {
|
||||
return account.postbox.multiplePeersView([peerId])
|
||||
|> filter { view in
|
||||
return view.peers[peerId] != nil
|
||||
}
|
||||
|> take(1)
|
||||
|> map { _ in
|
||||
return peerId
|
||||
}
|
||||
|> introduceError(CreateChannelError.self)
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||
|> filter { view in
|
||||
return view.peers[peerId] != nil
|
||||
}
|
||||
|> take(1)
|
||||
|> map { _ in
|
||||
return peerId
|
||||
}
|
||||
|> introduceError(CreateChannelError.self)
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ final class ChatHistoryPreloadManager {
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
self.automaticChatListDisposable.set((combineLatest(queue: .mainQueue(), postbox.tailChatListView(groupId: .root, count: 20, summaryComponents: ChatListEntrySummaryComponents()), additionalPeerIds)
|
||||
self.automaticChatListDisposable.set((combineLatest(queue: .mainQueue(), self.postbox.tailChatListView(groupId: .root, count: 20, summaryComponents: ChatListEntrySummaryComponents()), additionalPeerIds)
|
||||
|> delay(1.0, queue: .mainQueue())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] view, additionalPeerIds in
|
||||
guard let strongSelf = self else {
|
||||
|
@ -21,6 +21,7 @@
|
||||
0962E66F21B6147600245FD9 /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0962E66E21B6147600245FD9 /* AppConfiguration.swift */; };
|
||||
0962E67521B6437600245FD9 /* SplitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0962E67421B6437600245FD9 /* SplitTest.swift */; };
|
||||
0962E68121BAA20E00245FD9 /* SearchBotsConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0962E68021BAA20E00245FD9 /* SearchBotsConfiguration.swift */; };
|
||||
09EC0DE922C6825D00E7185B /* AppUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EC0DE822C6825D00E7185B /* AppUpdate.swift */; };
|
||||
09EDAD382213120C0012A50B /* AutodownloadSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EDAD372213120C0012A50B /* AutodownloadSettings.swift */; };
|
||||
09EDAD3A22131D010012A50B /* ManagedAutodownloadSettingsUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EDAD3922131D010012A50B /* ManagedAutodownloadSettingsUpdates.swift */; };
|
||||
9F06831021A40DEC001D8EDB /* NotificationExceptionsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F06830F21A40DEC001D8EDB /* NotificationExceptionsList.swift */; };
|
||||
@ -831,6 +832,7 @@
|
||||
0962E66E21B6147600245FD9 /* AppConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfiguration.swift; sourceTree = "<group>"; };
|
||||
0962E67421B6437600245FD9 /* SplitTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitTest.swift; sourceTree = "<group>"; };
|
||||
0962E68021BAA20E00245FD9 /* SearchBotsConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBotsConfiguration.swift; sourceTree = "<group>"; };
|
||||
09EC0DE822C6825D00E7185B /* AppUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdate.swift; sourceTree = "<group>"; };
|
||||
09EDAD372213120C0012A50B /* AutodownloadSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutodownloadSettings.swift; sourceTree = "<group>"; };
|
||||
09EDAD3922131D010012A50B /* ManagedAutodownloadSettingsUpdates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedAutodownloadSettingsUpdates.swift; sourceTree = "<group>"; };
|
||||
9F06830F21A40DEC001D8EDB /* NotificationExceptionsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationExceptionsList.swift; sourceTree = "<group>"; };
|
||||
@ -1642,6 +1644,7 @@
|
||||
D02B198F21FB1D520094A764 /* RegisterNotificationToken.swift */,
|
||||
D0338742223BD532007A2CE4 /* InitializeAccountAfterLogin.swift */,
|
||||
D0575C2C22B922DF00A71A0E /* DeleteAccount.swift */,
|
||||
09EC0DE822C6825D00E7185B /* AppUpdate.swift */,
|
||||
);
|
||||
name = Account;
|
||||
sourceTree = "<group>";
|
||||
@ -2469,6 +2472,7 @@
|
||||
D0B843871DA6F705005F29E1 /* UpdateCachedPeerData.swift in Sources */,
|
||||
D0E412F1206B9BB700BEE4A2 /* SecureIdPassportValue.swift in Sources */,
|
||||
D03B0D6D1D631AA300955575 /* ContactManagement.swift in Sources */,
|
||||
09EC0DE922C6825D00E7185B /* AppUpdate.swift in Sources */,
|
||||
D03B0D0F1D62255C00955575 /* UpdateMessageService.swift in Sources */,
|
||||
D03B0CF61D62250800955575 /* TelegramMediaFile.swift in Sources */,
|
||||
D03B0CE81D6224AD00955575 /* ViewCountMessageAttribute.swift in Sources */,
|
||||
|
@ -70,12 +70,14 @@ final class AuthorizedApplicationContext {
|
||||
private let termsOfServiceProceedToBotDisposable = MetaDisposable()
|
||||
private let watchNavigateToMessageDisposable = MetaDisposable()
|
||||
private let permissionsDisposable = MetaDisposable()
|
||||
private let appUpdateInfoDisposable = MetaDisposable()
|
||||
|
||||
private var inAppNotificationSettings: InAppNotificationSettings?
|
||||
|
||||
private var isLocked: Bool = true
|
||||
var passcodeController: PasscodeEntryController?
|
||||
|
||||
private var currentAppUpdateInfo: AppUpdateInfo?
|
||||
private var currentTermsOfServiceUpdate: TermsOfServiceUpdate?
|
||||
private var currentPermissionsController: PermissionController?
|
||||
private var currentPermissionsState: PermissionState?
|
||||
@ -511,6 +513,19 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
}))
|
||||
|
||||
self.appUpdateInfoDisposable.set((context.account.stateManager.appUpdateInfo
|
||||
|> deliverOnMainQueue).start(next: { [weak self] appUpdateInfo in
|
||||
guard let strongSelf = self, strongSelf.currentAppUpdateInfo != appUpdateInfo else {
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.currentAppUpdateInfo = appUpdateInfo
|
||||
if let appUpdateInfo = appUpdateInfo {
|
||||
let controller = updateInfoController(context: strongSelf.context, appUpdateInfo: appUpdateInfo)
|
||||
(strongSelf.rootController.viewControllers.last as? ViewController)?.present(controller, in: .window(.root))
|
||||
}
|
||||
}))
|
||||
|
||||
if #available(iOS 10.0, *) {
|
||||
let permissionsPosition = ValuePromise(0, ignoreRepeated: true)
|
||||
self.permissionsDisposable.set((combineLatest(queue: .mainQueue(), requiredPermissions(context: context), permissionUISplitTest(postbox: context.account.postbox), permissionsPosition.get(), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.permissionWarningKey(permission: .contacts)!), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.permissionWarningKey(permission: .notifications)!), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.permissionWarningKey(permission: .cellularData)!))
|
||||
|
@ -429,7 +429,11 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode {
|
||||
return (nodeLayout, { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if let peer = item.topMessage.peers[item.topMessage.id.peerId] {
|
||||
strongSelf.avatarNode.setPeer(account: item.account, theme: item.theme, peer: peer, emptyColor: item.theme.list.mediaPlaceholderColor)
|
||||
var overrideImage: AvatarNodeImageOverride?
|
||||
if peer.isDeleted {
|
||||
overrideImage = .deletedIcon
|
||||
}
|
||||
strongSelf.avatarNode.setPeer(account: item.account, theme: item.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.theme.list.mediaPlaceholderColor)
|
||||
}
|
||||
|
||||
return (strongSelf.avatarNode.ready, { [weak strongSelf] animated in
|
||||
|
@ -264,10 +264,10 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
let viewProcessingQueue = self.viewProcessingQueue
|
||||
|
||||
let callListViewUpdate = self.callListLocationAndType.get()
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { locationAndType in
|
||||
return callListViewForLocationAndType(locationAndType: locationAndType, account: context.account)
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { locationAndType in
|
||||
return callListViewForLocationAndType(locationAndType: locationAndType, account: context.account)
|
||||
}
|
||||
|
||||
let previousView = Atomic<CallListNodeView?>(value: nil)
|
||||
|
||||
@ -332,8 +332,8 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
return preparedCallListNodeViewTransition(from: previous, to: processedView, reason: reason, disableAnimations: false, account: context.account, scrollPosition: update.scrollPosition)
|
||||
|> map({ mappedCallListNodeViewListTransition(account: context.account, showSettings: showSettings, nodeInteraction: nodeInteraction, transition: $0) })
|
||||
|> runOn(prepareOnMainQueue ? Queue.mainQueue() : viewProcessingQueue)
|
||||
|> map({ mappedCallListNodeViewListTransition(account: context.account, showSettings: showSettings, nodeInteraction: nodeInteraction, transition: $0) })
|
||||
|> runOn(prepareOnMainQueue ? Queue.mainQueue() : viewProcessingQueue)
|
||||
}
|
||||
|
||||
let appliedTransition = callListNodeViewTransition |> deliverOnMainQueue |> mapToQueue { [weak self] transition -> Signal<Void, NoError> in
|
||||
|
112
submodules/TelegramUI/TelegramUI/UpdateInfoController.swift
Normal file
112
submodules/TelegramUI/TelegramUI/UpdateInfoController.swift
Normal file
@ -0,0 +1,112 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
|
||||
private final class UpdateInfoControllerArguments {
|
||||
let openAppStorePage: () -> Void
|
||||
|
||||
init(openAppStorePage: @escaping () -> Void) {
|
||||
self.openAppStorePage = openAppStorePage
|
||||
}
|
||||
}
|
||||
|
||||
private enum UpdateInfoControllerSection: Int32 {
|
||||
case info
|
||||
case update
|
||||
}
|
||||
|
||||
private enum UpdateInfoControllerEntry: ItemListNodeEntry {
|
||||
case info(PresentationTheme, String, String, [MessageTextEntity])
|
||||
case update(PresentationTheme, String)
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .info:
|
||||
return UpdateInfoControllerSection.info.rawValue
|
||||
case .update:
|
||||
return UpdateInfoControllerSection.update.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
var stableId: Int32 {
|
||||
switch self {
|
||||
case .info:
|
||||
return 0
|
||||
case .update:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
static func ==(lhs: UpdateInfoControllerEntry, rhs: UpdateInfoControllerEntry) -> Bool {
|
||||
switch lhs {
|
||||
case let .info(lhsTheme, lhsTitle, lhsText, lhsEntities):
|
||||
if case let .info(rhsTheme, rhsTitle, rhsText, rhsEntities) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsText == rhsText, lhsEntities == rhsEntities {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .update(lhsTheme, lhsTitle):
|
||||
if case let .update(rhsTheme, rhsTitle) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func <(lhs: UpdateInfoControllerEntry, rhs: UpdateInfoControllerEntry) -> Bool {
|
||||
return lhs.stableId < rhs.stableId
|
||||
}
|
||||
|
||||
func item(_ arguments: UpdateInfoControllerArguments) -> ListViewItem {
|
||||
switch self {
|
||||
case let .info(theme, title, text, entities):
|
||||
let text = stringWithAppliedEntities(text, entities: entities, baseColor: theme.list.itemPrimaryTextColor, linkColor: theme.list.itemAccentColor, baseFont: Font.regular(14.0), linkFont: Font.regular(14.0), boldFont: Font.bold(14.0), italicFont: Font.italic(14.0), boldItalicFont: Font.semiboldItalic(14.0), fixedFont: Font.monospace(14.0))
|
||||
return ItemListSectionHeaderItem(theme: theme, text: text.string, sectionId: self.section)
|
||||
case let .update(theme, title):
|
||||
return ItemListActionItem(theme: theme, title: title, kind: .generic, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openAppStorePage()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateInfoControllerEntries(theme: PresentationTheme, strings: PresentationStrings, appUpdateInfo: AppUpdateInfo) -> [UpdateInfoControllerEntry] {
|
||||
var entries: [UpdateInfoControllerEntry] = []
|
||||
|
||||
entries.append(.info(theme, strings.Update_AppVersion(appUpdateInfo.version).0, appUpdateInfo.text, appUpdateInfo.entities))
|
||||
entries.append(.update(theme, strings.Update_UpdateApp))
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
public func updateInfoController(context: AccountContext, appUpdateInfo: AppUpdateInfo) -> ViewController {
|
||||
var dismissImpl: (() -> Void)?
|
||||
|
||||
let arguments = UpdateInfoControllerArguments(openAppStorePage: {
|
||||
context.sharedContext.applicationBindings.openAppStorePage()
|
||||
})
|
||||
|
||||
let signal = context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData -> (ItemListControllerState, (ItemListNodeState<UpdateInfoControllerEntry>, UpdateInfoControllerEntry.ItemGenerationArguments)) in
|
||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Update_Skip), style: .regular, enabled: true, action: {
|
||||
dismissImpl?()
|
||||
})
|
||||
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Update_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let listState = ItemListNodeState(entries: updateInfoControllerEntries(theme: presentationData.theme, strings: presentationData.strings, appUpdateInfo: appUpdateInfo), style: .blocks, animateChanges: false)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
||||
let controller = ItemListController(sharedContext: context.sharedContext, state: signal)
|
||||
dismissImpl = { [weak controller] in
|
||||
controller?.view.endEditing(true)
|
||||
controller?.dismiss()
|
||||
}
|
||||
return controller
|
||||
}
|
@ -151,6 +151,7 @@
|
||||
09E4A803223B833B0038140F /* ForwardPrivacyChatPreviewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A802223B833B0038140F /* ForwardPrivacyChatPreviewItem.swift */; };
|
||||
09E4A805223D4A5A0038140F /* OpenSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A804223D4A5A0038140F /* OpenSettings.swift */; };
|
||||
09E4A807223D4B860038140F /* AccountUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A806223D4B860038140F /* AccountUtils.swift */; };
|
||||
09EC0DE722C67FB100E7185B /* UpdateInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EC0DE622C67FB100E7185B /* UpdateInfoController.swift */; };
|
||||
09EDAD26220D30980012A50B /* AutodownloadConnectionTypeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EDAD25220D30980012A50B /* AutodownloadConnectionTypeController.swift */; };
|
||||
09EDAD2A220DA6A40012A50B /* VolumeButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EDAD29220DA6A40012A50B /* VolumeButtons.swift */; };
|
||||
09EDAD2C2211552F0012A50B /* AutodownloadMediaCategoryController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EDAD2B2211552F0012A50B /* AutodownloadMediaCategoryController.swift */; };
|
||||
@ -1370,6 +1371,7 @@
|
||||
09E4A802223B833B0038140F /* ForwardPrivacyChatPreviewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardPrivacyChatPreviewItem.swift; sourceTree = "<group>"; };
|
||||
09E4A804223D4A5A0038140F /* OpenSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSettings.swift; sourceTree = "<group>"; };
|
||||
09E4A806223D4B860038140F /* AccountUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountUtils.swift; sourceTree = "<group>"; };
|
||||
09EC0DE622C67FB100E7185B /* UpdateInfoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateInfoController.swift; sourceTree = "<group>"; };
|
||||
09EDAD25220D30980012A50B /* AutodownloadConnectionTypeController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutodownloadConnectionTypeController.swift; sourceTree = "<group>"; };
|
||||
09EDAD29220DA6A40012A50B /* VolumeButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeButtons.swift; sourceTree = "<group>"; };
|
||||
09EDAD2B2211552F0012A50B /* AutodownloadMediaCategoryController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutodownloadMediaCategoryController.swift; sourceTree = "<group>"; };
|
||||
@ -2771,6 +2773,14 @@
|
||||
name = UI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
09EC0DE522C67F8900E7185B /* Update */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
09EC0DE622C67FB100E7185B /* UpdateInfoController.swift */,
|
||||
);
|
||||
name = Update;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
09F215982263E61400AEDF6D /* Passcode */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4565,6 +4575,7 @@
|
||||
D0F69DE61D6B8A4E0046BCD6 /* Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
09EC0DE522C67F8900E7185B /* Update */,
|
||||
D0F69DE71D6B8A590046BCD6 /* Authorization */,
|
||||
D05174C11EAE582A00A1BF36 /* Root */,
|
||||
D0F69DF61D6B8A720046BCD6 /* Chat List */,
|
||||
@ -5434,6 +5445,7 @@
|
||||
D05D8B3F2192FC6E0064586F /* LocalizationListControllerNode.swift in Sources */,
|
||||
D0EC6CE21EB9F58800EBF1C3 /* PresentationResourcesChatList.swift in Sources */,
|
||||
D0EC6CE31EB9F58800EBF1C3 /* PresentationResourcesChat.swift in Sources */,
|
||||
09EC0DE722C67FB100E7185B /* UpdateInfoController.swift in Sources */,
|
||||
D0AA840C1FEB2BA3005C6E91 /* OverlayPlayerControlsNode.swift in Sources */,
|
||||
09DD5D5021ECC3C400D7007A /* SuppressContactsWarning.swift in Sources */,
|
||||
D02B198A21F1DA9E0094A764 /* SharedAccountContext.swift in Sources */,
|
||||
|
Loading…
x
Reference in New Issue
Block a user