Add account switching application shortcut

This commit is contained in:
Ilya Laktyushin 2019-11-21 21:37:21 +04:00
parent 85ab1872ae
commit 4ffb3bc52b
16 changed files with 1346 additions and 1246 deletions

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_lt_user.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -5136,3 +5136,5 @@ Any member of this group will be able to see messages in the channel.";
"Appearance.TextSize.Title" = "Text Size";
"Appearance.TextSize.UseSystem" = "User System Text Size";
"Appearance.TextSize.Apply" = "Set";
"Shortcut.SwitchAccount" = "Switch Account";

View File

@ -0,0 +1,19 @@
load("//Config:buck_rule_macros.bzl", "static_library")
static_library(
name = "AccountUtils",
srcs = glob([
"Sources/**/*.swift",
]),
deps = [
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
"//submodules/Postbox:Postbox#shared",
"//submodules/TelegramCore:TelegramCore#shared",
"//submodules/SyncCore:SyncCore#shared",
"//submodules/AccountContext:AccountContext",
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
],
)

View File

@ -6,7 +6,9 @@ import SyncCore
import TelegramUIPreferences
import AccountContext
func activeAccountsAndPeers(context: AccountContext, includePrimary: Bool = false) -> Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError> {
public let maximumNumberOfAccounts = 3
public func activeAccountsAndPeers(context: AccountContext, includePrimary: Bool = false) -> Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError> {
let sharedContext = context.sharedContext
return context.sharedContext.activeAccounts
|> mapToSignal { primary, activeAccounts, _ -> Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError> in

View File

@ -84,6 +84,7 @@ static_library(
"//submodules/DeleteChatPeerActionSheetItem:DeleteChatPeerActionSheetItem",
"//submodules/PhoneNumberFormat:PhoneNumberFormat",
"//submodules/OpenInExternalAppUI:OpenInExternalAppUI",
"//submodules/AccountUtils:AccountUtils",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",

View File

@ -10,6 +10,7 @@ import ItemListUI
import ItemListPeerItem
import AccountContext
import AppIntents
import AccountUtils
private final class IntentsSettingsControllerArguments {
let context: AccountContext

View File

@ -7,8 +7,7 @@ import SyncCore
import OverlayStatusController
import AccountContext
import PresentationDataUtils
private let maximumNumberOfAccounts = 3
import AccountUtils
func openEditSettings(context: AccountContext, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>, focusOnItemTag: EditSettingsEntryTag? = nil, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void) -> Disposable {
let openEditingDisposable = MetaDisposable()

View File

@ -15,8 +15,7 @@ import CallListUI
import NotificationSoundSelectionUI
import PresentationDataUtils
import PhoneNumberFormat
private let maximumNumberOfAccounts = 3
import AccountUtils
enum SettingsSearchableItemIcon {
case profile

View File

@ -35,8 +35,7 @@ import AppBundle
import ContextUI
import WalletUI
import PhoneNumberFormat
private let maximumNumberOfAccounts = 3
import AccountUtils
private let avatarFont = avatarPlaceholderFont(size: 13.0)

View File

@ -201,6 +201,7 @@ framework(
"//submodules/LocationResources:LocationResources",
"//submodules/ItemListVenueItem:ItemListVenueItem",
"//submodules/SemanticStatusNode:SemanticStatusNode",
"//submodules/AccountUtils:AccountUtils",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",

View File

@ -34,6 +34,7 @@ import OpenSSLEncryptionProvider
import AppLock
import PresentationDataUtils
import AppIntents
import AccountUtils
#if canImport(BackgroundTasks)
import BackgroundTasks
@ -960,14 +961,23 @@ final class SharedApplicationContext {
return true
})
|> mapToSignal { account -> Signal<(Account, LimitsConfiguration, CallListSettings)?, NoError> in
return sharedApplicationContext.sharedContext.accountManager.transaction { transaction -> CallListSettings in
return transaction.getSharedData(ApplicationSpecificSharedDataKeys.callListSettings) as? CallListSettings ?? CallListSettings.defaultSettings
return sharedApplicationContext.sharedContext.accountManager.transaction { transaction -> CallListSettings? in
return transaction.getSharedData(ApplicationSpecificSharedDataKeys.callListSettings) as? CallListSettings
}
|> reduceLeft(value: nil) { current, updated -> CallListSettings? in
var result: CallListSettings?
if let updated = updated {
result = updated
} else if let current = current {
result = current
}
return result
}
|> mapToSignal { callListSettings -> Signal<(Account, LimitsConfiguration, CallListSettings)?, NoError> in
if let account = account {
return account.postbox.transaction { transaction -> (Account, LimitsConfiguration, CallListSettings)? in
let limitsConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
return (account, limitsConfiguration, callListSettings)
return (account, limitsConfiguration, callListSettings ?? CallListSettings.defaultSettings)
}
} else {
return .single(nil)
@ -1243,7 +1253,22 @@ final class SharedApplicationContext {
|> mapToSignal { context -> Signal<[ApplicationShortcutItem], NoError> in
if let context = context {
let presentationData = context.context.sharedContext.currentPresentationData.with { $0 }
return .single(applicationShortcutItems(strings: presentationData.strings))
return activeAccountsAndPeers(context: context.context)
|> take(1)
|> map { primaryAndAccounts -> (Account, Peer, Int32)? in
return primaryAndAccounts.1.first
}
|> map { accountAndPeer -> String? in
if let (_, peer, _) = accountAndPeer {
return peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
} else {
return nil
}
} |> mapToSignal { otherAccountName -> Signal<[ApplicationShortcutItem], NoError> in
let presentationData = context.context.sharedContext.currentPresentationData.with { $0 }
return .single(applicationShortcutItems(strings: presentationData.strings, otherAccountName: otherAccountName))
}
} else {
return .single([])
}
@ -1792,27 +1817,31 @@ final class SharedApplicationContext {
let _ = (self.sharedContextPromise.get()
|> take(1)
|> deliverOnMainQueue).start(next: { sharedContext in
let type = ApplicationShortcutItemType(rawValue: shortcutItem.type)
var immediately = type == .account
let proceed: () -> Void = {
let _ = (self.context.get()
|> take(1)
|> deliverOnMainQueue).start(next: { context in
if let context = context {
if let type = ApplicationShortcutItemType(rawValue: shortcutItem.type) {
if let type = type {
switch type {
case .search:
context.openRootSearch()
case .compose:
context.openRootCompose()
case .camera:
context.openRootCamera()
case .savedMessages:
self.openChatWhenReady(accountId: nil, peerId: context.context.account.peerId)
case .search:
context.openRootSearch()
case .compose:
context.openRootCompose()
case .camera:
context.openRootCamera()
case .savedMessages:
self.openChatWhenReady(accountId: nil, peerId: context.context.account.peerId)
case .account:
context.switchAccount()
}
}
}
})
}
if let appLockContext = sharedContext.sharedContext.appLockContext as? AppLockContextImpl {
if let appLockContext = sharedContext.sharedContext.appLockContext as? AppLockContextImpl, !immediately {
let _ = (appLockContext.isCurrentlyLocked
|> filter { !$0 }
|> take(1)

View File

@ -22,6 +22,7 @@ import ImageBlur
import WatchBridge
import SettingsUI
import AppLock
import AccountUtils
final class UnauthorizedApplicationContext {
let sharedContext: SharedAccountContextImpl
@ -754,6 +755,27 @@ final class AuthorizedApplicationContext {
self.rootController.openRootCamera()
}
func switchAccount() {
let _ = (activeAccountsAndPeers(context: self.context)
|> take(1)
|> map { primaryAndAccounts -> (Account, Peer, Int32)? in
return primaryAndAccounts.1.first
}
|> map { accountAndPeer -> Account? in
if let (account, _, _) = accountAndPeer {
return account
} else {
return nil
}
}
|> deliverOnMainQueue).start(next: { [weak self] account in
guard let strongSelf = self, let account = account else {
return
}
strongSelf.context.sharedContext.switchToAccount(id: account.id, fromSettingsController: nil, withChatListController: nil)
})
}
private func updateCoveringViewSnaphot(_ visible: Bool) {
if visible {
let scale: CGFloat = 0.5

View File

@ -7,11 +7,13 @@ enum ApplicationShortcutItemType: String {
case compose
case camera
case savedMessages
case account
}
struct ApplicationShortcutItem: Equatable {
let type: ApplicationShortcutItemType
let title: String
let subtitle: String?
}
@available(iOS 9.1, *)
@ -27,16 +29,27 @@ extension ApplicationShortcutItem {
icon = UIApplicationShortcutIcon(templateImageName: "Shortcuts/Camera")
case .savedMessages:
icon = UIApplicationShortcutIcon(templateImageName: "Shortcuts/SavedMessages")
case .account:
icon = UIApplicationShortcutIcon(templateImageName: "Shortcuts/Account")
}
return UIApplicationShortcutItem(type: self.type.rawValue, localizedTitle: self.title, localizedSubtitle: nil, icon: icon, userInfo: nil)
return UIApplicationShortcutItem(type: self.type.rawValue, localizedTitle: self.title, localizedSubtitle: self.subtitle, icon: icon, userInfo: nil)
}
}
func applicationShortcutItems(strings: PresentationStrings) -> [ApplicationShortcutItem] {
return [
ApplicationShortcutItem(type: .search, title: strings.Common_Search),
ApplicationShortcutItem(type: .compose, title: strings.Compose_NewMessage),
ApplicationShortcutItem(type: .camera, title: strings.Camera_Title),
ApplicationShortcutItem(type: .savedMessages, title: strings.Conversation_SavedMessages)
]
func applicationShortcutItems(strings: PresentationStrings, otherAccountName: String?) -> [ApplicationShortcutItem] {
if let otherAccountName = otherAccountName {
return [
ApplicationShortcutItem(type: .search, title: strings.Common_Search, subtitle: nil),
ApplicationShortcutItem(type: .compose, title: strings.Compose_NewMessage, subtitle: nil),
ApplicationShortcutItem(type: .savedMessages, title: strings.Conversation_SavedMessages, subtitle: nil),
ApplicationShortcutItem(type: .account, title: strings.Shortcut_SwitchAccount, subtitle: otherAccountName)
]
} else {
return [
ApplicationShortcutItem(type: .search, title: strings.Common_Search, subtitle: nil),
ApplicationShortcutItem(type: .compose, title: strings.Compose_NewMessage, subtitle: nil),
ApplicationShortcutItem(type: .camera, title: strings.Camera_Title, subtitle: nil),
ApplicationShortcutItem(type: .savedMessages, title: strings.Conversation_SavedMessages, subtitle: nil)
]
}
}