init, finished
This commit is contained in:
186
GIFCollector MessagesExtension/Views/AddGIFViewController.swift
Normal file
186
GIFCollector MessagesExtension/Views/AddGIFViewController.swift
Normal file
@@ -0,0 +1,186 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user