From b25202bd3b5f8125f6377ad7ac9dcf5bd3c6c071 Mon Sep 17 00:00:00 2001 From: Alex Grebenyuk Date: Fri, 13 Dec 2024 09:06:23 -0500 Subject: [PATCH] Add media URLs and entity IDs (#23887) * Add URL to Media metadata * Add Media IDs * Add post IDs * Update release notes --- RELEASE-NOTES.txt | 1 + .../Utility/ImmuTable/WPImmuTableRows.swift | 14 +++++++++ .../ViewRelated/Cells/TextViewTableCell.swift | 27 +++++++++++++++++ .../Media/MediaItemViewController.swift | 12 +++++++- .../PostSettingsViewController+Swift.swift | 11 +++++-- .../Post/PostSettingsViewController.m | 8 ++++- .../Shared/UITableView+Header.swift | 2 +- .../Views/EntityMetadataTableFooterView.swift | 30 +++++++++++++++++++ 8 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 WordPress/Classes/ViewRelated/Cells/TextViewTableCell.swift create mode 100644 WordPress/Classes/ViewRelated/Views/EntityMetadataTableFooterView.swift diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index c9f362272838..f1266dce466f 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -7,6 +7,7 @@ * [*] [internal] Update Gravatar SDK to 3.0.0 [#23701] * [*] Use the Gravatar Quick Editor to update the avatar [#23729] * [*] (Hidden under a feature flag) User Management for self-hosted sites. [#23768] +* [*] Add URL and ID to the Media details screen, add IDs for posts [#23887] * [*] Enable quick access to notifications from Reader on iPad [#23882] * [*] Add support for restricted posts in Reader [#23853] * [*] Fix minor appearance issues in the Blaze campaign list [#23891] diff --git a/WordPress/Classes/Utility/ImmuTable/WPImmuTableRows.swift b/WordPress/Classes/Utility/ImmuTable/WPImmuTableRows.swift index 592cfa80f896..b31d6636a968 100644 --- a/WordPress/Classes/Utility/ImmuTable/WPImmuTableRows.swift +++ b/WordPress/Classes/Utility/ImmuTable/WPImmuTableRows.swift @@ -468,3 +468,17 @@ class ExpandableRow: ImmuTableRow { cell.urlCallback = onLinkTap } } + +struct TextViewRow: ImmuTableRow { + static var cell = ImmuTableCell.class(TextViewTableCell.self) + + let title: String + let details: String + var action: ImmuTableAction? + + func configureCell(_ cell: UITableViewCell) { + let cell = cell as! TextViewTableCell + cell.titleLabel.text = title + cell.detailsView.text = details + } +} diff --git a/WordPress/Classes/ViewRelated/Cells/TextViewTableCell.swift b/WordPress/Classes/ViewRelated/Cells/TextViewTableCell.swift new file mode 100644 index 000000000000..7de4c0350093 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Cells/TextViewTableCell.swift @@ -0,0 +1,27 @@ +import UIKit +import WordPressUI + +final class TextViewTableCell: UITableViewCell { + let titleLabel = UILabel() + let detailsView = UITextView.makeLabel() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + detailsView.textContainer.maximumNumberOfLines = 1 + detailsView.textContainer.lineBreakMode = .byTruncatingMiddle + detailsView.textColor = .secondaryLabel + detailsView.font = .preferredFont(forTextStyle: .body) + detailsView.dataDetectorTypes = .link + + titleLabel.setContentCompressionResistancePriority(.init(900), for: .horizontal) + + let stackView = UIStackView(alignment: .firstBaseline, spacing: 3, [titleLabel, UIView(), detailsView]) + contentView.addSubview(stackView) + stackView.pinEdges(to: contentView.layoutMarginsGuide) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift index d07bdcf14a19..2d1e29ddb088 100644 --- a/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/MediaItemViewController.swift @@ -40,11 +40,15 @@ final class MediaItemViewController: UITableViewController { tableView.showsVerticalScrollIndicator = false tableView.cellLayoutMarginsFollowReadableWidth = true - ImmuTable.registerRows([TextRow.self, EditableTextRow.self], tableView: tableView) + ImmuTable.registerRows([TextRow.self, EditableTextRow.self, TextViewRow.self], tableView: tableView) updateViewModel() updateNavigationItem() updateTitle() + + if let mediaID = media.mediaID, mediaID.intValue > 0 { + tableView.tableFooterView = EntityMetadataTableFooterView.make(id: mediaID) + } } private func updateTitle() { @@ -90,12 +94,14 @@ final class MediaItemViewController: UITableViewController { // constraint doesn't seem to go into effect until after `viewDidLayoutSubviews`. headerMaxHeightConstraint.constant = view.bounds.height * 0.75 tableView.sizeToFitHeaderView() + tableView.sizeToFitFooterView() } private var metadataRows: [ImmuTableRow] { let presenter = MediaMetadataPresenter(media: media) var rows = [ImmuTableRow]() + rows.append(TextViewRow(title: Strings.url, details: media.remoteURL ?? "")) rows.append(TextRow(title: NSLocalizedString("File name", comment: "Label for the file name for a media asset (image / video)"), value: media.filename ?? "")) rows.append(TextRow(title: NSLocalizedString("File type", comment: "Label for the file type (.JPG, .PNG, etc) for a media asset (image / video)"), value: presenter.fileType ?? "")) @@ -461,3 +467,7 @@ private struct MediaMetadata { media.alt = alt } } + +private enum Strings { + static let url = NSLocalizedString("siteMedia.details.url", value: "URL", comment: "Title for the URL field") +} diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift index 1afd45196cd2..b781321cfb0f 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift +++ b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift @@ -28,9 +28,16 @@ extension PostSettingsViewController { apost.original().isStatus(in: [.draft, .pending]) } - @objc func setupStandaloneEditor() { - guard isStandalone else { return } + @objc func onViewDidLoad() { + if isStandalone { + setupStandaloneEditor() + } + if let postID = apost.postID, postID.intValue > 0 { + tableView.tableFooterView = EntityMetadataTableFooterView.make(id: postID) + } + } + private func setupStandaloneEditor() { wpAssert(navigationController?.presentationController != nil) navigationController?.presentationController?.delegate = self diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m index 060461825b54..24aeecebf6af 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m +++ b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m @@ -147,7 +147,7 @@ - (void)viewDidLoad // reachability callbacks to trigger before such initial setup completes. // [self setupReachability]; - [self setupStandaloneEditor]; + [self onViewDidLoad]; } - (void)viewWillAppear:(BOOL)animated @@ -162,6 +162,12 @@ - (void)viewWillAppear:(BOOL)animated [self reloadData]; } +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + + [self.tableView sizeToFitFooterView]; +} + - (void)didReceiveMemoryWarning { DDLogWarn(@"%@ %@", self, NSStringFromSelector(_cmd)); diff --git a/WordPress/Classes/ViewRelated/Site Creation/Shared/UITableView+Header.swift b/WordPress/Classes/ViewRelated/Site Creation/Shared/UITableView+Header.swift index 716db7dca6e5..74f5d135bb7a 100644 --- a/WordPress/Classes/ViewRelated/Site Creation/Shared/UITableView+Header.swift +++ b/WordPress/Classes/ViewRelated/Site Creation/Shared/UITableView+Header.swift @@ -58,7 +58,7 @@ extension UITableView { /// /// Source: https://gist.github.com/smileyborg/50de5da1c921b73bbccf7f76b3694f6a /// - func sizeToFitFooterView() { + @objc func sizeToFitFooterView() { guard let tableFooterView else { return } diff --git a/WordPress/Classes/ViewRelated/Views/EntityMetadataTableFooterView.swift b/WordPress/Classes/ViewRelated/Views/EntityMetadataTableFooterView.swift new file mode 100644 index 000000000000..eb882108b25b --- /dev/null +++ b/WordPress/Classes/ViewRelated/Views/EntityMetadataTableFooterView.swift @@ -0,0 +1,30 @@ +import UIKit + +final class EntityMetadataTableFooterView: UIView { + let textLabel = UILabel() + + override init(frame: CGRect) { + super.init(frame: frame) + + textLabel.textColor = .tertiaryLabel + textLabel.font = .preferredFont(forTextStyle: .footnote) + textLabel.textAlignment = .center + + addSubview(textLabel) + textLabel.pinEdges(insets: UIEdgeInsets(.all, 8)) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + static func make(id: NSNumber) -> UIView { + let footerView = EntityMetadataTableFooterView() + footerView.textLabel.text = "\(Strings.id) \(id)" + return footerView + } +} + +private enum Strings { + static let id = NSLocalizedString("entityMetadataFooterView.id", value: "ID", comment: "A name of the ID field (it's a technical field, has to be short, displayed below everything else)") +}