diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 74811df9978a..0c972659445f 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -24,6 +24,7 @@ * [*] Fix non-stable order in Posts and Pages section in Stats [#23915] * [*] (P2) Reader: Fix an issue with a missing "Mark as Read/Unread" button that was removed in the previous release [#23917] * [*] (P2) Reader: Show "read" status for P2 posts in the feeds [#23917] +* [*] Fix some missing or invalid social sharing icons [#23918] 25.6 ----- diff --git a/WordPress/Classes/Models/PublicizeService.swift b/WordPress/Classes/Models/PublicizeService.swift index e056aec957f6..d4842e0506a2 100644 --- a/WordPress/Classes/Models/PublicizeService.swift +++ b/WordPress/Classes/Models/PublicizeService.swift @@ -37,6 +37,7 @@ extension PublicizeService { case linkedin case instagram = "instagram-business" case mastodon + case threads case unknown /// Returns the local image for the icon representing the social network. diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServiceCell.swift b/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServiceCell.swift new file mode 100644 index 000000000000..ebeaa18c8c4b --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServiceCell.swift @@ -0,0 +1,90 @@ +import UIKit +import WordPressUI + +final class PublicizeServiceCell: UITableViewCell { + let iconView = AsyncImageView() + let titleLabel = UILabel() + let detailsLabel = UILabel() + + @objc class var cellId: String { "PublicizeServiceCell" } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + detailsLabel.font = .preferredFont(forTextStyle: .footnote) + detailsLabel.textColor = .secondaryLabel + + let stackView = UIStackView(alignment: .center, spacing: 12, [ + iconView, + UIStackView(axis: .vertical, alignment: .leading, spacing: 2, [titleLabel, detailsLabel]) + ]) + contentView.addSubview(stackView) + stackView.pinEdges(to: contentView.layoutMarginsGuide) + + NSLayoutConstraint.activate([ + iconView.widthAnchor.constraint(equalToConstant: 28), + iconView.heightAnchor.constraint(equalToConstant: 28), + ]) + iconView.layer.cornerRadius = 8 + iconView.layer.masksToBounds = true + iconView.backgroundColor = UIColor.white + + iconView.contentMode = .scaleAspectFit + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForReuse() { + super.prepareForReuse() + + accessoryView = .none + iconView.prepareForReuse() + } + + @objc func configure(with service: PublicizeService, connections: [PublicizeConnection]) { + let name = service.name + if name != .unknown && !name.hasModernRemoteLogo { + iconView.image = name.localIconImage + } else if let imageURL = URL(string: service.icon) { + iconView.setImage(with: imageURL) + } else { + iconView.image = UIImage(named: "social-default") + } + + titleLabel.text = service.label + + detailsLabel.isHidden = connections.isEmpty + if connections.count > 2 { + detailsLabel.text = String(format: Strings.numberOfAccounts, connections.count) + } else { + detailsLabel.text = connections + .map(\.externalDisplay) + .joined(separator: ", ") + } + + if service.isSupported { + if connections.contains(where: { $0.requiresUserAction() }) { + accessoryView = WPStyleGuide.sharingCellWarningAccessoryImageView() + } + } else { + accessoryView = WPStyleGuide.sharingCellErrorAccessoryImageView() + } + } +} + +private extension PublicizeService.ServiceName { + /// We no longer need to provide local overrides for these on this screen + /// as the remote images are good. + var hasModernRemoteLogo: Bool { + [ + PublicizeService.ServiceName.instagram, + PublicizeService.ServiceName.mastodon + ].contains(self) + } +} + +private enum Strings { + static let numberOfAccounts = NSLocalizedString("socialSharing.connectionDetails.nAccount", value: "%d accounts", comment: "The number of connected accounts on a third party sharing service connected to the user's blog. The '%d' is a placeholder for the number of accounts.") +} diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingViewController.m b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingViewController.m index 077c4846c677..0ddf6bc3eda4 100644 --- a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingViewController.m +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingViewController.m @@ -66,6 +66,7 @@ - (void)viewDidLoad action:@selector(doneButtonTapped)]; } + [self.tableView registerClass:[PublicizeServiceCell class] forCellReuseIdentifier:PublicizeServiceCell.cellId]; self.tableView.cellLayoutMarginsFollowReadableWidth = YES; [WPStyleGuide configureColorsForView:self.view andTableView:self.tableView]; [self.publicizeServicesState addInitialConnections:[self allConnections]]; @@ -237,32 +238,16 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - WPTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (!cell) { - cell = [[WPTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; - } - - [WPStyleGuide configureTableViewCell:cell]; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - SharingSectionType sectionType = [self sectionTypeForIndex:indexPath.section]; switch (sectionType) { case SharingSectionAvailableServices: // fallthrough case SharingSectionUnsupported: - [self configurePublicizeCell:cell atIndexPath:indexPath]; - break; - + return [self makePublicizeCellAtIndexPath:indexPath]; case SharingSectionSharingButtons: - cell.textLabel.text = NSLocalizedString(@"Manage", @"Verb. Text label. Tapping displays a screen where the user can configure 'share' buttons for third-party services."); - cell.detailTextLabel.text = nil; - cell.imageView.image = nil; - break; - + return [self makeManageButtonCell]; default: return [UITableViewCell new]; } - - return cell; } - (PublicizeService *)publicizeServiceForIndexPath:(NSIndexPath *)indexPath @@ -278,51 +263,38 @@ - (PublicizeService *)publicizeServiceForIndexPath:(NSIndexPath *)indexPath } } -- (void)configurePublicizeCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath +- (UITableViewCell *)makePublicizeCellAtIndexPath:(NSIndexPath *)indexPath { + PublicizeServiceCell *cell = [self.tableView dequeueReusableCellWithIdentifier:PublicizeServiceCell.cellId]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + PublicizeService *publicizer = [self publicizeServiceForIndexPath:indexPath]; NSArray *connections = [self connectionsForService:publicizer]; // TODO: Remove? if ([publicizer.serviceID isEqualToString:PublicizeService.googlePlusServiceID] && [connections count] == 0) { // Temporarily hiding Google+ cell.hidden = YES; - return; - } - - // Configure the image - UIImage *image = [WPStyleGuide socialIconFor:publicizer.serviceID]; - [cell.imageView setImage:image]; - - // Configure the text - cell.textLabel.text = publicizer.label; - - // Show the name(s) or number of connections. - NSString *str = @""; - if ([connections count] > 2) { - NSString *format = NSLocalizedString(@"%d accounts", @"The number of connected accounts on a third party sharing service connected to the user's blog. The '%d' is a placeholder for the number of accounts."); - str = [NSString stringWithFormat:format, [connections count]]; - } else { - NSMutableArray *names = [NSMutableArray array]; - for (PublicizeConnection *pubConn in connections) { - [names addObject:pubConn.externalDisplay]; - } - str = [names componentsJoinedByString:@", "]; + return cell; } - cell.detailTextLabel.text = str; + [cell configureWith:publicizer connections:connections]; + return cell; +} - if (![publicizer isSupported]) { - cell.accessoryView = [WPStyleGuide sharingCellErrorAccessoryImageView]; - return; +- (UITableViewCell *)makeManageButtonCell +{ + WPTableViewCell *cell = [self. + tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[WPTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; } - // Check if any of the connections are broken. - for (PublicizeConnection *pubConn in connections) { - if ([pubConn requiresUserAction]) { - cell.accessoryView = [WPStyleGuide sharingCellWarningAccessoryImageView]; - break; - } - } + [WPStyleGuide configureTableViewCell:cell]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.textLabel.text = NSLocalizedString(@"Manage", @"Verb. Text label. Tapping displays a screen where the user can configure 'share' buttons for third-party services."); + cell.detailTextLabel.text = nil; + cell.imageView.image = nil; + return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath diff --git a/WordPress/Classes/ViewRelated/Jetpack/Social/JetpackSocialNoConnectionView.swift b/WordPress/Classes/ViewRelated/Jetpack/Social/JetpackSocialNoConnectionView.swift index f1d7556e0c5a..a958a0469153 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Social/JetpackSocialNoConnectionView.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Social/JetpackSocialNoConnectionView.swift @@ -40,7 +40,7 @@ struct JetpackSocialNoConnectionView: View { } func iconImage(image: UIImage, url: URL?) -> some View { - AsyncImage(url: url) { image in + CachedAsyncImage(url: url) { image in image .icon(backgroundColor: viewModel.preferredBackgroundColor) } placeholder: { diff --git a/WordPress/Jetpack/AppImages.xcassets/Social/icon-threads.imageset/361591942_304761532104096_2740029438399114184_n-2.png b/WordPress/Jetpack/AppImages.xcassets/Social/icon-threads.imageset/361591942_304761532104096_2740029438399114184_n-2.png new file mode 100644 index 000000000000..e75640c24a02 Binary files /dev/null and b/WordPress/Jetpack/AppImages.xcassets/Social/icon-threads.imageset/361591942_304761532104096_2740029438399114184_n-2.png differ diff --git a/WordPress/Jetpack/AppImages.xcassets/Social/icon-threads.imageset/Contents.json b/WordPress/Jetpack/AppImages.xcassets/Social/icon-threads.imageset/Contents.json new file mode 100644 index 000000000000..efeea35ba64f --- /dev/null +++ b/WordPress/Jetpack/AppImages.xcassets/Social/icon-threads.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "361591942_304761532104096_2740029438399114184_n-2.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +}