Skip to content

Commit 7e6c816

Browse files
authored
Product Details: Display cover tag on the first product image (#15041)
2 parents a5f402a + 7439764 commit 7e6c816

File tree

5 files changed

+65
-13
lines changed

5 files changed

+65
-13
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*** Use [*****] to indicate smoke tests of all critical flows should be run on the final IPA before release (e.g. major library or OS update).
33
21.7
44
-----
5+
- [*] Product Details: Display cover tag on the first product image [https://github.com/woocommerce/woocommerce-ios/pull/15041]
56
- [*] Payments: Update learn more links to open Stripe-specific docs when using that gateway [https://github.com/woocommerce/woocommerce-ios/pull/15035]
67
- [x] Now, usernames and emails in text fields across multiple login views are no longer capitalized. [https://github.com/woocommerce/woocommerce-ios/pull/15002]
78

WooCommerce/Classes/ViewRelated/Products/Cells/Product Images/Collection View Cells/ProductImageCollectionViewCell.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,33 @@ final class ProductImageCollectionViewCell: UICollectionViewCell {
77

88
var cancellableTask: Task<Void, Never>?
99

10+
private(set) lazy var coverTagView: UIView = {
11+
let containerView = UIView(frame: .zero)
12+
containerView.backgroundColor = UIColor.primary
13+
containerView.clipsToBounds = true
14+
containerView.isHidden = true
15+
containerView.layer.cornerRadius = Constants.tagCornerRadius
16+
containerView.translatesAutoresizingMaskIntoConstraints = false
17+
containerView.addSubview(tagLabel)
18+
containerView.pinSubviewToAllEdges(tagLabel, insets: Constants.tagEdgeInsets)
19+
return containerView
20+
}()
21+
22+
private lazy var tagLabel: UILabel = {
23+
let label = UILabel(frame: .zero)
24+
label.translatesAutoresizingMaskIntoConstraints = false
25+
label.applyCaption1Style()
26+
label.textColor = UIColor(light: .white, dark: .black)
27+
label.text = Localization.tagLabel
28+
return label
29+
}()
30+
1031
override func awakeFromNib() {
1132
super.awakeFromNib()
1233
configureBackground()
1334
configureImageView()
1435
configureCellAppearance()
36+
configureCoverTagView()
1537
}
1638

1739
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
@@ -46,6 +68,14 @@ private extension ProductImageCollectionViewCell {
4668
contentView.layer.borderColor = Colors.borderColor.cgColor
4769
contentView.layer.masksToBounds = Settings.maskToBounds
4870
}
71+
72+
func configureCoverTagView() {
73+
contentView.addSubview(coverTagView)
74+
NSLayoutConstraint.activate([
75+
contentView.leadingAnchor.constraint(equalTo: coverTagView.leadingAnchor, constant: -Constants.tagPadding),
76+
contentView.topAnchor.constraint(equalTo: coverTagView.topAnchor, constant: -Constants.tagPadding),
77+
])
78+
}
4979
}
5080

5181
/// Constants
@@ -54,6 +84,9 @@ private extension ProductImageCollectionViewCell {
5484
enum Constants {
5585
static let cornerRadius = CGFloat(2.0)
5686
static let borderWidth = CGFloat(0.5)
87+
static let tagPadding = CGFloat(8)
88+
static let tagCornerRadius = CGFloat(4)
89+
static let tagEdgeInsets = UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4)
5790
}
5891

5992
enum Colors {
@@ -65,4 +98,12 @@ private extension ProductImageCollectionViewCell {
6598
static let imageContentMode = ContentMode.center
6699
static let maskToBounds = true
67100
}
101+
102+
enum Localization {
103+
static let tagLabel = NSLocalizedString(
104+
"productImageCollectionViewCell.tagLabel.text",
105+
value: "Cover",
106+
comment: "Label indicating the cover image of a product"
107+
)
108+
}
68109
}

WooCommerce/Classes/ViewRelated/Products/Cells/Product Images/ProductImagesCollectionViewDataSource.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ private extension ProductImagesCollectionViewDataSource {
3838
func configure(collectionView: UICollectionView, _ cell: UICollectionViewCell, for item: ProductImagesItem, at indexPath: IndexPath) {
3939
switch item {
4040
case .image(let status):
41-
configureImageCell(cell, productImageStatus: status)
41+
let isFirstImage = indexPath.item == 0
42+
configureImageCell(cell, productImageStatus: status, isFirstImage: isFirstImage)
4243
case .extendedAddImage(let isVariation):
4344
if let cell = cell as? ExtendedAddProductImageCollectionViewCell {
4445
cell.configurePlaceholderLabelForProductImages(isVariation: isVariation)
@@ -48,10 +49,10 @@ private extension ProductImagesCollectionViewDataSource {
4849
}
4950
}
5051

51-
func configureImageCell(_ cell: UICollectionViewCell, productImageStatus: ProductImageStatus) {
52+
func configureImageCell(_ cell: UICollectionViewCell, productImageStatus: ProductImageStatus, isFirstImage: Bool) {
5253
switch productImageStatus {
5354
case .remote(let image):
54-
configureRemoteImageCell(cell, productImage: image)
55+
configureRemoteImageCell(cell, productImage: image, isFirstImage: isFirstImage)
5556
case .uploading(let asset):
5657
switch asset {
5758
case .phAsset(let asset):
@@ -62,7 +63,7 @@ private extension ProductImagesCollectionViewDataSource {
6263
}
6364
}
6465

65-
func configureRemoteImageCell(_ cell: UICollectionViewCell, productImage: ProductImage) {
66+
func configureRemoteImageCell(_ cell: UICollectionViewCell, productImage: ProductImage, isFirstImage: Bool) {
6667
guard let cell = cell as? ProductImageCollectionViewCell else {
6768
fatalError()
6869
}
@@ -83,6 +84,7 @@ private extension ProductImagesCollectionViewDataSource {
8384
cell?.imageView.contentMode = .scaleAspectFit
8485
cell?.imageView.image = image
8586
}
87+
cell.coverTagView.isHidden = !isFirstImage
8688
}
8789

8890
func configureUploadingImageCell(_ cell: UICollectionViewCell, asset: PHAsset) {

WooCommerce/Classes/ViewRelated/Products/Media/ProductImagesCollectionViewController.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,19 @@ extension ProductImagesCollectionViewController {
7272
let productImageStatus = productImageStatuses[indexPath.row]
7373
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: productImageStatus.cellReuseIdentifier,
7474
for: indexPath)
75-
configureCell(cell, productImageStatus: productImageStatus)
75+
let isFirstImage = indexPath.row == 0
76+
configureCell(cell, productImageStatus: productImageStatus, isFirstImage: isFirstImage)
7677
return cell
7778
}
7879
}
7980

8081
// MARK: Cell configurations
8182
//
8283
private extension ProductImagesCollectionViewController {
83-
func configureCell(_ cell: UICollectionViewCell, productImageStatus: ProductImageStatus) {
84+
func configureCell(_ cell: UICollectionViewCell, productImageStatus: ProductImageStatus, isFirstImage: Bool) {
8485
switch productImageStatus {
8586
case .remote(let image):
86-
configureRemoteImageCell(cell, productImage: image)
87+
configureRemoteImageCell(cell, productImage: image, isFirstImage: isFirstImage)
8788
case .uploading(let asset):
8889
switch asset {
8990
case .phAsset(let asset):
@@ -94,7 +95,7 @@ private extension ProductImagesCollectionViewController {
9495
}
9596
}
9697

97-
func configureRemoteImageCell(_ cell: UICollectionViewCell, productImage: ProductImage) {
98+
func configureRemoteImageCell(_ cell: UICollectionViewCell, productImage: ProductImage, isFirstImage: Bool) {
9899
guard let cell = cell as? ProductImageCollectionViewCell else {
99100
fatalError()
100101
}
@@ -116,6 +117,7 @@ private extension ProductImagesCollectionViewController {
116117
cell.imageView.contentMode = .scaleAspectFit
117118
cell.imageView.image = image
118119
}
120+
cell.coverTagView.isHidden = !isFirstImage
119121
}
120122

121123
func configureUploadingImageCell(_ cell: UICollectionViewCell, asset: PHAsset) {
@@ -254,7 +256,9 @@ extension ProductImagesCollectionViewController: UICollectionViewDragDelegate, U
254256
}, completion: { [weak self] _ in
255257
// [Workaround] Reload the collection view if there are more than
256258
// one type of cells, for example, when there are any pending upload.
257-
self?.reloadCollectionViewIfNeeded()
259+
// Reloading is also necessary when the first image is updated.
260+
let firstImageUpdated = item.sourceIndexPath?.item == 0 || destinationIndexPath.item == 0
261+
self?.reloadCollectionViewIfNeeded(firstImageUpdated: firstImageUpdated)
258262
})
259263

260264
coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)
@@ -264,9 +268,10 @@ extension ProductImagesCollectionViewController: UICollectionViewDragDelegate, U
264268
/// Reloads collection view only if there is any pending upload.
265269
/// This makes sure that cells for pending uploads are reloaded properly
266270
/// to remove their overlays after uploading is done.
271+
/// If the first image is updated, reloading is also necessary to update the Cover tag.
267272
///
268-
private func reloadCollectionViewIfNeeded() {
269-
if productImageStatuses.hasPendingUpload {
273+
private func reloadCollectionViewIfNeeded(firstImageUpdated: Bool) {
274+
if firstImageUpdated || productImageStatuses.hasPendingUpload {
270275
collectionView.reloadData()
271276
}
272277
}

WooCommerce/Classes/ViewRelated/Products/Media/ProductImagesViewController.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,10 @@ private extension ProductImagesViewController {
371371
static let replacePhoto = NSLocalizedString("Replace Photo", comment: "Action to replace one photo on the Product images screen")
372372
static let variableProductHelperText = NSLocalizedString("Only one photo can be displayed by variation",
373373
comment: "Helper text above photo list in Product images screen")
374-
static let dragAndDropHelperText = NSLocalizedString("Drag and drop to re-order photos",
375-
comment: "Drag and drop helper text above photo list in Product images screen")
374+
static let dragAndDropHelperText = NSLocalizedString(
375+
"productImagesViewController.dragAndDropHelperText",
376+
value: "Drag and drop to re-order photos. The first photo will be set as the cover.",
377+
comment: "Drag and drop helper text above photo list in Product images screen"
378+
)
376379
}
377380
}

0 commit comments

Comments
 (0)