jsoncreator_app/JSONCreator_iOS/JSONCreator/DetailViewController.swift
2024-07-16 21:11:38 -04:00

189 lines
9.5 KiB
Swift

//
// DetailViewController.swift
// JSONCreator
//
// Created by Scott Pfeil on 8/2/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
import MVMCoreUI
class DetailViewController: UIViewController {
let textView = UITextView(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
guard textView.superview == nil else {
return
}
modalPresentationStyle = .fullScreen
view.addSubview(textView)
if UIDevice.current.userInterfaceIdiom == .pad {
textView.font = UIFont.systemFont(ofSize: 40)
} else {
textView.font = UIFont.systemFont(ofSize: 14)
}
textView.translatesAutoresizingMaskIntoConstraints = false
textView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: textView.trailingAnchor).isActive = true
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true
textView.delegate = self
textView.smartDashesType = .no
textView.smartQuotesType = .no
textView.smartInsertDeleteType = .no
textView.autocapitalizationType = .none
textView.autocorrectionType = .no
if let data = UserDefaults.standard.data(forKey: "prior"),
let prior = String(data: data, encoding: .utf8) {
textView.text = prior
}
let clearButton = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(clearButtonPressed))
let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareButtonPressed))
let buildButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(play))
navigationItem.setRightBarButtonItems([shareButton,clearButton, buildButton], animated: true)
JSONCreatorActionHandler.doStuff()
}
func showError(_ error: NSError) {
let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
@objc func clearButtonPressed() {
textView.text = ""
UserDefaults.standard.removeObject(forKey: "prior")
}
@objc func shareButtonPressed() {
if let text = textView.text {
let activityController = UIActivityViewController(activityItems: [text], applicationActivities: nil)
activityController.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
present(activityController, animated: true, completion: nil)
}
}
@objc func play() {
do {
if let data = textView.text.data(using: .utf8), let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyHashable: Any] {
guard let page = jsonObject.optionalDictionaryForKey(KeyPage) else {
let error = NSError(domain: ErrorDomainNative, code: ErrorCode.parsingJSON.rawValue, userInfo: [NSLocalizedDescriptionKey: "Needs a Page to show."])
showError(error)
return
}
guard let pageType = page.optionalStringForKey(KeyPageType) else {
let error = NSError(domain: ErrorDomainNative, code: ErrorCode.parsingJSON.rawValue, userInfo: [NSLocalizedDescriptionKey: "Needs a pageType."])
showError(error)
return
}
let template = page.optionalStringForKey("template")
let moduleMap = jsonObject.optionalDictionaryForKey(KeyModuleMap)
var errorObject: MVMCoreErrorObject? = MVMCoreErrorObject(title: nil, message: "No Template Found", code: ErrorCode.initViewController.rawValue, domain: ErrorDomainNative, location: nil)
if let viewController = MVMCoreUIViewControllerMappingObject.shared()?.createMFViewController(ofTemplate: template, pageType: pageType),
let loadObject = MVMCoreLoadObject(pageJSON: page, modulesJSON: moduleMap, requestParameters: nil, dataForPage: nil, delegateObject: nil),
viewController.shouldFinishProcessingLoad(loadObject, error: &errorObject) {
UserDefaults.standard.set(data, forKey: "prior")
Task(priority: .userInitiated) { @MainActor in
let gr = UILongPressGestureRecognizer(target: self, action: #selector(DetailViewController.close))
viewController.view.addGestureRecognizer(gr)
let topAlert = NotificationContainerView()
CoreUIObject.sharedInstance()?.topNotificationHandler = NotificationHandler(with: topAlert)
let split = MVMCoreUISplitViewController.setup(asMainController: nil, rightPanel: nil, topAlert: topAlert)!
_ = split.view // Force loadView
let done = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.close))
let update = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(self.update))
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
split.navigationController?.isToolbarHidden = false
viewController.setToolbarItems([update, spacer, done], animated: false)
split.navigationController?.setToolbarItems([spacer, done], animated: false)
NavigationHandler.shared().viewControllerToPresentOn = split
UIApplication.shared.delegate?.window??.rootViewController = split
//await MVMCoreLoadRequestOperation.processJSON(fromServer: jsonObject, loadObject: loadObject)
await NavigationHandler.shared().push(viewController: viewController, animated: false)
}
} else if let errorObject = errorObject {
let error = NSError(domain: ErrorDomainNative, code: ErrorCode.initViewController.rawValue, userInfo: [NSLocalizedDescriptionKey: errorObject.messageToLog ?? errorObject.messageToDisplay!])
showError(error)
}
}
} catch {
showError(error as NSError)
}
}
@objc func update() {
Task { @MainActor in
let moleculeReplacementVC = MoleculeReplacementViewController()
moleculeReplacementVC.replaceCallback = { [weak self] serverResponse, loadObject, delay, replay in
Task {
await NavigationHandler.shared().popTopViewController()
repeat {
try? await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))
await MVMCoreLoadRequestOperation.processJSON(fromServer: serverResponse, loadObject: loadObject)
} while(replay && self != nil)
}
}
await NavigationHandler.shared().push(viewController: moleculeReplacementVC)
}
}
@objc func close() {
guard let splitViewController = (UIApplication.shared.delegate as? AppDelegate)?.splitViewController else { return }
NavigationHandler.shared().viewControllerToPresentOn = splitViewController
UIApplication.shared.delegate?.window??.rootViewController = splitViewController
}
}
extension DetailViewController: UITextViewDelegate {
func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
guard textView.text.count > 0 else {
return true
}
do {
if let data = textView.text.data(using: .utf8) {
let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
_ = try JSONSerialization.data(withJSONObject: jsonObject, options: [.prettyPrinted, .sortedKeys])
}
return true
} catch {
let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
return false
}
}
func textViewDidEndEditing(_ textView: UITextView) {
guard textView.text.count > 0 else {
return
}
do {
if let data = textView.text.data(using: .utf8) {
let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
let prettyData = try JSONSerialization.data(withJSONObject: jsonObject, options: [.prettyPrinted, .sortedKeys])
let prettyString = String.init(data: prettyData, encoding: .utf8)
textView.text = prettyString
}
} catch {
let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
}
}