mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
no message
This commit is contained in:
parent
2a94ab2b41
commit
9d38010d3f
2
BUCK
2
BUCK
@ -49,6 +49,8 @@ resource_dependencies = [
|
|||||||
"//submodules/TelegramUI:TelegramUIResources",
|
"//submodules/TelegramUI:TelegramUIResources",
|
||||||
"//submodules/WalletUI:WalletUIAssets",
|
"//submodules/WalletUI:WalletUIAssets",
|
||||||
"//submodules/WalletUI:WalletUIResources",
|
"//submodules/WalletUI:WalletUIResources",
|
||||||
|
"//submodules/PasswordSetupUI:PasswordSetupUIResources",
|
||||||
|
"//submodules/PasswordSetupUI:PasswordSetupUIAssets",
|
||||||
"//submodules/OverlayStatusController:OverlayStatusControllerResources",
|
"//submodules/OverlayStatusController:OverlayStatusControllerResources",
|
||||||
"//:AppResources",
|
"//:AppResources",
|
||||||
"//:AppStringResources",
|
"//:AppStringResources",
|
||||||
|
@ -4973,3 +4973,38 @@ Any member of this group will be able to see messages in the channel.";
|
|||||||
"Wallet.VoiceOver.Editing.ClearText" = "Clear text";
|
"Wallet.VoiceOver.Editing.ClearText" = "Clear text";
|
||||||
|
|
||||||
"Wallet.Receive.ShareInvoiceUrlInfo" = "Share this link with other Gram wallet owners to receive %@ Grams from them.";
|
"Wallet.Receive.ShareInvoiceUrlInfo" = "Share this link with other Gram wallet owners to receive %@ Grams from them.";
|
||||||
|
|
||||||
|
"TwoFactorSetup.Intro.Title" = "Additional Password";
|
||||||
|
"TwoFactorSetup.Intro.Text" = "You can set a password that will be\nrequired when you log in on a new device in addition to the code you get via SMS.";
|
||||||
|
"TwoFactorSetup.Intro.Action" = "Set Additional Password";
|
||||||
|
|
||||||
|
"TwoFactorSetup.Password.Title" = "Create Password";
|
||||||
|
"TwoFactorSetup.Password.PlaceholderPassword" = "Password";
|
||||||
|
"TwoFactorSetup.Password.PlaceholderConfirmPassword" = "Re-enter Password";
|
||||||
|
"TwoFactorSetup.Password.Action" = "Create Password";
|
||||||
|
|
||||||
|
"TwoFactorSetup.Email.Title" = "Recovery Email";
|
||||||
|
"TwoFactorSetup.Email.Text" = "You can set a recovery email to be able to reset password and restore access\nto your Telegram account.";
|
||||||
|
"TwoFactorSetup.Email.Placeholder" = "Your email address";
|
||||||
|
"TwoFactorSetup.Email.Action" = "Continue";
|
||||||
|
"TwoFactorSetup.Email.SkipAction" = "Skip setting email";
|
||||||
|
"TwoFactorSetup.Email.SkipConfirmationTitle" = "No, seriously.";
|
||||||
|
"TwoFactorSetup.Email.SkipConfirmationText" = "If you forget your password, you will lose access to your Telegram account. There will be no way to restore it.";
|
||||||
|
"TwoFactorSetup.Email.SkipConfirmationSkip" = "Skip";
|
||||||
|
|
||||||
|
"TwoFactorSetup.EmailVerification.Title" = "Recovery Email";
|
||||||
|
"TwoFactorSetup.EmailVerification.Text" = "Please enter code we've just emailed at %@";
|
||||||
|
"TwoFactorSetup.EmailVerification.Placeholder" = "Code";
|
||||||
|
"TwoFactorSetup.EmailVerification.Action" = "Continue";
|
||||||
|
"TwoFactorSetup.EmailVerification.ChangeAction" = "Change Email";
|
||||||
|
"TwoFactorSetup.EmailVerification.ResendAction" = "Resend Code";
|
||||||
|
|
||||||
|
"TwoFactorSetup.Hint.Title" = "Hint";
|
||||||
|
"TwoFactorSetup.Hint.Text" = "You can create an optional hint for\nyour password.";
|
||||||
|
"TwoFactorSetup.Hint.Placeholder" = "Hint (optional)";
|
||||||
|
"TwoFactorSetup.Hint.Action" = "Continue";
|
||||||
|
"TwoFactorSetup.Hint.SkipAction" = "Skip setting hint";
|
||||||
|
|
||||||
|
"TwoFactorSetup.Done.Title" = "Password Set!";
|
||||||
|
"TwoFactorSetup.Done.Text" = "Now password will be required when you log in on a new device in addition to the code you get via SMS.";
|
||||||
|
"TwoFactorSetup.Done.Action" = "Return to Settings";
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
"Wallet.Info.TransactionTo" = "to";
|
"Wallet.Info.TransactionTo" = "to";
|
||||||
"Wallet.Info.TransactionFrom" = "from";
|
"Wallet.Info.TransactionFrom" = "from";
|
||||||
"Wallet.Info.Updating" = "updating";
|
"Wallet.Info.Updating" = "updating";
|
||||||
"Wallet.Info.TransactionBlockchainFee" = "%@ blockchain fee";
|
"Wallet.Info.TransactionBlockchainFee" = "%@ blockchain fees";
|
||||||
"Wallet.Info.TransactionPendingHeader" = "Pending";
|
"Wallet.Info.TransactionPendingHeader" = "Pending";
|
||||||
"Wallet.Qr.ScanCode" = "Scan QR Code";
|
"Wallet.Qr.ScanCode" = "Scan QR Code";
|
||||||
"Wallet.Qr.Title" = "QR Code";
|
"Wallet.Qr.Title" = "QR Code";
|
||||||
@ -192,3 +192,4 @@
|
|||||||
"Wallet.Time.PreciseDate_m11" = "Nov %1$@, %2$@ at %3$@";
|
"Wallet.Time.PreciseDate_m11" = "Nov %1$@, %2$@ at %3$@";
|
||||||
"Wallet.Time.PreciseDate_m12" = "Dec %1$@, %2$@ at %3$@";
|
"Wallet.Time.PreciseDate_m12" = "Dec %1$@, %2$@ at %3$@";
|
||||||
"Wallet.VoiceOver.Editing.ClearText" = "Clear text";
|
"Wallet.VoiceOver.Editing.ClearText" = "Clear text";
|
||||||
|
"Wallet.Receive.ShareInvoiceUrlInfo" = "Share this link with other Gram wallet owners to receive %@ Grams from them.";
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
load("//Config:buck_rule_macros.bzl", "static_library")
|
load("//Config:buck_rule_macros.bzl", "static_library")
|
||||||
|
|
||||||
|
apple_resource(
|
||||||
|
name = "PasswordSetupUIResources",
|
||||||
|
files = glob([
|
||||||
|
"Resources/**/*",
|
||||||
|
], exclude = ["Resources/**/.*"]),
|
||||||
|
visibility = ["PUBLIC"],
|
||||||
|
)
|
||||||
|
|
||||||
|
apple_asset_catalog(
|
||||||
|
name = "PasswordSetupUIAssets",
|
||||||
|
dirs = [
|
||||||
|
"PasswordSetupUIImages.xcassets",
|
||||||
|
],
|
||||||
|
visibility = ["PUBLIC"],
|
||||||
|
)
|
||||||
|
|
||||||
static_library(
|
static_library(
|
||||||
name = "PasswordSetupUI",
|
name = "PasswordSetupUI",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
@ -18,6 +34,11 @@ static_library(
|
|||||||
"//submodules/AlertUI:AlertUI",
|
"//submodules/AlertUI:AlertUI",
|
||||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||||
"//submodules/ItemListUI:ItemListUI",
|
"//submodules/ItemListUI:ItemListUI",
|
||||||
|
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||||
|
"//submodules/AppBundle:AppBundle",
|
||||||
|
"//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode",
|
||||||
|
"//submodules/OverlayStatusController:OverlayStatusController",
|
||||||
|
"//submodules/rlottie:RLottieBinding",
|
||||||
],
|
],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"provides-namespace" : true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "User.pdf"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/PasswordSetupUI/PasswordSetupUIImages.xcassets/PasswordSetup/TextHidden.imageset/User.pdf
vendored
Normal file
BIN
submodules/PasswordSetupUI/PasswordSetupUIImages.xcassets/PasswordSetup/TextHidden.imageset/User.pdf
vendored
Normal file
Binary file not shown.
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupDone.tgs
Normal file
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupDone.tgs
Normal file
Binary file not shown.
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupHint.tgs
Normal file
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupHint.tgs
Normal file
Binary file not shown.
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupIntro.tgs
Normal file
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupIntro.tgs
Normal file
Binary file not shown.
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupMail.tgs
Normal file
BIN
submodules/PasswordSetupUI/Resources/TwoFactorSetupMail.tgs
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
256
submodules/PasswordSetupUI/Sources/ManagedAnimationNode.swift
Normal file
256
submodules/PasswordSetupUI/Sources/ManagedAnimationNode.swift
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import RLottieBinding
|
||||||
|
import AppBundle
|
||||||
|
import GZip
|
||||||
|
|
||||||
|
enum ManagedAnimationTrackState {
|
||||||
|
case intro
|
||||||
|
case loop
|
||||||
|
case outro
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ManagedAnimationState {
|
||||||
|
var item: ManagedAnimationItem
|
||||||
|
|
||||||
|
private let instance: LottieInstance
|
||||||
|
|
||||||
|
let frameCount: Int
|
||||||
|
let fps: Double
|
||||||
|
|
||||||
|
var startTime: Double?
|
||||||
|
var trackState: ManagedAnimationTrackState?
|
||||||
|
var trackingFrameState: (Int, Int)?
|
||||||
|
var frameIndex: Int?
|
||||||
|
|
||||||
|
private let renderContext: DrawingContext
|
||||||
|
|
||||||
|
init?(item: ManagedAnimationItem) {
|
||||||
|
guard let path = getAppBundle().path(forResource: item.name, ofType: "tgs") else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let unpackedData = TGGUnzipData(data, 5 * 1024 * 1024) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let instance = LottieInstance(data: unpackedData, cacheKey: item.name) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
self.item = item
|
||||||
|
self.instance = instance
|
||||||
|
|
||||||
|
self.frameCount = Int(instance.frameCount)
|
||||||
|
self.fps = Double(instance.frameRate)
|
||||||
|
|
||||||
|
self.renderContext = DrawingContext(size: instance.dimensions, scale: UIScreenScale, premultiplied: true, clear: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func draw() -> UIImage? {
|
||||||
|
self.instance.renderFrame(with: Int32(self.frameIndex ?? 0), into: self.renderContext.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(self.renderContext.size.width * self.renderContext.scale), height: Int32(self.renderContext.size.height * self.renderContext.scale), bytesPerRow: Int32(self.renderContext.bytesPerRow))
|
||||||
|
return self.renderContext.generateImage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ManagedAnimationActionAtEnd {
|
||||||
|
case pause
|
||||||
|
case advance
|
||||||
|
case loop
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ManagedAnimationTrack: Equatable {
|
||||||
|
let frameRange: Range<Int>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ManagedAnimationItem: Equatable {
|
||||||
|
let name: String
|
||||||
|
var intro: ManagedAnimationTrack?
|
||||||
|
var loop: ManagedAnimationTrack?
|
||||||
|
var outro: ManagedAnimationTrack?
|
||||||
|
}
|
||||||
|
|
||||||
|
final class ManagedAnimationNode: ASDisplayNode {
|
||||||
|
let intrinsicSize: CGSize
|
||||||
|
|
||||||
|
private let imageNode: ASImageNode
|
||||||
|
private let displayLink: CADisplayLink
|
||||||
|
|
||||||
|
private var items: [ManagedAnimationState] = []
|
||||||
|
|
||||||
|
var currentItemName: String? {
|
||||||
|
return self.items.first?.item.name
|
||||||
|
}
|
||||||
|
|
||||||
|
init(size: CGSize) {
|
||||||
|
self.intrinsicSize = size
|
||||||
|
|
||||||
|
self.imageNode = ASImageNode()
|
||||||
|
self.imageNode.displayWithoutProcessing = true
|
||||||
|
self.imageNode.displaysAsynchronously = false
|
||||||
|
self.imageNode.frame = CGRect(origin: CGPoint(), size: self.intrinsicSize)
|
||||||
|
|
||||||
|
final class DisplayLinkTarget: NSObject {
|
||||||
|
private let f: () -> Void
|
||||||
|
|
||||||
|
init(_ f: @escaping () -> Void) {
|
||||||
|
self.f = f
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func event() {
|
||||||
|
self.f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var displayLinkUpdate: (() -> Void)?
|
||||||
|
self.displayLink = CADisplayLink(target: DisplayLinkTarget {
|
||||||
|
displayLinkUpdate?()
|
||||||
|
}, selector: #selector(DisplayLinkTarget.event))
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.addSubnode(self.imageNode)
|
||||||
|
|
||||||
|
self.displayLink.add(to: RunLoop.main, forMode: .common)
|
||||||
|
|
||||||
|
displayLinkUpdate = { [weak self] in
|
||||||
|
self?.updateAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateAnimation() {
|
||||||
|
guard let item = self.items.first else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let timestamp = CACurrentMediaTime()
|
||||||
|
var startTime: Double
|
||||||
|
let maybeTrackState: ManagedAnimationTrackState?
|
||||||
|
if let current = item.startTime {
|
||||||
|
startTime = current
|
||||||
|
} else {
|
||||||
|
startTime = timestamp
|
||||||
|
item.startTime = startTime
|
||||||
|
}
|
||||||
|
if let current = item.trackState {
|
||||||
|
maybeTrackState = current
|
||||||
|
} else if let _ = item.item.intro {
|
||||||
|
maybeTrackState = .intro
|
||||||
|
} else if let _ = item.item.loop {
|
||||||
|
maybeTrackState = .loop
|
||||||
|
} else if let _ = item.item.outro {
|
||||||
|
maybeTrackState = .outro
|
||||||
|
} else {
|
||||||
|
maybeTrackState = nil
|
||||||
|
}
|
||||||
|
if item.trackState != maybeTrackState {
|
||||||
|
item.trackState = maybeTrackState
|
||||||
|
item.startTime = timestamp
|
||||||
|
startTime = timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let trackState = maybeTrackState else {
|
||||||
|
self.items.removeFirst()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var fps = item.fps
|
||||||
|
|
||||||
|
let track: ManagedAnimationTrack
|
||||||
|
switch trackState {
|
||||||
|
case .intro:
|
||||||
|
track = item.item.intro!
|
||||||
|
case .loop:
|
||||||
|
track = item.item.loop!
|
||||||
|
if self.items.count > 1 {
|
||||||
|
//fps *= 2.0
|
||||||
|
}
|
||||||
|
case .outro:
|
||||||
|
track = item.item.outro!
|
||||||
|
}
|
||||||
|
|
||||||
|
let frameIndex: Int
|
||||||
|
if let (startFrame, endFrame) = item.trackingFrameState {
|
||||||
|
let duration: Double = 0.3
|
||||||
|
var t = (timestamp - startTime) / duration
|
||||||
|
t = max(0.0, t)
|
||||||
|
t = min(1.0, t)
|
||||||
|
let frameOffset = Int(Double(startFrame) * (1.0 - t) + Double(endFrame) * t)
|
||||||
|
let lowerBound = min(track.frameRange.lowerBound, item.frameCount - 1)
|
||||||
|
let upperBound = min(track.frameRange.upperBound, item.frameCount)
|
||||||
|
frameIndex = max(lowerBound, min(upperBound, frameOffset))
|
||||||
|
} else {
|
||||||
|
let frameOffset = Int((timestamp - startTime) * fps)
|
||||||
|
let lowerBound = min(track.frameRange.lowerBound, item.frameCount - 1)
|
||||||
|
let upperBound = min(track.frameRange.upperBound, item.frameCount)
|
||||||
|
if frameOffset >= upperBound - lowerBound {
|
||||||
|
switch trackState {
|
||||||
|
case .intro:
|
||||||
|
if let _ = item.item.loop {
|
||||||
|
item.trackState = .loop
|
||||||
|
item.startTime = timestamp
|
||||||
|
return
|
||||||
|
} else if let _ = item.item.outro {
|
||||||
|
item.trackState = .outro
|
||||||
|
item.startTime = timestamp
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
self.items.removeFirst()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case .loop:
|
||||||
|
if self.items.count > 1 {
|
||||||
|
if let _ = item.item.outro {
|
||||||
|
item.trackState = .outro
|
||||||
|
item.startTime = timestamp
|
||||||
|
} else {
|
||||||
|
self.items.removeFirst()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
item.startTime = timestamp
|
||||||
|
frameIndex = lowerBound
|
||||||
|
}
|
||||||
|
case .outro:
|
||||||
|
self.items.removeFirst()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
frameIndex = lowerBound + frameOffset % (upperBound - lowerBound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.frameIndex != frameIndex {
|
||||||
|
item.frameIndex = frameIndex
|
||||||
|
if let image = item.draw() {
|
||||||
|
self.imageNode.image = image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func switchTo(_ item: ManagedAnimationItem, noOutro: Bool = false) {
|
||||||
|
if let state = ManagedAnimationState(item: item) {
|
||||||
|
if let last = self.items.last {
|
||||||
|
if last.item.name == item.name {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let first = self.items.first {
|
||||||
|
if noOutro {
|
||||||
|
first.item.outro = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.items.append(state)
|
||||||
|
self.updateAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func trackTo(frameIndex: Int) {
|
||||||
|
if let first = self.items.first {
|
||||||
|
first.startTime = CACurrentMediaTime()
|
||||||
|
first.trackingFrameState = (first.frameIndex ?? 0, frameIndex)
|
||||||
|
self.updateAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// PasswordSetupUI.h
|
|
||||||
// PasswordSetupUI
|
|
||||||
//
|
|
||||||
// Created by Peter on 8/12/19.
|
|
||||||
// Copyright © 2019 Telegram Messenger LLP. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
|
|
||||||
//! Project version number for PasswordSetupUI.
|
|
||||||
FOUNDATION_EXPORT double PasswordSetupUIVersionNumber;
|
|
||||||
|
|
||||||
//! Project version string for PasswordSetupUI.
|
|
||||||
FOUNDATION_EXPORT const unsigned char PasswordSetupUIVersionString[];
|
|
||||||
|
|
||||||
// In this header, you should import all the public headers of your framework using statements like #import <PasswordSetupUI/PublicHeader.h>
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,207 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import AppBundle
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import Display
|
||||||
|
import SolidRoundedButtonNode
|
||||||
|
import SwiftSignalKit
|
||||||
|
import OverlayStatusController
|
||||||
|
import AnimatedStickerNode
|
||||||
|
import AccountContext
|
||||||
|
import TelegramPresentationData
|
||||||
|
import PresentationDataUtils
|
||||||
|
|
||||||
|
public enum TwoFactorAuthSplashMode {
|
||||||
|
case intro
|
||||||
|
case done
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class TwoFactorAuthSplashScreen: ViewController {
|
||||||
|
private let context: AccountContext
|
||||||
|
private var presentationData: PresentationData
|
||||||
|
private var mode: TwoFactorAuthSplashMode
|
||||||
|
|
||||||
|
public init(context: AccountContext, mode: TwoFactorAuthSplashMode) {
|
||||||
|
self.context = context
|
||||||
|
self.mode = mode
|
||||||
|
|
||||||
|
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
|
let defaultTheme = NavigationBarTheme(rootControllerTheme: self.presentationData.theme)
|
||||||
|
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
|
||||||
|
|
||||||
|
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Wallet_Intro_NotNow, close: self.presentationData.strings.Wallet_Navigation_Close)))
|
||||||
|
|
||||||
|
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
||||||
|
self.navigationPresentation = .modalInLargeLayout
|
||||||
|
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||||
|
self.navigationBar?.intrinsicCanTransitionInline = false
|
||||||
|
|
||||||
|
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Wallet_Navigation_Back, style: .plain, target: nil, action: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
}
|
||||||
|
|
||||||
|
override public func loadDisplayNode() {
|
||||||
|
self.displayNode = TwoFactorAuthSplashScreenNode(context: self.context, presentationData: self.presentationData, mode: self.mode, action: { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch strongSelf.mode {
|
||||||
|
case .intro:
|
||||||
|
strongSelf.push(TwoFactorDataInputScreen(context: strongSelf.context, mode: .password))
|
||||||
|
case .done:
|
||||||
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.filterController(strongSelf, animated: true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
self.displayNodeDidLoad()
|
||||||
|
}
|
||||||
|
|
||||||
|
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
|
super.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
|
||||||
|
(self.displayNode as! TwoFactorAuthSplashScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationHeight, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
||||||
|
private var presentationData: PresentationData
|
||||||
|
private let mode: TwoFactorAuthSplashMode
|
||||||
|
|
||||||
|
private var animationSize: CGSize = CGSize()
|
||||||
|
private var animationOffset: CGPoint = CGPoint()
|
||||||
|
private let animationNode: AnimatedStickerNode
|
||||||
|
private let titleNode: ImmediateTextNode
|
||||||
|
private let textNode: ImmediateTextNode
|
||||||
|
let buttonNode: SolidRoundedButtonNode
|
||||||
|
|
||||||
|
var inProgress: Bool = false {
|
||||||
|
didSet {
|
||||||
|
self.buttonNode.isUserInteractionEnabled = !self.inProgress
|
||||||
|
self.buttonNode.alpha = self.inProgress ? 0.6 : 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(context: AccountContext, presentationData: PresentationData, mode: TwoFactorAuthSplashMode, action: @escaping () -> Void) {
|
||||||
|
self.presentationData = presentationData
|
||||||
|
self.mode = mode
|
||||||
|
|
||||||
|
self.animationNode = AnimatedStickerNode()
|
||||||
|
|
||||||
|
let title: String
|
||||||
|
let text: NSAttributedString
|
||||||
|
let buttonText: String
|
||||||
|
|
||||||
|
let textFont = Font.regular(16.0)
|
||||||
|
let textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
||||||
|
|
||||||
|
switch mode {
|
||||||
|
case .intro:
|
||||||
|
title = self.presentationData.strings.TwoFactorSetup_Intro_Title
|
||||||
|
text = NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Intro_Text, font: textFont, textColor: textColor)
|
||||||
|
buttonText = self.presentationData.strings.TwoFactorSetup_Intro_Action
|
||||||
|
|
||||||
|
if let path = getAppBundle().path(forResource: "TwoFactorSetupIntro", ofType: "tgs") {
|
||||||
|
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, playbackMode: .once, mode: .direct)
|
||||||
|
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||||
|
self.animationNode.visibility = true
|
||||||
|
}
|
||||||
|
case .done:
|
||||||
|
title = self.presentationData.strings.TwoFactorSetup_Done_Title
|
||||||
|
text = NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Done_Text, font: textFont, textColor: textColor)
|
||||||
|
buttonText = self.presentationData.strings.TwoFactorSetup_Done_Action
|
||||||
|
|
||||||
|
if let path = getAppBundle().path(forResource: "TwoFactorSetupDone", ofType: "tgs") {
|
||||||
|
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, mode: .direct)
|
||||||
|
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||||
|
self.animationNode.visibility = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.titleNode = ImmediateTextNode()
|
||||||
|
self.titleNode.displaysAsynchronously = false
|
||||||
|
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.bold(32.0), textColor: self.presentationData.theme.list.itemPrimaryTextColor)
|
||||||
|
self.titleNode.maximumNumberOfLines = 0
|
||||||
|
self.titleNode.textAlignment = .center
|
||||||
|
|
||||||
|
self.textNode = ImmediateTextNode()
|
||||||
|
self.textNode.displaysAsynchronously = false
|
||||||
|
self.textNode.attributedText = text
|
||||||
|
self.textNode.maximumNumberOfLines = 0
|
||||||
|
self.textNode.lineSpacing = 0.1
|
||||||
|
self.textNode.textAlignment = .center
|
||||||
|
|
||||||
|
self.buttonNode = SolidRoundedButtonNode(title: buttonText, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 10.0, gloss: false)
|
||||||
|
self.buttonNode.isHidden = buttonText.isEmpty
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
|
|
||||||
|
self.addSubnode(self.animationNode)
|
||||||
|
self.addSubnode(self.titleNode)
|
||||||
|
self.addSubnode(self.textNode)
|
||||||
|
self.addSubnode(self.buttonNode)
|
||||||
|
|
||||||
|
self.buttonNode.pressed = {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
}
|
||||||
|
|
||||||
|
func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
|
let sideInset: CGFloat = 32.0
|
||||||
|
let buttonSideInset: CGFloat = 48.0
|
||||||
|
let iconSpacing: CGFloat = 8.0
|
||||||
|
let titleSpacing: CGFloat = 19.0
|
||||||
|
let buttonHeight: CGFloat = 50.0
|
||||||
|
|
||||||
|
let iconSize: CGSize = self.animationSize
|
||||||
|
var iconOffset = CGPoint()
|
||||||
|
switch self.mode {
|
||||||
|
case .done:
|
||||||
|
iconOffset.x = 10.0
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
||||||
|
let textSize = self.textNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
||||||
|
|
||||||
|
let contentHeight = iconSize.height + iconSpacing + titleSize.height + titleSpacing + textSize.height
|
||||||
|
var contentVerticalOrigin = floor((layout.size.height - contentHeight - iconSize.height / 2.0) / 2.0)
|
||||||
|
|
||||||
|
let minimalBottomInset: CGFloat = 60.0
|
||||||
|
let bottomInset = layout.intrinsicInsets.bottom + minimalBottomInset
|
||||||
|
|
||||||
|
let buttonWidth = layout.size.width - buttonSideInset * 2.0
|
||||||
|
|
||||||
|
let buttonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: layout.size.height - bottomInset - buttonHeight), size: CGSize(width: buttonWidth, height: buttonHeight))
|
||||||
|
transition.updateFrame(node: self.buttonNode, frame: buttonFrame)
|
||||||
|
self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition)
|
||||||
|
|
||||||
|
var maxContentVerticalOrigin = buttonFrame.minY - 12.0 - contentHeight
|
||||||
|
|
||||||
|
contentVerticalOrigin = min(contentVerticalOrigin, maxContentVerticalOrigin)
|
||||||
|
|
||||||
|
let iconFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0) + self.animationOffset.x, y: contentVerticalOrigin + self.animationOffset.y), size: iconSize).offsetBy(dx: iconOffset.x, dy: iconOffset.y)
|
||||||
|
self.animationNode.updateLayout(size: iconFrame.size)
|
||||||
|
transition.updateFrameAdditive(node: self.animationNode, frame: iconFrame)
|
||||||
|
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: iconFrame.maxY + iconSpacing), size: titleSize)
|
||||||
|
transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame)
|
||||||
|
let textFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: titleFrame.maxY + titleSpacing), size: textSize)
|
||||||
|
transition.updateFrameAdditive(node: self.textNode, frame: textFrame)
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ import AccountContext
|
|||||||
import TelegramNotices
|
import TelegramNotices
|
||||||
import LocalAuth
|
import LocalAuth
|
||||||
import AppBundle
|
import AppBundle
|
||||||
|
import PasswordSetupUI
|
||||||
|
|
||||||
private final class PrivacyAndSecurityControllerArguments {
|
private final class PrivacyAndSecurityControllerArguments {
|
||||||
let account: Account
|
let account: Account
|
||||||
@ -639,7 +640,14 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
case .set:
|
case .set:
|
||||||
break
|
break
|
||||||
case let .notSet(pendingEmail):
|
case let .notSet(pendingEmail):
|
||||||
intro = pendingEmail == nil
|
if pendingEmail == nil {
|
||||||
|
let controller = TwoFactorAuthSplashScreen(context: context, mode: .intro)
|
||||||
|
pushControllerImpl?(controller, true)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
//intro = pendingEmail == nil
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if intro {
|
if intro {
|
||||||
|
@ -334,9 +334,9 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr
|
|||||||
inputBackgroundColor: UIColor(rgb: 0xe9e9e9),
|
inputBackgroundColor: UIColor(rgb: 0xe9e9e9),
|
||||||
inputHollowBackgroundColor: .white,
|
inputHollowBackgroundColor: .white,
|
||||||
inputBorderColor: UIColor(rgb: 0xe4e4e6),
|
inputBorderColor: UIColor(rgb: 0xe4e4e6),
|
||||||
inputPlaceholderColor: UIColor(rgb: 0x818086),
|
inputPlaceholderColor: UIColor(rgb: 0x8E8D92),
|
||||||
inputTextColor: .black,
|
inputTextColor: .black,
|
||||||
inputClearButtonColor: UIColor(rgb: 0x7b7b81),
|
inputClearButtonColor: UIColor(rgb: 0xBCBCC0),
|
||||||
checkContentColor: .white
|
checkContentColor: .white
|
||||||
)
|
)
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -363,58 +363,61 @@ public final class WalletStrings: Equatable {
|
|||||||
public var Wallet_Sending_Title: String { return self._s[146]! }
|
public var Wallet_Sending_Title: String { return self._s[146]! }
|
||||||
public var Wallet_Navigation_Done: String { return self._s[147]! }
|
public var Wallet_Navigation_Done: String { return self._s[147]! }
|
||||||
public var Wallet_Settings_Title: String { return self._s[148]! }
|
public var Wallet_Settings_Title: String { return self._s[148]! }
|
||||||
public var Wallet_Info_RefreshErrorNetworkText: String { return self._s[149]! }
|
public func Wallet_Receive_ShareInvoiceUrlInfo(_ _0: String) -> (String, [(Int, NSRange)]) {
|
||||||
public var Wallet_Weekday_Today: String { return self._s[151]! }
|
return formatWithArgumentRanges(self._s[149]!, self._r[149]!, [_0])
|
||||||
public var Wallet_Month_ShortDecember: String { return self._s[152]! }
|
}
|
||||||
public var Wallet_Words_Text: String { return self._s[153]! }
|
public var Wallet_Info_RefreshErrorNetworkText: String { return self._s[150]! }
|
||||||
public var Wallet_WordCheck_ViewWords: String { return self._s[154]! }
|
public var Wallet_Weekday_Today: String { return self._s[152]! }
|
||||||
public var Wallet_Send_AddressInfo: String { return self._s[155]! }
|
public var Wallet_Month_ShortDecember: String { return self._s[153]! }
|
||||||
|
public var Wallet_Words_Text: String { return self._s[154]! }
|
||||||
|
public var Wallet_WordCheck_ViewWords: String { return self._s[155]! }
|
||||||
|
public var Wallet_Send_AddressInfo: String { return self._s[156]! }
|
||||||
public func Wallet_Updated_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) {
|
public func Wallet_Updated_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) {
|
||||||
return formatWithArgumentRanges(self._s[156]!, self._r[156]!, [_0])
|
return formatWithArgumentRanges(self._s[157]!, self._r[157]!, [_0])
|
||||||
}
|
}
|
||||||
public var Wallet_Intro_NotNow: String { return self._s[157]! }
|
public var Wallet_Intro_NotNow: String { return self._s[158]! }
|
||||||
public var Wallet_Navigation_Close: String { return self._s[158]! }
|
public var Wallet_Navigation_Close: String { return self._s[159]! }
|
||||||
public var Wallet_Month_GenDecember: String { return self._s[160]! }
|
public var Wallet_Month_GenDecember: String { return self._s[161]! }
|
||||||
public var Wallet_Send_ErrorNotEnoughFundsTitle: String { return self._s[161]! }
|
public var Wallet_Send_ErrorNotEnoughFundsTitle: String { return self._s[162]! }
|
||||||
public var Wallet_WordImport_IncorrectTitle: String { return self._s[162]! }
|
public var Wallet_WordImport_IncorrectTitle: String { return self._s[163]! }
|
||||||
public var Wallet_Send_AddressText: String { return self._s[163]! }
|
public var Wallet_Send_AddressText: String { return self._s[164]! }
|
||||||
public var Wallet_Receive_AmountInfo: String { return self._s[164]! }
|
public var Wallet_Receive_AmountInfo: String { return self._s[165]! }
|
||||||
public func Wallet_Time_PreciseDate_m2(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
|
public func Wallet_Time_PreciseDate_m2(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
|
||||||
return formatWithArgumentRanges(self._s[165]!, self._r[165]!, [_1, _2, _3])
|
return formatWithArgumentRanges(self._s[166]!, self._r[166]!, [_1, _2, _3])
|
||||||
}
|
}
|
||||||
public var Wallet_Month_ShortAugust: String { return self._s[166]! }
|
public var Wallet_Month_ShortAugust: String { return self._s[167]! }
|
||||||
public var Wallet_Qr_Title: String { return self._s[167]! }
|
public var Wallet_Qr_Title: String { return self._s[168]! }
|
||||||
public var Wallet_WordCheck_TryAgain: String { return self._s[168]! }
|
public var Wallet_WordCheck_TryAgain: String { return self._s[169]! }
|
||||||
public var Wallet_Info_TransactionPendingHeader: String { return self._s[169]! }
|
public var Wallet_Info_TransactionPendingHeader: String { return self._s[170]! }
|
||||||
public var Wallet_Receive_InvoiceUrlHeader: String { return self._s[170]! }
|
public var Wallet_Receive_InvoiceUrlHeader: String { return self._s[171]! }
|
||||||
public var Wallet_Created_Text: String { return self._s[171]! }
|
public var Wallet_Created_Text: String { return self._s[172]! }
|
||||||
public var Wallet_Created_Proceed: String { return self._s[172]! }
|
public var Wallet_Created_Proceed: String { return self._s[173]! }
|
||||||
public var Wallet_Words_Done: String { return self._s[173]! }
|
public var Wallet_Words_Done: String { return self._s[174]! }
|
||||||
public var Wallet_WordImport_Continue: String { return self._s[174]! }
|
public var Wallet_WordImport_Continue: String { return self._s[175]! }
|
||||||
public var Wallet_TransactionInfo_StorageFeeHeader: String { return self._s[175]! }
|
public var Wallet_TransactionInfo_StorageFeeHeader: String { return self._s[176]! }
|
||||||
public var Wallet_WordImport_CanNotRemember: String { return self._s[176]! }
|
public var Wallet_WordImport_CanNotRemember: String { return self._s[177]! }
|
||||||
public func Wallet_Time_PreciseDate_m11(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
|
public func Wallet_Time_PreciseDate_m11(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
|
||||||
return formatWithArgumentRanges(self._s[177]!, self._r[177]!, [_1, _2, _3])
|
return formatWithArgumentRanges(self._s[178]!, self._r[178]!, [_1, _2, _3])
|
||||||
}
|
}
|
||||||
public func Wallet_Send_ConfirmationText(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
|
public func Wallet_Send_ConfirmationText(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
|
||||||
return formatWithArgumentRanges(self._s[178]!, self._r[178]!, [_1, _2])
|
return formatWithArgumentRanges(self._s[179]!, self._r[179]!, [_1, _2])
|
||||||
}
|
}
|
||||||
public var Wallet_Created_ExportErrorText: String { return self._s[180]! }
|
public var Wallet_Created_ExportErrorText: String { return self._s[181]! }
|
||||||
public func Wallet_Updated_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
|
public func Wallet_Updated_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
|
||||||
return formatWithArgumentRanges(self._s[181]!, self._r[181]!, [_0])
|
return formatWithArgumentRanges(self._s[182]!, self._r[182]!, [_0])
|
||||||
}
|
}
|
||||||
public var Wallet_Settings_DeleteWalletInfo: String { return self._s[182]! }
|
public var Wallet_Settings_DeleteWalletInfo: String { return self._s[183]! }
|
||||||
public var Wallet_Intro_CreateErrorText: String { return self._s[183]! }
|
public var Wallet_Intro_CreateErrorText: String { return self._s[184]! }
|
||||||
public var Wallet_Sent_ViewWallet: String { return self._s[184]! }
|
public var Wallet_Sent_ViewWallet: String { return self._s[185]! }
|
||||||
public var Wallet_Send_ErrorInvalidAddress: String { return self._s[185]! }
|
public var Wallet_Send_ErrorInvalidAddress: String { return self._s[186]! }
|
||||||
public func Wallet_Time_PreciseDate_m7(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
|
public func Wallet_Time_PreciseDate_m7(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
|
||||||
return formatWithArgumentRanges(self._s[186]!, self._r[186]!, [_1, _2, _3])
|
return formatWithArgumentRanges(self._s[187]!, self._r[187]!, [_1, _2, _3])
|
||||||
}
|
}
|
||||||
public var Wallet_Send_Title: String { return self._s[187]! }
|
public var Wallet_Send_Title: String { return self._s[188]! }
|
||||||
public var Wallet_Info_RefreshErrorText: String { return self._s[188]! }
|
public var Wallet_Info_RefreshErrorText: String { return self._s[189]! }
|
||||||
public var Wallet_SecureStorageReset_Title: String { return self._s[189]! }
|
public var Wallet_SecureStorageReset_Title: String { return self._s[190]! }
|
||||||
public var Wallet_Receive_CommentHeader: String { return self._s[190]! }
|
public var Wallet_Receive_CommentHeader: String { return self._s[191]! }
|
||||||
public var Wallet_Info_ReceiveGrams: String { return self._s[191]! }
|
public var Wallet_Info_ReceiveGrams: String { return self._s[192]! }
|
||||||
public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
|
public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
|
||||||
let form = getPluralizationForm(self.lc, value)
|
let form = getPluralizationForm(self.lc, value)
|
||||||
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
||||||
|
@ -2283,7 +2283,7 @@ private final class WordCheckInputNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
self.backgroundNode = ASImageNode()
|
self.backgroundNode = ASImageNode()
|
||||||
self.backgroundNode.displaysAsynchronously = false
|
self.backgroundNode.displaysAsynchronously = false
|
||||||
self.backgroundNode.displayWithoutProcessing = true
|
self.backgroundNode.displayWithoutProcessing = true
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 10.0, color: theme.setup.inputBackgroundColor)
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 20.0, color: theme.setup.inputBackgroundColor)
|
||||||
|
|
||||||
self.labelNode = ImmediateTextNode()
|
self.labelNode = ImmediateTextNode()
|
||||||
self.labelNode.attributedText = NSAttributedString(string: "\(index + 1):", font: Font.regular(17.0), textColor: theme.setup.inputPlaceholderColor)
|
self.labelNode.attributedText = NSAttributedString(string: "\(index + 1):", font: Font.regular(17.0), textColor: theme.setup.inputPlaceholderColor)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user