mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
5b58ad5018
commit
56aff0306e
@ -93,6 +93,15 @@ public final class PhoneInputNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var codeNumberAndFullNumber: (String, String, String) {
|
||||||
|
let full = self.number
|
||||||
|
return (
|
||||||
|
cleanPhoneNumber(self.countryCodeField.textField.text ?? ""),
|
||||||
|
cleanPhoneNumber(self.numberField.textField.text ?? ""),
|
||||||
|
full
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
public var countryCodeText: String {
|
public var countryCodeText: String {
|
||||||
get {
|
get {
|
||||||
return self.countryCodeField.textField.text ?? ""
|
return self.countryCodeField.textField.text ?? ""
|
||||||
|
@ -486,18 +486,22 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat
|
|||||||
action(peers, nil)
|
action(peers, nil)
|
||||||
})
|
})
|
||||||
case .phone:
|
case .phone:
|
||||||
var phoneNumber: String?
|
var code: String?
|
||||||
|
var number: String?
|
||||||
controller?.forEachItemNode { itemNode in
|
controller?.forEachItemNode { itemNode in
|
||||||
if let itemNode = itemNode as? DeleteAccountPhoneItemNode {
|
if let itemNode = itemNode as? DeleteAccountPhoneItemNode {
|
||||||
var phoneValue = itemNode.phoneNumber
|
let value = itemNode.codeNumberAndFullNumber
|
||||||
if phoneValue.hasPrefix("+939998") {
|
if value.0 == "+93" && value.1.hasPrefix("9998") {
|
||||||
phoneValue = phoneValue.replacingOccurrences(of: "+939998", with: "+9998")
|
code = "+"
|
||||||
|
number = value.1
|
||||||
|
} else {
|
||||||
|
code = value.0
|
||||||
|
number = value.1
|
||||||
}
|
}
|
||||||
phoneNumber = phoneValue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let phoneNumber = phoneNumber, phoneNumber.count > 4 {
|
if let code, var number, (code + number).count > 4 {
|
||||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
||||||
|> deliverOnMainQueue)
|
|> deliverOnMainQueue)
|
||||||
.start(next: { accountPeer in
|
.start(next: { accountPeer in
|
||||||
@ -505,7 +509,20 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat
|
|||||||
if !phone.hasPrefix("+") {
|
if !phone.hasPrefix("+") {
|
||||||
phone = "+\(phone)"
|
phone = "+\(phone)"
|
||||||
}
|
}
|
||||||
if phone != phoneNumber {
|
|
||||||
|
var matches = false
|
||||||
|
if phone == (code + number) {
|
||||||
|
matches = true
|
||||||
|
} else {
|
||||||
|
while number.hasPrefix("0") {
|
||||||
|
number.removeFirst()
|
||||||
|
if phone == (code + number) {
|
||||||
|
matches = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matches {
|
||||||
secondaryActionDisabled = false
|
secondaryActionDisabled = false
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.DeleteAccount_InvalidPhoneNumberError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.DeleteAccount_InvalidPhoneNumberError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||||
return
|
return
|
||||||
|
@ -188,13 +188,13 @@ class DeleteAccountPhoneItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(country.id, strings: item.strings) ?? country.name
|
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(country.id, strings: item.strings) ?? country.name
|
||||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(17.0), with: item.theme.list.itemPrimaryTextColor, for: [])
|
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(17.0), with: item.theme.list.itemPrimaryTextColor, for: [])
|
||||||
|
|
||||||
let maskFont = Font.with(size: 20.0, design: .regular, traits: [.monospacedNumbers])
|
let maskFont = Font.with(size: 17.0, design: .regular, traits: [.monospacedNumbers])
|
||||||
if let mask = AuthorizationSequenceCountrySelectionController.lookupPatternByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode).flatMap({ NSAttributedString(string: $0, font: maskFont, textColor: item.theme.list.itemPlaceholderTextColor) }) {
|
if let mask = AuthorizationSequenceCountrySelectionController.lookupPatternByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode).flatMap({ NSAttributedString(string: $0, font: maskFont, textColor: item.theme.list.itemPlaceholderTextColor) }) {
|
||||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = nil
|
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = nil
|
||||||
strongSelf.phoneInputNode.mask = mask
|
strongSelf.phoneInputNode.mask = mask
|
||||||
} else {
|
} else {
|
||||||
strongSelf.phoneInputNode.mask = nil
|
strongSelf.phoneInputNode.mask = nil
|
||||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: item.strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: item.theme.list.itemPlaceholderTextColor)
|
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: item.strings.Login_PhonePlaceholder, font: Font.regular(17.0), textColor: item.theme.list.itemPlaceholderTextColor)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -269,6 +269,10 @@ class DeleteAccountPhoneItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
return self.phoneInputNode.number
|
return self.phoneInputNode.number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var codeNumberAndFullNumber: (String, String, String) {
|
||||||
|
return self.phoneInputNode.codeNumberAndFullNumber
|
||||||
|
}
|
||||||
|
|
||||||
func updateCountryCode() {
|
func updateCountryCode() {
|
||||||
self.phoneInputNode.codeAndNumber = self.phoneInputNode.codeAndNumber
|
self.phoneInputNode.codeAndNumber = self.phoneInputNode.codeAndNumber
|
||||||
}
|
}
|
||||||
@ -397,7 +401,7 @@ class DeleteAccountPhoneItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
strongSelf.phoneInputNode.frame = phoneInputFrame
|
strongSelf.phoneInputNode.frame = phoneInputFrame
|
||||||
strongSelf.phoneInputNode.countryCodeField.frame = countryCodeFrame.offsetBy(dx: -phoneInputFrame.minX, dy: -phoneInputFrame.minY)
|
strongSelf.phoneInputNode.countryCodeField.frame = countryCodeFrame.offsetBy(dx: -phoneInputFrame.minX, dy: -phoneInputFrame.minY)
|
||||||
strongSelf.phoneInputNode.numberField.frame = numberFrame.offsetBy(dx: -phoneInputFrame.minX, dy: -phoneInputFrame.minY)
|
strongSelf.phoneInputNode.numberField.frame = numberFrame.offsetBy(dx: -phoneInputFrame.minX, dy: -phoneInputFrame.minY)
|
||||||
strongSelf.phoneInputNode.placeholderNode.frame = placeholderFrame.offsetBy(dx: -phoneInputFrame.minX, dy: -phoneInputFrame.minY)
|
strongSelf.phoneInputNode.placeholderNode.frame = placeholderFrame.offsetBy(dx: -phoneInputFrame.minX, dy: -phoneInputFrame.minY + 4.0 + UIScreenPixel)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -800,7 +800,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
|||||||
if let boostStatus {
|
if let boostStatus {
|
||||||
boostData = .single(boostStatus)
|
boostData = .single(boostStatus)
|
||||||
} else {
|
} else {
|
||||||
boostData = context.engine.peers.getChannelBoostStatus(peerId: peerId)
|
boostData = .single(nil) |> then(context.engine.peers.getChannelBoostStatus(peerId: peerId))
|
||||||
}
|
}
|
||||||
let boostersContext = ChannelBoostersContext(account: context.account, peerId: peerId)
|
let boostersContext = ChannelBoostersContext(account: context.account, peerId: peerId)
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
|
|||||||
case storyStealthModeReplyCount = 47
|
case storyStealthModeReplyCount = 47
|
||||||
case viewOnceTooltip = 48
|
case viewOnceTooltip = 48
|
||||||
case displayStoryUnmuteTooltip = 49
|
case displayStoryUnmuteTooltip = 49
|
||||||
|
case displayStoryInteractionGuide = 50
|
||||||
|
|
||||||
var key: ValueBoxKey {
|
var key: ValueBoxKey {
|
||||||
let v = ValueBoxKey(length: 4)
|
let v = ValueBoxKey(length: 4)
|
||||||
@ -434,6 +435,10 @@ private struct ApplicationSpecificNoticeKeys {
|
|||||||
static func displayStoryUnmuteTooltip() -> NoticeEntryKey {
|
static func displayStoryUnmuteTooltip() -> NoticeEntryKey {
|
||||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.displayStoryUnmuteTooltip.key)
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.displayStoryUnmuteTooltip.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func displayStoryInteractionGuide() -> NoticeEntryKey {
|
||||||
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.displayStoryInteractionGuide.key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ApplicationSpecificNotice {
|
public struct ApplicationSpecificNotice {
|
||||||
@ -1659,4 +1664,25 @@ public struct ApplicationSpecificNotice {
|
|||||||
}
|
}
|
||||||
|> take(1)
|
|> take(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func setDisplayStoryInteractionGuide(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Never, NoError> {
|
||||||
|
return accountManager.transaction { transaction -> Void in
|
||||||
|
if let entry = CodableEntry(ApplicationSpecificBoolNotice()) {
|
||||||
|
transaction.setNotice(ApplicationSpecificNoticeKeys.displayStoryInteractionGuide(), entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func displayStoryInteractionGuide(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Bool, NoError> {
|
||||||
|
return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.displayStoryInteractionGuide())
|
||||||
|
|> map { view -> Bool in
|
||||||
|
if let _ = view.value?.get(ApplicationSpecificBoolNotice.self) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> take(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,10 +393,9 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
|
|
||||||
private var pendingNavigationToItemId: (peerId: EnginePeer.Id, id: Int32)?
|
private var pendingNavigationToItemId: (peerId: EnginePeer.Id, id: Int32)?
|
||||||
|
|
||||||
private var didDisplayReactionTooltip: Bool = false
|
|
||||||
|
|
||||||
private let interactionGuide = ComponentView<Empty>()
|
private let interactionGuide = ComponentView<Empty>()
|
||||||
private var isDisplayingInteractionGuide: Bool = false
|
private var isDisplayingInteractionGuide: Bool = false
|
||||||
|
private var displayInteractionGuideDisposable: Disposable?
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
self.backgroundLayer = SimpleLayer()
|
self.backgroundLayer = SimpleLayer()
|
||||||
@ -637,6 +636,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
self.headphonesDisposable?.dispose()
|
self.headphonesDisposable?.dispose()
|
||||||
self.stealthModeDisposable?.dispose()
|
self.stealthModeDisposable?.dispose()
|
||||||
self.stealthModeTimer?.invalidate()
|
self.stealthModeTimer?.invalidate()
|
||||||
|
self.displayInteractionGuideDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
@ -893,10 +893,6 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
self.didAnimateIn = true
|
self.didAnimateIn = true
|
||||||
self.state?.updated(transition: .immediate)
|
self.state?.updated(transition: .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let view = self.interactionGuide.view as? StoryInteractionGuideComponent.View {
|
|
||||||
view.animateIn(transitionIn: transitionIn)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.didAnimateIn = true
|
self.didAnimateIn = true
|
||||||
self.state?.updated(transition: .immediate)
|
self.state?.updated(transition: .immediate)
|
||||||
@ -926,13 +922,11 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !value {
|
if !value && !self.isDisplayingInteractionGuide {
|
||||||
if let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id], let currentItemView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
if let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id], let currentItemView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||||
currentItemView.maybeDisplayReactionTooltip()
|
currentItemView.maybeDisplayReactionTooltip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.didDisplayReactionTooltip = true
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1119,6 +1113,22 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let accountManager = component.context.sharedContext.accountManager
|
||||||
|
self.displayInteractionGuideDisposable = (ApplicationSpecificNotice.displayStoryInteractionGuide(accountManager: accountManager)
|
||||||
|
|> deliverOnMainQueue).startStrict(next: { [weak self] value in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !value {
|
||||||
|
self.isDisplayingInteractionGuide = true
|
||||||
|
if update {
|
||||||
|
self.state?.updated(transition: .immediate)
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = ApplicationSpecificNotice.setDisplayStoryInteractionGuide(accountManager: accountManager).startStandalone()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
update = true
|
update = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1718,15 +1728,18 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
strings: environment.strings,
|
strings: environment.strings,
|
||||||
action: { [weak self] in
|
action: { [weak self] in
|
||||||
self?.isDisplayingInteractionGuide = false
|
self?.isDisplayingInteractionGuide = false
|
||||||
|
self?.state?.updated()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: availableSize
|
containerSize: availableSize
|
||||||
)
|
)
|
||||||
if let view = self.interactionGuide.view {
|
if let view = self.interactionGuide.view as? StoryInteractionGuideComponent.View {
|
||||||
if view.superview == nil {
|
if view.superview == nil {
|
||||||
self.addSubview(view)
|
self.addSubview(view)
|
||||||
|
|
||||||
|
view.animateIn()
|
||||||
}
|
}
|
||||||
view.layer.zPosition = 1000.0
|
view.layer.zPosition = 1000.0
|
||||||
view.frame = CGRect(origin: .zero, size: availableSize)
|
view.frame = CGRect(origin: .zero, size: availableSize)
|
||||||
|
@ -66,7 +66,10 @@ final class StoryInteractionGuideComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func animateIn(transitionIn: StoryContainerScreen.TransitionIn) {
|
var didAnimateOut = false
|
||||||
|
|
||||||
|
func animateIn() {
|
||||||
|
self.didAnimateOut = false
|
||||||
UIView.animate(withDuration: 0.2) {
|
UIView.animate(withDuration: 0.2) {
|
||||||
self.effectView.effect = UIBlurEffect(style: .dark)
|
self.effectView.effect = UIBlurEffect(style: .dark)
|
||||||
}
|
}
|
||||||
@ -75,6 +78,10 @@ final class StoryInteractionGuideComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func animateOut(completion: @escaping () -> Void) {
|
func animateOut(completion: @escaping () -> Void) {
|
||||||
|
guard !self.didAnimateOut else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.didAnimateOut = true
|
||||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||||
completion()
|
completion()
|
||||||
})
|
})
|
||||||
@ -87,6 +94,7 @@ final class StoryInteractionGuideComponent: Component {
|
|||||||
|
|
||||||
let sideInset: CGFloat = 48.0
|
let sideInset: CGFloat = 48.0
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
let titleSize = self.titleLabel.update(
|
let titleSize = self.titleLabel.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Watching Stories", font: Font.semibold(20.0), textColor: .white, paragraphAlignment: .center)))),
|
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Watching Stories", font: Font.semibold(20.0), textColor: .white, paragraphAlignment: .center)))),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user