187 lines
6.2 KiB
Swift
187 lines
6.2 KiB
Swift
import UIKit
|
|
|
|
class AddGIFViewController: UIViewController {
|
|
|
|
private let titleLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.text = "Add New GIF"
|
|
label.font = .systemFont(ofSize: 18, weight: .bold)
|
|
label.textAlignment = .center
|
|
return label
|
|
}()
|
|
|
|
private let urlTextField: UITextField = {
|
|
let textField = UITextField()
|
|
textField.placeholder = "Enter GIF URL"
|
|
textField.borderStyle = .roundedRect
|
|
textField.autocorrectionType = .no
|
|
textField.autocapitalizationType = .none
|
|
textField.keyboardType = .URL
|
|
textField.returnKeyType = .next
|
|
textField.clearButtonMode = .whileEditing
|
|
return textField
|
|
}()
|
|
|
|
|
|
|
|
private let previewGIFPlayer: GIFPlayerView = {
|
|
let player = GIFPlayerView()
|
|
player.clipsToBounds = true
|
|
player.layer.cornerRadius = 8
|
|
player.backgroundColor = .systemGray6
|
|
return player
|
|
}()
|
|
|
|
private let loadingIndicator: UIActivityIndicatorView = {
|
|
let indicator = UIActivityIndicatorView(style: .medium)
|
|
indicator.hidesWhenStopped = true
|
|
return indicator
|
|
}()
|
|
|
|
private let saveButton: UIButton = {
|
|
let button = UIButton(type: .system)
|
|
button.setTitle("Save", for: .normal)
|
|
button.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
button.backgroundColor = .systemBlue
|
|
button.setTitleColor(.white, for: .normal)
|
|
button.layer.cornerRadius = 8
|
|
button.isEnabled = false
|
|
return button
|
|
}()
|
|
|
|
private let cancelButton: UIButton = {
|
|
let button = UIButton(type: .system)
|
|
button.setTitle("Cancel", for: .normal)
|
|
button.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
return button
|
|
}()
|
|
|
|
private var currentTask: URLSessionDataTask?
|
|
var onSaveGIF: ((GIF) -> Void)?
|
|
var onCancel: (() -> Void)?
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
setupUI()
|
|
setupActions()
|
|
}
|
|
|
|
private func setupUI() {
|
|
view.backgroundColor = .systemBackground
|
|
|
|
view.addSubview(titleLabel)
|
|
view.addSubview(urlTextField)
|
|
view.addSubview(previewGIFPlayer)
|
|
view.addSubview(loadingIndicator)
|
|
view.addSubview(saveButton)
|
|
view.addSubview(cancelButton)
|
|
|
|
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
urlTextField.translatesAutoresizingMaskIntoConstraints = false
|
|
previewGIFPlayer.translatesAutoresizingMaskIntoConstraints = false
|
|
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
|
|
saveButton.translatesAutoresizingMaskIntoConstraints = false
|
|
cancelButton.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
NSLayoutConstraint.activate([
|
|
titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
|
|
titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
|
titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
|
|
|
urlTextField.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),
|
|
urlTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
|
urlTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
|
|
|
previewGIFPlayer.topAnchor.constraint(equalTo: urlTextField.bottomAnchor, constant: 16),
|
|
previewGIFPlayer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
|
previewGIFPlayer.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
|
previewGIFPlayer.heightAnchor.constraint(equalToConstant: 150),
|
|
|
|
loadingIndicator.centerXAnchor.constraint(equalTo: previewGIFPlayer.centerXAnchor),
|
|
loadingIndicator.centerYAnchor.constraint(equalTo: previewGIFPlayer.centerYAnchor),
|
|
|
|
saveButton.topAnchor.constraint(equalTo: previewGIFPlayer.bottomAnchor, constant: 24),
|
|
saveButton.leadingAnchor.constraint(equalTo: view.centerXAnchor, constant: 8),
|
|
saveButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
|
saveButton.heightAnchor.constraint(equalToConstant: 44),
|
|
|
|
cancelButton.topAnchor.constraint(equalTo: previewGIFPlayer.bottomAnchor, constant: 24),
|
|
cancelButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
|
cancelButton.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant: -8),
|
|
cancelButton.heightAnchor.constraint(equalToConstant: 44),
|
|
])
|
|
}
|
|
|
|
private func setupActions() {
|
|
urlTextField.delegate = self
|
|
|
|
urlTextField.addTarget(self, action: #selector(urlTextDidChange), for: .editingChanged)
|
|
|
|
saveButton.addTarget(self, action: #selector(saveButtonTapped), for: .touchUpInside)
|
|
cancelButton.addTarget(self, action: #selector(cancelButtonTapped), for: .touchUpInside)
|
|
}
|
|
|
|
@objc private func urlTextDidChange() {
|
|
guard let urlString = urlTextField.text, !urlString.isEmpty else {
|
|
previewGIFPlayer.stopAnimating()
|
|
saveButton.isEnabled = false
|
|
return
|
|
}
|
|
|
|
loadGIFPreview(from: urlString)
|
|
}
|
|
|
|
private func loadGIFPreview(from urlString: String) {
|
|
// Cancel any existing task
|
|
currentTask?.cancel()
|
|
|
|
guard let url = URL(string: urlString) else {
|
|
saveButton.isEnabled = false
|
|
return
|
|
}
|
|
|
|
loadingIndicator.startAnimating()
|
|
previewGIFPlayer.stopAnimating()
|
|
|
|
currentTask = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
|
|
DispatchQueue.main.async {
|
|
guard let self = self else { return }
|
|
|
|
self.loadingIndicator.stopAnimating()
|
|
|
|
if let data = data, error == nil {
|
|
self.previewGIFPlayer.loadGIF(from: data)
|
|
self.previewGIFPlayer.startAnimating()
|
|
self.saveButton.isEnabled = true
|
|
} else {
|
|
self.previewGIFPlayer.stopAnimating()
|
|
self.saveButton.isEnabled = false
|
|
}
|
|
}
|
|
}
|
|
|
|
currentTask?.resume()
|
|
}
|
|
|
|
@objc private func saveButtonTapped() {
|
|
guard let urlString = urlTextField.text, !urlString.isEmpty else { return }
|
|
|
|
let gif = GIF(urlString: urlString)
|
|
|
|
onSaveGIF?(gif)
|
|
dismiss(animated: true)
|
|
}
|
|
|
|
@objc private func cancelButtonTapped() {
|
|
onCancel?()
|
|
dismiss(animated: true)
|
|
}
|
|
}
|
|
|
|
extension AddGIFViewController: UITextFieldDelegate {
|
|
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
|
textField.resignFirstResponder()
|
|
return true
|
|
}
|
|
}
|