Added app update info screen

This commit is contained in:
Ilya Laktyushin 2019-06-29 12:41:52 +02:00
parent 7a71806cf9
commit 971892f941
16 changed files with 296 additions and 57 deletions

View File

@ -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)")

View File

@ -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) }

View File

@ -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

View File

@ -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
}

View File

@ -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())

View File

@ -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

View File

@ -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()
}

View 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
}

View File

@ -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)
}

View File

@ -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 {

View File

@ -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 */,

View File

@ -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)!))

View File

@ -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

View File

@ -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

View 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
}

View File

@ -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 */,