From 3522f79b18531e36f94f8439148037645ce3ce80 Mon Sep 17 00:00:00 2001 From: Vegard Bieker Matthey Date: Tue, 28 Jul 2026 01:01:14 +0200 Subject: [PATCH] add long press option for viewing metadata and deleting comic --- ImageViewer/ViewController.swift | 134 +++++++++++++++++++++++++++ ImageViewer/metadata_generated.swift | 1 + 2 files changed, 135 insertions(+) diff --git a/ImageViewer/ViewController.swift b/ImageViewer/ViewController.swift index 80ca728..981445f 100644 --- a/ImageViewer/ViewController.swift +++ b/ImageViewer/ViewController.swift @@ -170,6 +170,9 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { comicCollectionView.register( ComicImageCell.self, forCellWithReuseIdentifier: "ComicImageCell" ) + let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:))) + longPress.minimumPressDuration = 0.5 + comicCollectionView.addGestureRecognizer(longPress) homeView.addSubview(comicCollectionView) } @@ -1279,6 +1282,15 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { backgroundColorDropdownView.isHidden = true } + @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) { + guard gesture.state == .began else { return } + + let point = gesture.location(in: comicCollectionView) + guard let indexPath = comicCollectionView.indexPathForItem(at: point) else { return } + + showComicOptions(for: indexPath) + } + @objc func handleTopTap() { toggleBar() } @@ -1382,6 +1394,39 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { saveLocalState() } + func showComicOptions(for indexPath: IndexPath) { + let alert = UIAlertController(title: "Options", message: nil, preferredStyle: .actionSheet) + alert.addAction(UIAlertAction(title: "View Metadata", style: .default) { _ in + let metadataVC = ComicMetadataViewController(comic: self.comics[indexPath.item].metadata) + let nav = UINavigationController(rootViewController: metadataVC) + nav.modalPresentationStyle = .formSheet + self.present(nav, animated: false) + }) + alert.addAction(UIAlertAction(title: "Delete", style: .destructive) { _ in + do { + try self.fileManager.removeItem(at: self.comics[indexPath.item].path) + self.comics.remove(at: indexPath.item) + self.comicCollectionView.reloadData() + } catch { + let failureAlert = UIAlertController( + title: "Failed to remove directory.", + message: "Failed to recursively remove \(self.comics[indexPath.item].path)", + preferredStyle: .alert + ) + self.present(failureAlert, animated: false) + } + }) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) + + // Required for iPad, harmless on iPhone + if let cell = comicCollectionView.cellForItem(at: indexPath) { + alert.popoverPresentationController?.sourceView = cell + alert.popoverPresentationController?.sourceRect = cell.bounds + } + + present(alert, animated: false) + } + func metaValueToString(m: MetaValue) -> String { var r = "" if m.bonus != 0 { @@ -1994,3 +2039,92 @@ func imageDimensions(of entry: Entry, in archive: Archive) throws -> ImageDimens throw ImageSizeError.couldNotDetermineSize } + +class ComicMetadataViewController: UITableViewController { + private let comic: Metadata + + init(comic: Metadata) { + self.comic = comic + super.init(style: .grouped) + } + + @available(*, unavailable) + required init?(coder _: NSCoder) { + fatalError() + } + + override func viewDidLoad() { + super.viewDidLoad() + title = "Metadata" + navigationItem.rightBarButtonItem = UIBarButtonItem( + barButtonSystemItem: .done, target: self, action: #selector(dismissSelf) + ) + } + + @objc private func dismissSelf() { + dismiss(animated: false) + } + + override func numberOfSections(in _: UITableView) -> Int { + 1 + } + + override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { + 11 + } + + override func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.row == 10 { + let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil) + cell.textLabel?.text = "Description" + cell.detailTextLabel?.text = comic.description + cell.detailTextLabel?.numberOfLines = 0 + return cell + } + let cell = UITableViewCell(style: .value1, reuseIdentifier: nil) + switch indexPath.row { + case 0: cell.textLabel?.text = "Title"; cell.detailTextLabel?.text = comic.title + case 1: cell.textLabel?.text = "Format"; cell.detailTextLabel?.text = "\(comic.format)" + case 2: cell.textLabel?.text = "Original Language"; cell.detailTextLabel?.text = comic.originalLanguage + case 3: cell.textLabel?.text = "Publication Demographic" + cell.detailTextLabel?.text = "\(comic.publicationDemographic)" + case 4: cell.textLabel?.text = "Country of Origin"; cell.detailTextLabel?.text = comic.countryOfOrigin + case 5: cell.textLabel?.text = "Status"; cell.detailTextLabel?.text = "\(comic.status)" + case 6: cell.textLabel?.text = "Content Rating"; cell.detailTextLabel?.text = "\(comic.contentRating)" + case 7: cell.textLabel?.text = "First Release" + cell.detailTextLabel?.text = "\(dateToString(comic.startReleaseDate))" + case 8: cell.textLabel?.text = "Last Release" + cell.detailTextLabel?.text = "\(dateToString(comic.endReleaseDate))" + case 9: cell.textLabel?.text = "Tags" + cell.detailTextLabel?.text = comic.tags.map { $0.value ?? "" }.joined(separator: ", ") + default: break + } + + return cell + } +} + +private func dateToString(_ date: Date?) -> String { + if let date = date { + return "\(date.day). \(monthIntToString(date.month)) \(date.year)" + } + return "" +} + +private func monthIntToString(_ month: UInt8) -> String { + switch month { + case 1: return "January" + case 2: return "February" + case 3: return "March" + case 4: return "April" + case 5: return "May" + case 6: return "June" + case 7: return "July" + case 8: return "August" + case 9: return "September" + case 10: return "October" + case 11: return "November" + case 12: return "December" + default: return "" + } +} diff --git a/ImageViewer/metadata_generated.swift b/ImageViewer/metadata_generated.swift index 74b18c3..cf529b3 100644 --- a/ImageViewer/metadata_generated.swift +++ b/ImageViewer/metadata_generated.swift @@ -543,3 +543,4 @@ public struct Metadata: FlatBufferTable, FlatbuffersVectorInitializable, Verifia } } +// swiftlint:enable all -- 2.54.0