diff --git a/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift b/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift index 6ba3381665..6c536c036d 100644 --- a/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift @@ -414,9 +414,9 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry { arguments.setPhoneIdWithRevealedOptions(lhs, rhs) }, updated: { value in arguments.updatePhone(id, value) - }, selectLabel: nil /*{ + }, selectLabel: { arguments.updatePhoneLabel(id, label) - }*/, delete: { + }, delete: { arguments.deletePhone(id) }, tag: DeviceContactInfoEntryTag.editingPhone(id)) case let .addPhoneNumber(_, theme, title): @@ -654,8 +654,8 @@ private func deviceContactInfoEntries(account: Account, presentationData: Presen } else { if editingPhoneNumbers { for number in state.phoneNumbers { - let label = !number.label.isEmpty ? number.label : presentationData.strings.ContactInfo_PhoneLabelMain - entries.append(.editingPhoneNumber(entries.count, presentationData.theme, presentationData.strings, number.id, localizedPhoneNumberLabel(label: label, strings: presentationData.strings), number.label, number.value, state.phoneIdWithRevealedOptions == number.id)) + let label = !number.label.isEmpty ? number.label : "_$!!$_" + entries.append(.editingPhoneNumber(entries.count, presentationData.theme, presentationData.strings, number.id, localizedPhoneNumberLabel(label: label, strings: presentationData.strings), label, number.value, state.phoneIdWithRevealedOptions == number.id)) } entries.append(.addPhoneNumber(entries.count, presentationData.theme, presentationData.strings.UserInfo_AddPhone)) } else { @@ -927,7 +927,18 @@ public func deviceContactInfoController(context: AccountContext, subject: Device return state } }, updatePhoneLabel: { id, currentLabel in - + presentControllerImpl?(phoneLabelController(context: context, currentLabel: currentLabel, completion: { value in + updateState { state in + var state = state + for i in 0 ..< state.phoneNumbers.count { + if state.phoneNumbers[i].id == id { + state.phoneNumbers[i].label = value + break + } + } + return state + } + }), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }, deletePhone: { id in updateState { state in var state = state diff --git a/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift b/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift new file mode 100644 index 0000000000..f22b84e79b --- /dev/null +++ b/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift @@ -0,0 +1,139 @@ +import Foundation +import UIKit +import Display +import SwiftSignalKit +import Postbox +import TelegramCore +import TelegramPresentationData + +private struct PhoneLabelArguments { + let selectLabel: (String) -> Void + let complete: () -> Void + let cancel: () -> Void +} + +private struct PhoneLabelState: Equatable { + var currentLabel: String +} + +private enum PhoneLabelSection: Int32 { + case labels +} + +private enum PhoneLabelEntryId: Hashable { + case label(String) +} + +private enum PhoneLabelEntry: ItemListNodeEntry { + case label(Int, PresentationTheme, String, String, Bool) + + var section: ItemListSectionId { + switch self { + case .label: + return PhoneLabelSection.labels.rawValue + } + } + + var stableId: PhoneLabelEntryId { + switch self { + case let .label(_, _, label, _, _): + return .label(label) + } + } + + var index: Int { + switch self { + case let .label(index, _, _, _, _): + return index + } + } + + static func <(lhs: PhoneLabelEntry, rhs: PhoneLabelEntry) -> Bool { + return lhs.index < rhs.index + } + + func item(_ arguments: PhoneLabelArguments) -> ListViewItem { + switch self { + case let .label(_, theme, value, text, selected): + return ItemListCheckboxItem(theme: theme, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: { + arguments.selectLabel(value) + }) + } + } +} + +private func phoneLabelEntries(presentationData: PresentationData, state: PhoneLabelState) -> [PhoneLabelEntry] { + var entries: [PhoneLabelEntry] = [] + + let labels: [String] = [ + "_$!!$_", + "X-iPhone", + "_$!!$_", + "_$!
!$_", + "_$!!$_", + "_$!!$_", + ] + + for label in labels { + entries.append(.label(entries.count, presentationData.theme, label, localizedPhoneNumberLabel(label: label, strings: presentationData.strings), state.currentLabel == label)) + } + + return entries +} + +public func phoneLabelController(context: AccountContext, currentLabel: String, completion: @escaping (String) -> Void) -> ViewController { + let statePromise = ValuePromise(PhoneLabelState(currentLabel: currentLabel)) + let stateValue = Atomic(value: PhoneLabelState(currentLabel: currentLabel)) + let updateState: ((PhoneLabelState) -> PhoneLabelState) -> Void = { f in + statePromise.set(stateValue.modify { f($0) }) + } + + var completeImpl: (() -> Void)? + var cancelImpl: (() -> Void)? + + let arguments = PhoneLabelArguments(selectLabel: { label in + updateState { state in + var state = state + state.currentLabel = label + return state + } + }, complete: { + completeImpl?() + }, cancel: { + cancelImpl?() + }) + + let signal = combineLatest(context.sharedContext.presentationData, statePromise.get()) + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, PhoneLabelEntry.ItemGenerationArguments)) in + + let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { + arguments.cancel() + }) + + let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: { + arguments.complete() + }) + + let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Notifications_TextTone), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back)) + let listState = ItemListNodeState(entries: phoneLabelEntries(presentationData: presentationData, state: state), style: .blocks) + + return (controllerState, (listState, arguments)) + } + + let controller = ItemListController(context: context, state: signal + |> afterDisposed { + }) + controller.enableInteractiveDismiss = true + + completeImpl = { [weak controller] in + let currentLabel = stateValue.with({ $0 }).currentLabel + completion(currentLabel) + controller?.dismiss() + } + + cancelImpl = { [weak controller] in + controller?.dismiss() + } + + return controller +}