mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
2c697b8b79
26 changed files with 209 additions and 61 deletions
4
BUCK
4
BUCK
|
|
@ -48,8 +48,8 @@ resource_dependencies = [
|
|||
"//submodules/LegacyComponents:LegacyComponentsResources",
|
||||
"//submodules/TelegramUI:TelegramUIAssets",
|
||||
"//submodules/TelegramUI:TelegramUIResources",
|
||||
"//submodules/WalletUI:WalletUIAssets",
|
||||
"//submodules/WalletUI:WalletUIResources",
|
||||
#"//submodules/WalletUI:WalletUIAssets",
|
||||
#"//submodules/WalletUI:WalletUIResources",
|
||||
"//submodules/PasswordSetupUI:PasswordSetupUIResources",
|
||||
"//submodules/PasswordSetupUI:PasswordSetupUIAssets",
|
||||
"//submodules/OverlayStatusController:OverlayStatusControllerResources",
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -3,7 +3,7 @@
|
|||
include Utils.makefile
|
||||
|
||||
BUCK_OPTIONS=\
|
||||
--config custom.appVersion="5.14.1" \
|
||||
--config custom.appVersion="5.15" \
|
||||
--config custom.developmentCodeSignIdentity="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \
|
||||
--config custom.distributionCodeSignIdentity="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \
|
||||
--config custom.developmentTeam="${DEVELOPMENT_TEAM}" \
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ static_library(
|
|||
"//submodules/Postbox:Postbox#shared",
|
||||
"//submodules/TelegramCore:TelegramCore#shared",
|
||||
"//submodules/SyncCore:SyncCore#shared",
|
||||
"//submodules/WalletCore:WalletCore",
|
||||
#"//submodules/WalletCore:WalletCore",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ import SwiftSignalKit
|
|||
import Display
|
||||
import DeviceLocationManager
|
||||
import TemporaryCachedPeerDataManager
|
||||
|
||||
#if ENABLE_WALLET
|
||||
import WalletCore
|
||||
#endif
|
||||
|
||||
public final class TelegramApplicationOpenUrlCompletion {
|
||||
public let completion: (Bool) -> Void
|
||||
|
|
@ -175,7 +178,9 @@ public enum ResolvedUrl {
|
|||
case share(url: String?, text: String?, to: String?)
|
||||
case wallpaper(WallpaperUrlParameter)
|
||||
case theme(String)
|
||||
#if ENABLE_WALLET
|
||||
case wallet(address: String, amount: Int64?, comment: String?)
|
||||
#endif
|
||||
case settings(ResolvedUrlSettingsSection)
|
||||
}
|
||||
|
||||
|
|
@ -380,10 +385,12 @@ public final class ContactSelectionControllerParams {
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_WALLET
|
||||
public enum OpenWalletContext {
|
||||
case generic
|
||||
case send(address: String, amount: Int64?, comment: String?)
|
||||
}
|
||||
#endif
|
||||
|
||||
public let defaultContactLabel: String = "_$!<Mobile>!$_"
|
||||
|
||||
|
|
@ -466,7 +473,9 @@ public protocol SharedAccountContext: class {
|
|||
func openAddContact(context: AccountContext, firstName: String, lastName: String, phoneNumber: String, label: String, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void)
|
||||
func openAddPersonContact(context: AccountContext, peerId: PeerId, pushController: @escaping (ViewController) -> Void, present: @escaping (ViewController, Any?) -> Void)
|
||||
func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void)
|
||||
#if ENABLE_WALLET
|
||||
func openWallet(context: AccountContext, walletContext: OpenWalletContext, present: @escaping (ViewController) -> Void)
|
||||
#endif
|
||||
func openImagePicker(context: AccountContext, completion: @escaping (UIImage) -> Void, present: @escaping (ViewController) -> Void)
|
||||
|
||||
func makeRecentSessionsController(context: AccountContext, activeSessionsContext: ActiveSessionsContext) -> ViewController & RecentSessionsController
|
||||
|
|
@ -479,6 +488,7 @@ public protocol SharedAccountContext: class {
|
|||
func beginNewAuth(testingEnvironment: Bool)
|
||||
}
|
||||
|
||||
#if ENABLE_WALLET
|
||||
private final class TonInstanceData {
|
||||
var config: String?
|
||||
var blockchainName: String?
|
||||
|
|
@ -543,10 +553,15 @@ public final class TonContext {
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public protocol AccountContext: class {
|
||||
var sharedContext: SharedAccountContext { get }
|
||||
var account: Account { get }
|
||||
|
||||
#if ENABLE_WALLET
|
||||
var tonContext: StoredTonContext? { get }
|
||||
#endif
|
||||
|
||||
var liveLocationManager: LiveLocationManager? { get }
|
||||
var fetchManager: FetchManager { get }
|
||||
|
|
@ -554,8 +569,11 @@ public protocol AccountContext: class {
|
|||
var peerChannelMemberCategoriesContextsManager: PeerChannelMemberCategoriesContextsManager { get }
|
||||
var wallpaperUploadManager: WallpaperUploadManager? { get }
|
||||
var watchManager: WatchManager? { get }
|
||||
|
||||
#if ENABLE_WALLET
|
||||
var hasWallets: Signal<Bool, NoError> { get }
|
||||
var hasWalletAccess: Signal<Bool, NoError> { get }
|
||||
#endif
|
||||
|
||||
var currentLimitsConfiguration: Atomic<LimitsConfiguration> { get }
|
||||
var currentContentSettings: Atomic<ContentSettings> { get }
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static_library(
|
|||
"//submodules/InstantPageCache:InstantPageCache",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/ContextUI:ContextUI",
|
||||
"//submodules/WalletUI:WalletUI",
|
||||
#"//submodules/WalletUI:WalletUI",
|
||||
"//submodules/Markdown:Markdown",
|
||||
"//submodules/UndoUI:UndoUI",
|
||||
"//submodules/DeleteChatPeerActionSheetItem:DeleteChatPeerActionSheetItem",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import ItemListUI
|
|||
import PresentationDataUtils
|
||||
import OverlayStatusController
|
||||
import AccountContext
|
||||
import WalletUI
|
||||
|
||||
@objc private final class DebugControllerMailComposeDelegate: NSObject, MFMailComposeViewControllerDelegate {
|
||||
public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
|
||||
|
|
|
|||
|
|
@ -219,7 +219,11 @@ func logoutOptionsController(context: AccountContext, navigationController: Navi
|
|||
presentControllerImpl?(alertController, nil)
|
||||
})
|
||||
|
||||
#if ENABLE_WALLET
|
||||
let hasWallets = context.hasWallets
|
||||
#else
|
||||
let hasWallets: Signal<Bool, NoError> = .single(false)
|
||||
#endif
|
||||
|
||||
let signal = combineLatest(queue: .mainQueue(),
|
||||
context.sharedContext.presentationData,
|
||||
|
|
|
|||
|
|
@ -882,6 +882,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
|
|||
})
|
||||
allItems.append(passport)
|
||||
|
||||
#if ENABLE_WALLET
|
||||
if hasWallet {
|
||||
let wallet = SettingsSearchableItem(id: .wallet(0), title: strings.Settings_Wallet, alternate: synonyms(strings.SettingsSearch_Synonyms_Wallet), icon: .wallet, breadcrumbs: [], present: { context, _, present in
|
||||
context.sharedContext.openWallet(context: context, walletContext: .generic, present: { c in
|
||||
|
|
@ -890,6 +891,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
|
|||
})
|
||||
allItems.append(wallet)
|
||||
}
|
||||
#endif
|
||||
|
||||
let support = SettingsSearchableItem(id: .support(0), title: strings.Settings_Support, alternate: synonyms(strings.SettingsSearch_Synonyms_Support), icon: .support, breadcrumbs: [], present: { context, _, present in
|
||||
let _ = (supportPeerId(account: context.account)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ import PeerAvatarGalleryUI
|
|||
import MapResourceToAvatarSizes
|
||||
import AppBundle
|
||||
import ContextUI
|
||||
#if ENABLE_WALLET
|
||||
import WalletUI
|
||||
#endif
|
||||
import PhoneNumberFormat
|
||||
import AccountUtils
|
||||
import AuthTransferUI
|
||||
|
|
@ -220,7 +222,9 @@ private indirect enum SettingsEntry: ItemListNodeEntry {
|
|||
case themes(PresentationTheme, UIImage?, String)
|
||||
case language(PresentationTheme, UIImage?, String, String)
|
||||
case passport(PresentationTheme, UIImage?, String, String)
|
||||
#if ENABLE_WALLET
|
||||
case wallet(PresentationTheme, UIImage?, String, String)
|
||||
#endif
|
||||
case watch(PresentationTheme, UIImage?, String, String)
|
||||
|
||||
case askAQuestion(PresentationTheme, UIImage?, String)
|
||||
|
|
@ -242,8 +246,12 @@ private indirect enum SettingsEntry: ItemListNodeEntry {
|
|||
return SettingsSection.media.rawValue
|
||||
case .notificationsAndSounds, .privacyAndSecurity, .dataAndStorage, .themes, .language, .contentStickers:
|
||||
return SettingsSection.generalSettings.rawValue
|
||||
case .passport, .wallet, .watch :
|
||||
case .passport, .watch:
|
||||
return SettingsSection.advanced.rawValue
|
||||
#if ENABLE_WALLET
|
||||
case .wallet:
|
||||
return SettingsSection.advanced.rawValue
|
||||
#endif
|
||||
case .askAQuestion, .faq:
|
||||
return SettingsSection.help.rawValue
|
||||
}
|
||||
|
|
@ -289,8 +297,10 @@ private indirect enum SettingsEntry: ItemListNodeEntry {
|
|||
return 1012
|
||||
case .contentStickers:
|
||||
return 1013
|
||||
#if ENABLE_WALLET
|
||||
case .wallet:
|
||||
return 1014
|
||||
#endif
|
||||
case .passport:
|
||||
return 1015
|
||||
case .watch:
|
||||
|
|
@ -456,12 +466,14 @@ private indirect enum SettingsEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
#if ENABLE_WALLET
|
||||
case let .wallet(lhsTheme, lhsImage, lhsText, lhsValue):
|
||||
if case let .wallet(rhsTheme, rhsImage, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
#endif
|
||||
case let .watch(lhsTheme, lhsImage, lhsText, lhsValue):
|
||||
if case let .watch(rhsTheme, rhsImage, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
|
|
@ -595,10 +607,12 @@ private indirect enum SettingsEntry: ItemListNodeEntry {
|
|||
return ItemListDisclosureItem(presentationData: presentationData, icon: image, title: text, label: value, sectionId: ItemListSectionId(self.section), style: .blocks, action: {
|
||||
arguments.openPassport()
|
||||
})
|
||||
#if ENABLE_WALLET
|
||||
case let .wallet(theme, image, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: image, title: text, label: value, sectionId: ItemListSectionId(self.section), style: .blocks, action: {
|
||||
arguments.openWallet()
|
||||
})
|
||||
#endif
|
||||
case let .watch(theme, image, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: image, title: text, label: value, sectionId: ItemListSectionId(self.section), style: .blocks, action: {
|
||||
arguments.openWatch()
|
||||
|
|
@ -684,9 +698,11 @@ private func settingsEntries(account: Account, presentationData: PresentationDat
|
|||
entries.append(.language(presentationData.theme, PresentationResourcesSettings.language, presentationData.strings.Settings_AppLanguage, languageName.isEmpty ? presentationData.strings.Localization_LanguageName : languageName))
|
||||
entries.append(.contentStickers(presentationData.theme, PresentationResourcesSettings.stickers, presentationData.strings.ChatSettings_Stickers, unreadTrendingStickerPacks == 0 ? "" : "\(unreadTrendingStickerPacks)", archivedPacks))
|
||||
|
||||
#if ENABLE_WALLET
|
||||
if hasWallet {
|
||||
entries.append(.wallet(presentationData.theme, PresentationResourcesSettings.wallet, "Gram Wallet", ""))
|
||||
}
|
||||
#endif
|
||||
if hasPassport {
|
||||
entries.append(.passport(presentationData.theme, PresentationResourcesSettings.passport, presentationData.strings.Settings_Passport, ""))
|
||||
}
|
||||
|
|
@ -988,6 +1004,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|
|||
pushControllerImpl?(SecureIdAuthController(context: context, mode: .list))
|
||||
})
|
||||
}, openWallet: {
|
||||
#if ENABLE_WALLET
|
||||
let _ = (contextValue.get()
|
||||
|> deliverOnMainQueue
|
||||
|> take(1)).start(next: { context in
|
||||
|
|
@ -995,6 +1012,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|
|||
pushControllerImpl?(c)
|
||||
})
|
||||
})
|
||||
#endif
|
||||
}, openWatch: {
|
||||
let _ = (contextValue.get()
|
||||
|> deliverOnMainQueue
|
||||
|
|
@ -1251,11 +1269,14 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|
|||
}
|
||||
)
|
||||
)
|
||||
|
||||
#if ENABLE_WALLET
|
||||
let hasWallet = contextValue.get()
|
||||
|> mapToSignal { context in
|
||||
return context.hasWalletAccess
|
||||
}
|
||||
#else
|
||||
let hasWallet: Signal<Bool, NoError> = .single(false)
|
||||
#endif
|
||||
|
||||
let hasPassport = ValuePromise<Bool>(false)
|
||||
let updatePassport: () -> Void = {
|
||||
|
|
|
|||
|
|
@ -186,8 +186,8 @@ framework(
|
|||
"//submodules/MessageReactionListUI:MessageReactionListUI",
|
||||
"//submodules/SegmentedControlNode:SegmentedControlNode",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/WalletUI:WalletUI",
|
||||
"//submodules/WalletCore:WalletCore",
|
||||
#"//submodules/WalletUI:WalletUI",
|
||||
#"//submodules/WalletCore:WalletCore",
|
||||
"//submodules/Markdown:Markdown",
|
||||
"//submodules/SearchPeerMembers:SearchPeerMembers",
|
||||
"//submodules/WidgetItems:WidgetItems",
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import TelegramPresentationData
|
|||
import AccountContext
|
||||
import LiveLocationManager
|
||||
import TemporaryCachedPeerDataManager
|
||||
#if ENABLE_WALLET
|
||||
import WalletCore
|
||||
import WalletUI
|
||||
#endif
|
||||
import PhoneNumberFormat
|
||||
|
||||
private final class DeviceSpecificContactImportContext {
|
||||
|
|
@ -106,7 +108,9 @@ public final class AccountContextImpl: AccountContext {
|
|||
}
|
||||
public let account: Account
|
||||
|
||||
#if ENABLE_WALLET
|
||||
public let tonContext: StoredTonContext?
|
||||
#endif
|
||||
|
||||
public let fetchManager: FetchManager
|
||||
private let prefetchManager: PrefetchManager?
|
||||
|
|
@ -142,6 +146,7 @@ public final class AccountContextImpl: AccountContext {
|
|||
private let deviceSpecificContactImportContexts: QueueLocalObject<DeviceSpecificContactImportContexts>
|
||||
private var managedAppSpecificContactsDisposable: Disposable?
|
||||
|
||||
#if ENABLE_WALLET
|
||||
public var hasWallets: Signal<Bool, NoError> {
|
||||
return WalletStorageInterfaceImpl(postbox: self.account.postbox).getWalletRecords()
|
||||
|> map { records in
|
||||
|
|
@ -164,11 +169,15 @@ public final class AccountContextImpl: AccountContext {
|
|||
}
|
||||
|> distinctUntilChanged
|
||||
}
|
||||
#endif
|
||||
|
||||
public init(sharedContext: SharedAccountContextImpl, account: Account, tonContext: StoredTonContext?, limitsConfiguration: LimitsConfiguration, contentSettings: ContentSettings, temp: Bool = false) {
|
||||
public init(sharedContext: SharedAccountContextImpl, account: Account, /*tonContext: StoredTonContext?, */limitsConfiguration: LimitsConfiguration, contentSettings: ContentSettings, temp: Bool = false)
|
||||
{
|
||||
self.sharedContextImpl = sharedContext
|
||||
self.account = account
|
||||
#if ENABLE_WALLET
|
||||
self.tonContext = tonContext
|
||||
#endif
|
||||
|
||||
self.downloadedMediaStoreManager = DownloadedMediaStoreManagerImpl(postbox: account.postbox, accountManager: sharedContext.accountManager)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,14 @@ import WatchBridge
|
|||
import LegacyDataImport
|
||||
import SettingsUI
|
||||
import AppBundle
|
||||
#if ENABLE_WALLET
|
||||
import WalletUI
|
||||
#endif
|
||||
import UrlHandling
|
||||
#if ENABLE_WALLET
|
||||
import WalletUrl
|
||||
import WalletCore
|
||||
#endif
|
||||
import OpenSSLEncryptionProvider
|
||||
import AppLock
|
||||
import PresentationDataUtils
|
||||
|
|
@ -681,6 +685,7 @@ final class SharedApplicationContext {
|
|||
})
|
||||
}
|
||||
|
||||
#if ENABLE_WALLET
|
||||
let tonKeychain: TonKeychain
|
||||
|
||||
#if targetEnvironment(simulator)
|
||||
|
|
@ -742,6 +747,7 @@ final class SharedApplicationContext {
|
|||
}
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
let sharedContextSignal = accountManagerSignal
|
||||
|> deliverOnMainQueue
|
||||
|
|
@ -1004,8 +1010,10 @@ final class SharedApplicationContext {
|
|||
|> deliverOnMainQueue
|
||||
|> map { accountAndSettings -> AuthorizedApplicationContext? in
|
||||
return accountAndSettings.flatMap { account, limitsConfiguration, callListSettings, contentSettings in
|
||||
#if ENABLE_WALLET
|
||||
let tonContext = StoredTonContext(basePath: account.basePath, postbox: account.postbox, network: account.network, keychain: tonKeychain)
|
||||
let context = AccountContextImpl(sharedContext: sharedApplicationContext.sharedContext, account: account, tonContext: tonContext, limitsConfiguration: limitsConfiguration, contentSettings: contentSettings)
|
||||
#endif
|
||||
let context = AccountContextImpl(sharedContext: sharedApplicationContext.sharedContext, account: account/*, tonContext: tonContext*/, limitsConfiguration: limitsConfiguration, contentSettings: contentSettings)
|
||||
return AuthorizedApplicationContext(sharedApplicationContext: sharedApplicationContext, mainWindow: self.mainWindow, watchManagerArguments: watchManagerArgumentsPromise.get(), context: context, accountManager: sharedApplicationContext.sharedContext.accountManager, showCallsTab: callListSettings.showTab, reinitializedNotificationSettings: {
|
||||
let _ = (self.context.get()
|
||||
|> take(1)
|
||||
|
|
@ -1706,10 +1714,13 @@ final class SharedApplicationContext {
|
|||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), on: .root, blockInteraction: false, completion: {})
|
||||
} else if let confirmationCode = parseConfirmationCodeUrl(url) {
|
||||
authContext.rootController.applyConfirmationCode(confirmationCode)
|
||||
} else if let _ = parseWalletUrl(url) {
|
||||
}
|
||||
#if ENABLE_WALLET
|
||||
if let _ = parseWalletUrl(url) {
|
||||
let presentationData = authContext.sharedContext.currentPresentationData.with { $0 }
|
||||
authContext.rootController.currentWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "Please log in to your account to use Gram Wallet.", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), on: .root, blockInteraction: false, completion: {})
|
||||
}
|
||||
#endif
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,10 @@ import ReactionSelectionNode
|
|||
import AvatarNode
|
||||
import MessageReactionListUI
|
||||
import AppBundle
|
||||
#if ENABLE_WALLET
|
||||
import WalletUI
|
||||
import WalletUrl
|
||||
#endif
|
||||
import LocalizedPeerData
|
||||
import PhoneNumberFormat
|
||||
import SettingsUI
|
||||
|
|
@ -5786,9 +5788,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if let strongSelf = self {
|
||||
if let (host, port, username, password, secret) = parseProxyUrl(code) {
|
||||
strongSelf.openResolved(ResolvedUrl.proxy(host: host, port: port, username: username, password: password, secret: secret))
|
||||
} else if let url = URL(string: code), let parsedWalletUrl = parseWalletUrl(url) {
|
||||
}/* else if let url = URL(string: code), let parsedWalletUrl = parseWalletUrl(url) {
|
||||
//strongSelf.openResolved(ResolvedUrl.wallet(address: parsedWalletUrl.address, amount: parsedWalletUrl.amount, comment: parsedWalletUrl.comment))
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}, presentSchedulePicker: { [weak self] done in
|
||||
if let strongSelf = self {
|
||||
|
|
|
|||
|
|
@ -815,8 +815,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||
break
|
||||
case .theme:
|
||||
break
|
||||
#if ENABLE_WALLET
|
||||
case .wallet:
|
||||
break
|
||||
#endif
|
||||
case .settings:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ private final class MultiScaleTextStateNode: ASDisplayNode {
|
|||
|
||||
override init() {
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
super.init()
|
||||
|
||||
|
|
@ -44,20 +45,36 @@ final class MultiScaleTextNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
func updateLayout(states: [AnyHashable: MultiScaleTextState]) -> [AnyHashable: MultiScaleTextLayout] {
|
||||
func stateNode(forKey key: AnyHashable) -> ASDisplayNode? {
|
||||
return self.stateNodes[key]?.textNode
|
||||
}
|
||||
|
||||
func updateLayout(states: [AnyHashable: MultiScaleTextState], mainState: AnyHashable) -> [AnyHashable: MultiScaleTextLayout] {
|
||||
assert(Set(states.keys) == Set(self.stateNodes.keys))
|
||||
assert(states[mainState] != nil)
|
||||
|
||||
var result: [AnyHashable: MultiScaleTextLayout] = [:]
|
||||
var mainLayout: MultiScaleTextLayout?
|
||||
for (key, state) in states {
|
||||
if let node = self.stateNodes[key] {
|
||||
node.textNode.attributedText = state.attributedText
|
||||
let nodeSize = node.textNode.updateLayout(state.constrainedSize)
|
||||
let nodeLayout = MultiScaleTextLayout(size: nodeSize)
|
||||
if key == mainState {
|
||||
mainLayout = nodeLayout
|
||||
}
|
||||
node.currentLayout = nodeLayout
|
||||
node.textNode.frame = CGRect(origin: CGPoint(x: -nodeSize.width / 2.0, y: -nodeSize.height / 2.0), size: nodeSize)
|
||||
result[key] = nodeLayout
|
||||
}
|
||||
}
|
||||
if let mainLayout = mainLayout {
|
||||
let mainBounds = CGRect(origin: CGPoint(x: -mainLayout.size.width / 2.0, y: -mainLayout.size.height / 2.0), size: mainLayout.size)
|
||||
for (key, _) in states {
|
||||
if let node = self.stateNodes[key], let nodeLayout = result[key] {
|
||||
node.textNode.frame = CGRect(origin: CGPoint(x: mainBounds.minX, y: mainBounds.minY + floor((mainBounds.height - nodeLayout.size.height) / 2.0)), size: nodeLayout.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -371,11 +371,13 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||
present(textAlertController(context: context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
}))
|
||||
dismissInput()
|
||||
#if ENABLE_WALLET
|
||||
case let .wallet(address, amount, comment):
|
||||
dismissInput()
|
||||
context.sharedContext.openWallet(context: context, walletContext: .send(address: address, amount: amount, comment: comment)) { c in
|
||||
navigationController?.pushViewController(c)
|
||||
}
|
||||
#endif
|
||||
case let .settings(section):
|
||||
dismissInput()
|
||||
switch section {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ import AccountContext
|
|||
import UrlEscaping
|
||||
import PassportUI
|
||||
import UrlHandling
|
||||
#if ENABLE_WALLET
|
||||
import WalletUI
|
||||
import WalletUrl
|
||||
#endif
|
||||
import OpenInExternalAppUI
|
||||
|
||||
public struct ParsedSecureIdUrl {
|
||||
|
|
@ -144,6 +146,7 @@ func formattedConfirmationCode(_ code: Int) -> String {
|
|||
}
|
||||
|
||||
func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void) {
|
||||
#if ENABLE_WALLET
|
||||
if url.hasPrefix("ton://") {
|
||||
if let url = URL(string: url), let parsedUrl = parseWalletUrl(url) {
|
||||
context.sharedContext.openWallet(context: context, walletContext: .send(address: parsedUrl.address, amount: parsedUrl.amount, comment: parsedUrl.comment)) { c in
|
||||
|
|
@ -153,6 +156,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||
|
||||
return
|
||||
}
|
||||
#endif
|
||||
|
||||
if forceExternal || url.lowercased().hasPrefix("tel:") || url.lowercased().hasPrefix("calshow:") {
|
||||
context.sharedContext.applicationBindings.openUrl(url)
|
||||
|
|
|
|||
|
|
@ -600,7 +600,7 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
|||
if hadOneStripNode && self.stripNodes.count > 1 {
|
||||
self.stripContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
}
|
||||
let stripInset: CGFloat = 5.0
|
||||
let stripInset: CGFloat = 8.0
|
||||
let stripSpacing: CGFloat = 4.0
|
||||
let stripWidth: CGFloat = max(5.0, floor((size.width - stripInset * 2.0 - stripSpacing * CGFloat(self.stripNodes.count - 1)) / CGFloat(self.stripNodes.count)))
|
||||
var stripX: CGFloat = stripInset
|
||||
|
|
@ -610,7 +610,7 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
|||
} else {
|
||||
self.stripNodes[i].isHidden = false
|
||||
}
|
||||
self.stripNodes[i].frame = CGRect(origin: CGPoint(x: stripX, y: 0.0), size: CGSize(width: stripWidth, height: 2.0))
|
||||
self.stripNodes[i].frame = CGRect(origin: CGPoint(x: stripX, y: 0.0), size: CGSize(width: stripWidth + 1.0, height: 2.0))
|
||||
stripX += stripWidth + stripSpacing
|
||||
}
|
||||
|
||||
|
|
@ -1341,6 +1341,9 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
private let TitleNodeStateRegular = 0
|
||||
private let TitleNodeStateExpanded = 1
|
||||
|
||||
final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
private var context: AccountContext
|
||||
private var presentationData: PresentationData?
|
||||
|
|
@ -1355,11 +1358,12 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
let editingContentNode: PeerInfoHeaderEditingContentNode
|
||||
let titleNodeContainer: ASDisplayNode
|
||||
let titleNodeRawContainer: ASDisplayNode
|
||||
let titleNode: ImmediateTextNode
|
||||
let titleNode: MultiScaleTextNode
|
||||
let titleCredibilityIconNode: ASImageNode
|
||||
let titleExpandedCredibilityIconNode: ASImageNode
|
||||
let subtitleNodeContainer: ASDisplayNode
|
||||
let subtitleNodeRawContainer: ASDisplayNode
|
||||
let subtitleNode: ImmediateTextNode
|
||||
let subtitleNode: MultiScaleTextNode
|
||||
private var buttonNodes: [PeerInfoHeaderButtonKey: PeerInfoHeaderButtonNode] = [:]
|
||||
private let backgroundNode: ASDisplayNode
|
||||
private let expandedBackgroundNode: ASDisplayNode
|
||||
|
|
@ -1382,17 +1386,22 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
|
||||
self.titleNodeContainer = ASDisplayNode()
|
||||
self.titleNodeRawContainer = ASDisplayNode()
|
||||
self.titleNode = ImmediateTextNode()
|
||||
self.titleNode = MultiScaleTextNode(stateKeys: [TitleNodeStateRegular, TitleNodeStateExpanded])
|
||||
self.titleNode.displaysAsynchronously = false
|
||||
|
||||
self.titleCredibilityIconNode = ASImageNode()
|
||||
self.titleCredibilityIconNode.displaysAsynchronously = false
|
||||
self.titleCredibilityIconNode.displayWithoutProcessing = true
|
||||
self.titleNode.addSubnode(self.titleCredibilityIconNode)
|
||||
self.titleNode.stateNode(forKey: TitleNodeStateRegular)?.addSubnode(self.titleCredibilityIconNode)
|
||||
|
||||
self.titleExpandedCredibilityIconNode = ASImageNode()
|
||||
self.titleExpandedCredibilityIconNode.displaysAsynchronously = false
|
||||
self.titleExpandedCredibilityIconNode.displayWithoutProcessing = true
|
||||
self.titleNode.stateNode(forKey: TitleNodeStateExpanded)?.addSubnode(self.titleExpandedCredibilityIconNode)
|
||||
|
||||
self.subtitleNodeContainer = ASDisplayNode()
|
||||
self.subtitleNodeRawContainer = ASDisplayNode()
|
||||
self.subtitleNode = ImmediateTextNode()
|
||||
self.subtitleNode = MultiScaleTextNode(stateKeys: [TitleNodeStateRegular, TitleNodeStateExpanded])
|
||||
self.subtitleNode.displaysAsynchronously = false
|
||||
|
||||
self.regularContentNode = PeerInfoHeaderRegularContentNode()
|
||||
|
|
@ -1458,7 +1467,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
|
||||
if themeUpdated {
|
||||
if let sourceImage = UIImage(bundleImageName: "Peer Info/VerifiedIcon") {
|
||||
self.titleCredibilityIconNode.image = generateImage(sourceImage.size, contextGenerator: { size, context in
|
||||
let image = generateImage(sourceImage.size, contextGenerator: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(presentationData.theme.list.itemCheckColors.foregroundColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: 7.0, dy: 7.0))
|
||||
|
|
@ -1466,7 +1475,8 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
context.clip(to: CGRect(origin: CGPoint(), size: size), mask: sourceImage.cgImage!)
|
||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||
})
|
||||
//self.titleCredibilityIconNode.image = PresentationResourcesItemList.verifiedPeerIcon(presentationData.theme)
|
||||
self.titleCredibilityIconNode.image = image
|
||||
self.titleExpandedCredibilityIconNode.image = image
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1506,15 +1516,22 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
|
||||
let defaultButtonSize: CGFloat = 40.0
|
||||
let defaultMaxButtonSpacing: CGFloat = 40.0
|
||||
let expandedAvatarListHeight = min(width, containerHeight - 64.0)
|
||||
let expandedAvatarControlsHeight: CGFloat = 61.0
|
||||
let expandedAvatarListHeight = min(width, containerHeight - expandedAvatarControlsHeight)
|
||||
let expandedAvatarListSize = CGSize(width: width, height: expandedAvatarListHeight)
|
||||
|
||||
let buttonKeys: [PeerInfoHeaderButtonKey] = peerInfoHeaderButtons(peer: peer, cachedData: cachedData)
|
||||
|
||||
var isVerified = false
|
||||
let titleString: NSAttributedString
|
||||
let subtitleString: NSAttributedString
|
||||
if let peer = peer, peer.isVerified {
|
||||
isVerified = true
|
||||
}
|
||||
|
||||
if let peer = peer {
|
||||
self.titleNode.attributedText = NSAttributedString(string: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), font: Font.medium(24.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||
titleString = NSAttributedString(string: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), font: Font.medium(24.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||
|
||||
let subtitleString: NSAttributedString?
|
||||
if let statusData = statusData {
|
||||
let subtitleColor: UIColor
|
||||
if statusData.isActivity {
|
||||
|
|
@ -1524,37 +1541,61 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
}
|
||||
subtitleString = NSAttributedString(string: statusData.text, font: Font.regular(15.0), textColor: subtitleColor)
|
||||
} else {
|
||||
subtitleString = nil
|
||||
subtitleString = NSAttributedString(string: " ", font: Font.regular(15.0), textColor: presentationData.theme.list.itemSecondaryTextColor)
|
||||
}
|
||||
self.subtitleNode.attributedText = subtitleString
|
||||
} else {
|
||||
titleString = NSAttributedString(string: " ", font: Font.medium(24.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||
subtitleString = NSAttributedString(string: " ", font: Font.regular(15.0), textColor: presentationData.theme.list.itemSecondaryTextColor)
|
||||
}
|
||||
|
||||
let textSideInset: CGFloat = 44.0
|
||||
let expandedAvatarControlsHeight: CGFloat = 64.0
|
||||
let expandedAvatarHeight: CGFloat = expandedAvatarListSize.height + expandedAvatarControlsHeight
|
||||
|
||||
let titleConstrainedSize = CGSize(width: width - textSideInset * 2.0 - (isVerified ? 16.0 : 0.0), height: .greatestFiniteMagnitude)
|
||||
|
||||
let titleNodeLayout = self.titleNode.updateLayout(states: [
|
||||
TitleNodeStateRegular: MultiScaleTextState(attributedText: titleString, constrainedSize: titleConstrainedSize),
|
||||
TitleNodeStateExpanded: MultiScaleTextState(attributedText: titleString, constrainedSize: CGSize(width: titleConstrainedSize.width, height: titleConstrainedSize.height))
|
||||
], mainState: TitleNodeStateRegular)
|
||||
|
||||
let subtitleNodeLayout = self.subtitleNode.updateLayout(states: [
|
||||
TitleNodeStateRegular: MultiScaleTextState(attributedText: subtitleString, constrainedSize: titleConstrainedSize),
|
||||
TitleNodeStateExpanded: MultiScaleTextState(attributedText: subtitleString, constrainedSize: CGSize(width: titleConstrainedSize.width - 82.0, height: titleConstrainedSize.height))
|
||||
], mainState: TitleNodeStateRegular)
|
||||
|
||||
self.titleNode.update(stateFractions: [
|
||||
TitleNodeStateRegular: self.isAvatarExpanded ? 0.0 : 1.0,
|
||||
TitleNodeStateExpanded: self.isAvatarExpanded ? 1.0 : 0.0
|
||||
], transition: transition)
|
||||
|
||||
self.subtitleNode.update(stateFractions: [
|
||||
TitleNodeStateRegular: self.isAvatarExpanded ? 0.0 : 1.0,
|
||||
TitleNodeStateExpanded: self.isAvatarExpanded ? 1.0 : 0.0
|
||||
], transition: transition)
|
||||
|
||||
let avatarSize: CGFloat = 100.0
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: floor((width - avatarSize) / 2.0), y: statusBarHeight + 10.0), size: CGSize(width: avatarSize, height: avatarSize))
|
||||
let avatarCenter = CGPoint(x: (1.0 - transitionFraction) * avatarFrame.midX + transitionFraction * transitionSourceAvatarFrame.midX, y: (1.0 - transitionFraction) * avatarFrame.midY + transitionFraction * transitionSourceAvatarFrame.midY)
|
||||
|
||||
var isVerified = false
|
||||
if let peer = peer, peer.isVerified {
|
||||
isVerified = true
|
||||
}
|
||||
|
||||
let titleSize = self.titleNode.updateLayout(CGSize(width: width - textSideInset * 2.0 - (isVerified ? 16.0 : 0.0), height: .greatestFiniteMagnitude))
|
||||
let subtitleSize = self.subtitleNode.updateLayout(CGSize(width: width - textSideInset * 2.0, height: .greatestFiniteMagnitude))
|
||||
let titleSize = titleNodeLayout[TitleNodeStateRegular]!.size
|
||||
let titleExpandedSize = titleNodeLayout[TitleNodeStateExpanded]!.size
|
||||
let subtitleSize = subtitleNodeLayout[TitleNodeStateRegular]!.size
|
||||
|
||||
if let image = self.titleCredibilityIconNode.image {
|
||||
transition.updateFrame(node: self.titleCredibilityIconNode, frame: CGRect(origin: CGPoint(x: titleSize.width + 4.0, y: floor((titleSize.height - image.size.height) / 2.0) + 1.0), size: image.size))
|
||||
self.titleCredibilityIconNode.isHidden = !isVerified
|
||||
|
||||
transition.updateFrame(node: self.titleExpandedCredibilityIconNode, frame: CGRect(origin: CGPoint(x: titleExpandedSize.width + 4.0, y: floor((titleExpandedSize.height - image.size.height) / 2.0) + 1.0), size: image.size))
|
||||
self.titleExpandedCredibilityIconNode.isHidden = !isVerified
|
||||
}
|
||||
|
||||
let titleFrame: CGRect
|
||||
let subtitleFrame: CGRect
|
||||
if self.isAvatarExpanded {
|
||||
titleFrame = CGRect(origin: CGPoint(x: 16.0, y: expandedAvatarHeight - expandedAvatarControlsHeight + 12.0 + (subtitleSize.height.isZero ? 10.0 : 0.0)), size: titleSize)
|
||||
subtitleFrame = CGRect(origin: CGPoint(x: 16.0, y: titleFrame.maxY - 5.0), size: subtitleSize)
|
||||
let minTitleSize = CGSize(width: titleSize.width * 0.7, height: titleSize.height * 0.7)
|
||||
let minTitleFrame = CGRect(origin: CGPoint(x: 16.0, y: expandedAvatarHeight - expandedAvatarControlsHeight + 9.0 + (subtitleSize.height.isZero ? 10.0 : 0.0)), size: minTitleSize)
|
||||
titleFrame = CGRect(origin: CGPoint(x: minTitleFrame.midX - titleSize.width / 2.0, y: minTitleFrame.midY - titleSize.height / 2.0), size: titleSize)
|
||||
subtitleFrame = CGRect(origin: CGPoint(x: 16.0, y: minTitleFrame.maxY + 4.0), size: subtitleSize)
|
||||
} else {
|
||||
titleFrame = CGRect(origin: CGPoint(x: floor((width - titleSize.width) / 2.0), y: avatarFrame.maxY + 10.0 + (subtitleSize.height.isZero ? 11.0 : 0.0)), size: titleSize)
|
||||
subtitleFrame = CGRect(origin: CGPoint(x: floor((width - subtitleSize.width) / 2.0), y: titleFrame.maxY + 1.0), size: subtitleSize)
|
||||
|
|
@ -1713,14 +1754,14 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
let titleCenter = CGPoint(x: transitionFraction * transitionSourceTitleFrame.midX + (1.0 - transitionFraction) * titleFrame.midX, y: transitionFraction * transitionSourceTitleFrame.midY + (1.0 - transitionFraction) * titleFrame.midY)
|
||||
let subtitleCenter = CGPoint(x: transitionFraction * transitionSourceSubtitleFrame.midX + (1.0 - transitionFraction) * subtitleFrame.midX, y: transitionFraction * transitionSourceSubtitleFrame.midY + (1.0 - transitionFraction) * subtitleFrame.midY)
|
||||
|
||||
let rawTitleFrame = CGRect(origin: CGPoint(x: titleCenter.x - titleFrame.size.width * titleScale / 2.0, y: titleCenter.y - titleFrame.size.height * titleScale / 2.0), size: CGSize(width: titleFrame.size.width * titleScale, height: titleFrame.size.height * titleScale))
|
||||
let rawTitleFrame = CGRect(origin: CGPoint(x: titleCenter.x - titleFrame.size.width * neutralTitleScale / 2.0, y: titleCenter.y - titleFrame.size.height * neutralTitleScale / 2.0), size: CGSize(width: titleFrame.size.width * neutralTitleScale, height: titleFrame.size.height * neutralTitleScale))
|
||||
self.titleNodeRawContainer.frame = rawTitleFrame
|
||||
transition.updateFrameAdditiveToCenter(node: self.titleNodeContainer, frame: CGRect(origin: rawTitleFrame.center, size: CGSize()))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: -titleFrame.size.width * 1.0 / titleScale / 2.0, y: -titleFrame.size.height * 1.0 / titleScale / 2.0), size: titleFrame.size))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(), size: CGSize()))
|
||||
let rawSubtitleFrame = CGRect(origin: CGPoint(x: subtitleCenter.x - subtitleFrame.size.width / 2.0, y: subtitleCenter.y - subtitleFrame.size.height / 2.0), size: subtitleFrame.size)
|
||||
self.subtitleNodeRawContainer.frame = rawSubtitleFrame
|
||||
transition.updateFrameAdditiveToCenter(node: self.subtitleNodeContainer, frame: rawSubtitleFrame)
|
||||
transition.updateFrame(node: self.subtitleNode, frame: CGRect(origin: CGPoint(), size: subtitleFrame.size))
|
||||
transition.updateFrameAdditiveToCenter(node: self.subtitleNodeContainer, frame: CGRect(origin: rawSubtitleFrame.center, size: CGSize()))
|
||||
transition.updateFrame(node: self.subtitleNode, frame: CGRect(origin: CGPoint(), size: CGSize()))
|
||||
transition.updateSublayerTransformScale(node: self.titleNodeContainer, scale: titleScale)
|
||||
transition.updateSublayerTransformScale(node: self.subtitleNodeContainer, scale: subtitleScale)
|
||||
} else {
|
||||
|
|
@ -1736,17 +1777,17 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
|
||||
let rawTitleFrame = titleFrame
|
||||
self.titleNodeRawContainer.frame = rawTitleFrame
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(), size: titleFrame.size))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(), size: CGSize()))
|
||||
let rawSubtitleFrame = subtitleFrame
|
||||
self.subtitleNodeRawContainer.frame = rawSubtitleFrame
|
||||
if self.isAvatarExpanded {
|
||||
transition.updateFrameAdditive(node: self.titleNodeContainer, frame: rawTitleFrame.offsetBy(dx: 0.0, dy: titleOffset + apparentTitleLockOffset).offsetBy(dx: rawTitleFrame.width * 0.5 * (titleScale - 1.0), dy: rawTitleFrame.height * 0.5 * (titleScale - 1.0)))
|
||||
transition.updateFrameAdditive(node: self.subtitleNodeContainer, frame: rawSubtitleFrame.offsetBy(dx: 0.0, dy: titleOffset).offsetBy(dx: rawSubtitleFrame.width * 0.5 * (subtitleScale - 1.0), dy: rawSubtitleFrame.height * 0.5 * (subtitleScale - 1.0)))
|
||||
transition.updateFrameAdditive(node: self.titleNodeContainer, frame: CGRect(origin: rawTitleFrame.center, size: CGSize()).offsetBy(dx: 0.0, dy: titleOffset + apparentTitleLockOffset))
|
||||
transition.updateFrameAdditive(node: self.subtitleNodeContainer, frame: CGRect(origin: rawSubtitleFrame.center, size: CGSize()).offsetBy(dx: 0.0, dy: titleOffset))
|
||||
} else {
|
||||
transition.updateFrameAdditiveToCenter(node: self.titleNodeContainer, frame: rawTitleFrame.offsetBy(dx: 0.0, dy: titleOffset + apparentTitleLockOffset))
|
||||
transition.updateFrameAdditiveToCenter(node: self.subtitleNodeContainer, frame: rawSubtitleFrame.offsetBy(dx: 0.0, dy: titleOffset))
|
||||
transition.updateFrameAdditiveToCenter(node: self.titleNodeContainer, frame: CGRect(origin: rawTitleFrame.center, size: CGSize()).offsetBy(dx: 0.0, dy: titleOffset + apparentTitleLockOffset))
|
||||
transition.updateFrameAdditiveToCenter(node: self.subtitleNodeContainer, frame: CGRect(origin: rawSubtitleFrame.center, size: CGSize()).offsetBy(dx: 0.0, dy: titleOffset))
|
||||
}
|
||||
transition.updateFrame(node: self.subtitleNode, frame: CGRect(origin: CGPoint(), size: subtitleFrame.size))
|
||||
transition.updateFrame(node: self.subtitleNode, frame: CGRect(origin: CGPoint(), size: CGSize()))
|
||||
transition.updateSublayerTransformScaleAdditive(node: self.titleNodeContainer, scale: titleScale)
|
||||
transition.updateSublayerTransformScaleAdditive(node: self.subtitleNodeContainer, scale: subtitleScale)
|
||||
}
|
||||
|
|
@ -1756,7 +1797,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||
if self.isAvatarExpanded {
|
||||
buttonSpacing = 16.0
|
||||
} else {
|
||||
buttonSpacing = min(defaultMaxButtonSpacing, width - floor(CGFloat(buttonKeys.count) * defaultButtonSize / CGFloat(buttonKeys.count + 1)))
|
||||
let normWidth = min(width, containerHeight)
|
||||
let buttonSpacingValue = floor((normWidth - floor(CGFloat(buttonKeys.count) * defaultButtonSize)) / CGFloat(buttonKeys.count + 1))
|
||||
buttonSpacing = min(buttonSpacingValue, 160.0)
|
||||
}
|
||||
|
||||
let expandedButtonSize: CGFloat = 32.0
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||
interaction.updateBlocked(false)
|
||||
}))
|
||||
} else {
|
||||
if user.flags.contains(.isSupport) {
|
||||
if user.flags.contains(.isSupport) || data.isContact {
|
||||
} else {
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 4, text: user.botInfo != nil ? presentationData.strings.Bot_Stop : presentationData.strings.Conversation_BlockUser, color: .destructive, action: {
|
||||
interaction.updateBlocked(true)
|
||||
|
|
@ -4152,8 +4152,8 @@ private final class PeerInfoNavigationTransitionNode: ASDisplayNode, CustomNavig
|
|||
self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: layout.safeInsets.left, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: topNavigationBar.bounds.height, contentOffset: 0.0, presentationData: self.presentationData, peer: self.screenNode.data?.peer, cachedData: self.screenNode.data?.cachedData, notificationSettings: self.screenNode.data?.notificationSettings, statusData: self.screenNode.data?.status, isContact: self.screenNode.data?.isContact ?? false, state: self.screenNode.state, transition: transition, additive: false)
|
||||
}
|
||||
|
||||
let titleScale = (fraction * previousTitleNode.bounds.height + (1.0 - fraction) * self.headerNode.titleNode.bounds.height) / previousTitleNode.bounds.height
|
||||
let subtitleScale = max(0.01, min(10.0, (fraction * previousStatusNode.bounds.height + (1.0 - fraction) * self.headerNode.subtitleNode.bounds.height) / previousStatusNode.bounds.height))
|
||||
let titleScale = (fraction * previousTitleNode.bounds.height + (1.0 - fraction) * self.headerNode.titleNodeRawContainer.bounds.height) / previousTitleNode.bounds.height
|
||||
let subtitleScale = max(0.01, min(10.0, (fraction * previousStatusNode.bounds.height + (1.0 - fraction) * self.headerNode.subtitleNodeRawContainer.bounds.height) / previousStatusNode.bounds.height))
|
||||
|
||||
transition.updateFrame(node: previousTitleContainerNode, frame: CGRect(origin: self.headerNode.titleNodeRawContainer.frame.center, size: CGSize()))
|
||||
transition.updateFrame(node: previousTitleNode, frame: CGRect(origin: CGPoint(x: -previousTitleFrame.width / 2.0, y: -previousTitleFrame.height / 2.0), size: previousTitleFrame.size))
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ public class ShareRootControllerImpl {
|
|||
|> castError(ShareAuthorizationError.self)
|
||||
|> map { sharedData, limitsConfigurationAndContentSettings, data -> (AccountContext, PostboxAccessChallengeData, [AccountWithInfo]) in
|
||||
updateLegacyLocalization(strings: sharedContext.currentPresentationData.with({ $0 }).strings)
|
||||
let context = AccountContextImpl(sharedContext: sharedContext, account: account, tonContext: nil, limitsConfiguration: limitsConfigurationAndContentSettings.0, contentSettings: limitsConfigurationAndContentSettings.1)
|
||||
let context = AccountContextImpl(sharedContext: sharedContext, account: account/*, tonContext: nil*/, limitsConfiguration: limitsConfigurationAndContentSettings.0, contentSettings: limitsConfigurationAndContentSettings.1)
|
||||
return (context, data.data, otherAccounts)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,15 @@ import PeersNearbyUI
|
|||
import PeerInfoUI
|
||||
import SettingsUI
|
||||
import UrlHandling
|
||||
#if ENABLE_WALLET
|
||||
import WalletUI
|
||||
import WalletCore
|
||||
#endif
|
||||
import LegacyMediaPickerUI
|
||||
import LocalMediaResources
|
||||
import OverlayStatusController
|
||||
import AlertUI
|
||||
import PresentationDataUtils
|
||||
import WalletCore
|
||||
|
||||
private enum CallStatusText: Equatable {
|
||||
case none
|
||||
|
|
@ -892,7 +894,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
}
|
||||
|
||||
public func makeTempAccountContext(account: Account) -> AccountContext {
|
||||
return AccountContextImpl(sharedContext: self, account: account, tonContext: nil, limitsConfiguration: .defaultValue, contentSettings: .default, temp: true)
|
||||
return AccountContextImpl(sharedContext: self, account: account/*, tonContext: nil*/, limitsConfiguration: .defaultValue, contentSettings: .default, temp: true)
|
||||
}
|
||||
|
||||
public func openChatMessage(_ params: OpenChatMessageParams) -> Bool {
|
||||
|
|
@ -1146,6 +1148,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
return ChatMessageDateHeader(timestamp: timestamp, scheduled: false, presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: theme, wallpaper: wallpaper), fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameOrder, disableAnimations: false, largeEmoji: false, chatBubbleCorners: chatBubbleCorners, animatedEmojiScale: 1.0, isPreview: true), context: context)
|
||||
}
|
||||
|
||||
#if ENABLE_WALLET
|
||||
public func openWallet(context: AccountContext, walletContext: OpenWalletContext, present: @escaping (ViewController) -> Void) {
|
||||
guard let storedContext = context.tonContext else {
|
||||
return
|
||||
|
|
@ -1205,6 +1208,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
}
|
||||
})
|
||||
}
|
||||
#endif
|
||||
|
||||
public func openImagePicker(context: AccountContext, completion: @escaping (UIImage) -> Void, present: @escaping (ViewController) -> Void) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
|
|
|||
|
|
@ -66,10 +66,12 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: PeerId?, navigate
|
|||
controller.present(JoinLinkPreviewController(context: context, link: link, navigateToPeer: { peerId in
|
||||
openResolvedPeerImpl(peerId, .chat(textInputState: nil, subject: nil))
|
||||
}, parentNavigationController: controller.navigationController as? NavigationController), in: .window(.root))
|
||||
#if ENABLE_WALLET
|
||||
case let .wallet(address, amount, comment):
|
||||
context.sharedContext.openWallet(context: context, walletContext: .send(address: address, amount: amount, comment: comment)) { c in
|
||||
(controller.navigationController as? NavigationController)?.pushViewController(c)
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#if ENABLE_WALLET
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
|
|
@ -278,3 +280,5 @@ final class WalletContextImpl: WalletContext {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ static_library(
|
|||
"//submodules/MtProtoKit:MtProtoKit#shared",
|
||||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
||||
"//submodules/WalletUrl:WalletUrl",
|
||||
#"//submodules/WalletUrl:WalletUrl",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ import MtProtoKitDynamic
|
|||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import AccountContext
|
||||
#if ENABLE_WALLET
|
||||
import WalletUrl
|
||||
#endif
|
||||
|
||||
private let baseTelegramMePaths = ["telegram.me", "t.me", "telegram.dog"]
|
||||
|
||||
|
|
@ -423,11 +425,13 @@ public func parseWallpaperUrl(_ url: String) -> WallpaperUrlParameter? {
|
|||
}
|
||||
|
||||
public func resolveUrlImpl(account: Account, url: String) -> Signal<ResolvedUrl, NoError> {
|
||||
#if ENABLE_WALLET
|
||||
if url.hasPrefix("ton://") {
|
||||
if let url = URL(string: url), let parsedUrl = parseWalletUrl(url) {
|
||||
return .single(.wallet(address: parsedUrl.address, amount: parsedUrl.amount, comment: parsedUrl.comment))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
let schemes = ["http://", "https://", ""]
|
||||
for basePath in baseTelegramMePaths {
|
||||
for scheme in schemes {
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ static_library(
|
|||
"//submodules/LocalAuth:LocalAuth",
|
||||
"//submodules/ScreenCaptureDetection:ScreenCaptureDetection",
|
||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||
"//submodules/WalletUrl:WalletUrl",
|
||||
"//submodules/WalletCore:WalletCore",
|
||||
#"//submodules/WalletUrl:WalletUrl",
|
||||
#"//submodules/WalletCore:WalletCore",
|
||||
"//submodules/StringPluralization:StringPluralization",
|
||||
"//submodules/ActivityIndicator:ActivityIndicator",
|
||||
"//submodules/ProgressNavigationButtonNode:ProgressNavigationButtonNode",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue