-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20369 from kean/feature/personalize-home-tab-screen
Hiding dashboard cards: add Personalize Home Tab screen
- Loading branch information
Showing
11 changed files
with
304 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
...ress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/BlogDashboardPersonalizeCardCell.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import UIKit | ||
import SwiftUI | ||
|
||
final class BlogDashboardPersonalizeCardCell: DashboardCollectionViewCell { | ||
private var blog: Blog? | ||
private weak var presentingViewController: BlogDashboardViewController? | ||
|
||
private let personalizeButton = UIButton(type: .system) | ||
|
||
// MARK: - Initializers | ||
|
||
override init(frame: CGRect) { | ||
super.init(frame: frame) | ||
setupView() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
// MARK: - View setup | ||
|
||
private func setupView() { | ||
let titleLabel = UILabel() | ||
titleLabel.text = Strings.buttonTitle | ||
titleLabel.font = WPStyleGuide.fontForTextStyle(.subheadline, fontWeight: .semibold) | ||
titleLabel.adjustsFontForContentSizeCategory = true | ||
|
||
let imageView = UIImageView(image: UIImage(named: "personalize")?.withRenderingMode(.alwaysTemplate)) | ||
imageView.tintColor = .label | ||
|
||
let spacer = UIView() | ||
spacer.translatesAutoresizingMaskIntoConstraints = false | ||
spacer.widthAnchor.constraint(greaterThanOrEqualToConstant: 8).isActive = true | ||
|
||
let contents = UIStackView(arrangedSubviews: [titleLabel, spacer, imageView]) | ||
contents.alignment = .center | ||
contents.isUserInteractionEnabled = false | ||
|
||
personalizeButton.accessibilityLabel = Strings.buttonTitle | ||
personalizeButton.setBackgroundImage(.renderBackgroundImage(fill: .tertiarySystemFill), for: .normal) | ||
personalizeButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) | ||
|
||
let container = UIView() | ||
container.layer.cornerRadius = 10 | ||
container.addSubview(personalizeButton) | ||
container.addSubview(contents) | ||
|
||
personalizeButton.translatesAutoresizingMaskIntoConstraints = false | ||
container.pinSubviewToAllEdges(personalizeButton) | ||
|
||
contents.translatesAutoresizingMaskIntoConstraints = false | ||
container.pinSubviewToAllEdges(contents, insets: .init(allEdges: 16)) | ||
|
||
contentView.addSubview(container) | ||
container.translatesAutoresizingMaskIntoConstraints = false | ||
contentView.pinSubviewToAllEdges(container) | ||
} | ||
|
||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { | ||
super.traitCollectionDidChange(previousTraitCollection) | ||
|
||
personalizeButton.setBackgroundImage(.renderBackgroundImage(fill: .tertiarySystemFill), for: .normal) | ||
} | ||
|
||
// MARK: - BlogDashboardCardConfigurable | ||
|
||
func configure(blog: Blog, viewController: BlogDashboardViewController?, apiResponse: BlogDashboardRemoteEntity?) { | ||
self.blog = blog | ||
self.presentingViewController = viewController | ||
} | ||
|
||
// MARK: - Actions | ||
|
||
@objc private func buttonTapped() { | ||
guard let blog = blog, let siteID = blog.dotComID?.intValue else { | ||
return DDLogError("Failed to show dashboard personalization screen: siteID is missing") | ||
} | ||
WPAnalytics.track(.dashboardCardItemTapped, properties: ["type": DashboardCard.personalize.rawValue], blog: blog) | ||
let viewController = UIHostingController(rootView: NavigationView { | ||
BlogDashboardPersonalizationView(viewModel: .init(service: .init(siteID: siteID))) | ||
}.navigationViewStyle(.stack)) // .stack is required for iPad | ||
if UIDevice.isPad() { | ||
viewController.modalPresentationStyle = .formSheet | ||
} | ||
presentingViewController?.present(viewController, animated: true) | ||
} | ||
} | ||
|
||
private extension BlogDashboardPersonalizeCardCell { | ||
struct Strings { | ||
static let buttonTitle = NSLocalizedString("dasboard.personalizeHomeButtonTitle", value: "Personalize your home tab", comment: "Personialize home tab button title") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
...Press/Classes/ViewRelated/Blog/BlogPersonalization/BlogDashboardPersonalizationView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import SwiftUI | ||
|
||
struct BlogDashboardPersonalizationView: View { | ||
@StateObject var viewModel: BlogDashboardPersonalizationViewModel | ||
|
||
@SwiftUI.Environment(\.presentationMode) var presentationMode | ||
|
||
var body: some View { | ||
List { | ||
Section(content: { | ||
ForEach(viewModel.cards, content: BlogDashboardPersonalizationCardCell.init) | ||
}, header: { | ||
Text(Strings.sectionHeader) | ||
}, footer: { | ||
Text(Strings.sectionFooter) | ||
}) | ||
} | ||
.listStyle(.insetGrouped) | ||
.navigationTitle(Strings.title) | ||
.navigationBarTitleDisplayMode(.inline) | ||
.toolbar { | ||
ToolbarItem(placement: .navigationBarLeading) { closeButton } | ||
} | ||
} | ||
|
||
private var closeButton: some View { | ||
Button(action: { presentationMode.wrappedValue.dismiss() }) { | ||
Image(systemName: "xmark") | ||
.font(.body.weight(.medium)) | ||
.foregroundColor(Color.primary) | ||
} | ||
} | ||
} | ||
|
||
private struct BlogDashboardPersonalizationCardCell: View { | ||
@ObservedObject var viewModel: BlogDashboardPersonalizationCardCellViewModel | ||
|
||
var body: some View { | ||
Toggle(viewModel.title, isOn: $viewModel.isOn) | ||
} | ||
} | ||
|
||
private extension BlogDashboardPersonalizationView { | ||
struct Strings { | ||
static let title = NSLocalizedString("personalizeHome.title", value: "Personalize Home Tab", comment: "Page title") | ||
static let sectionHeader = NSLocalizedString("personalizeHome.cardsSectionHeader", value: "Add or hide cards", comment: "Section header") | ||
static let sectionFooter = NSLocalizedString("personalizeHome.cardsSectionFooter", value: "Cards may show different content depending on what's happening on your site. We're working on more cards and controls.", comment: "Section footer displayed below the list of toggles") | ||
} | ||
} | ||
|
||
#if DEBUG | ||
struct BlogDashboardPersonalizationView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
NavigationView { | ||
BlogDashboardPersonalizationView(viewModel: .init(service: .init(repository: UserDefaults.standard, siteID: 1))) | ||
} | ||
} | ||
} | ||
#endif |
52 changes: 52 additions & 0 deletions
52
.../Classes/ViewRelated/Blog/BlogPersonalization/BlogDashboardPersonalizationViewModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import SwiftUI | ||
|
||
final class BlogDashboardPersonalizationViewModel: ObservableObject { | ||
let cards: [BlogDashboardPersonalizationCardCellViewModel] | ||
|
||
init(service: BlogDashboardPersonalizationService) { | ||
self.cards = DashboardCard.personalizableCards.map { | ||
BlogDashboardPersonalizationCardCellViewModel(card: $0, service: service) | ||
} | ||
} | ||
} | ||
|
||
final class BlogDashboardPersonalizationCardCellViewModel: ObservableObject, Identifiable { | ||
private let card: DashboardCard | ||
private let service: BlogDashboardPersonalizationService | ||
|
||
var id: DashboardCard { card } | ||
var title: String { card.localizedTitle } | ||
|
||
var isOn: Bool { | ||
get { service.isEnabled(card) } | ||
set { | ||
objectWillChange.send() | ||
service.setEnabled(newValue, for: card) | ||
} | ||
} | ||
|
||
init(card: DashboardCard, service: BlogDashboardPersonalizationService) { | ||
self.card = card | ||
self.service = service | ||
} | ||
} | ||
|
||
private extension DashboardCard { | ||
var localizedTitle: String { | ||
switch self { | ||
case .prompts: | ||
return NSLocalizedString("personalizeHome.dashboardCard.prompts", value: "Blogging prompts", comment: "Card title for the pesonalization menu") | ||
case .blaze: | ||
return NSLocalizedString("personalizeHome.dashboardCard.blaze", value: "Blaze", comment: "Card title for the pesonalization menu") | ||
case .todaysStats: | ||
return NSLocalizedString("personalizeHome.dashboardCard.todaysStats", value: "Today's stats", comment: "Card title for the pesonalization menu") | ||
case .draftPosts: | ||
return NSLocalizedString("personalizeHome.dashboardCard.draftPosts", value: "Draft posts", comment: "Card title for the pesonalization menu") | ||
case .scheduledPosts: | ||
return NSLocalizedString("personalizeHome.dashboardCard.scheduledPosts", value: "Scheduled posts", comment: "Card title for the pesonalization menu") | ||
case .quickStart, .nextPost, .createPost, .ghost, .failure, .personalize, .jetpackBadge, .jetpackInstall, .domainsDashboardCard: | ||
assertionFailure("\(self) card should not appear in the personalization menus") | ||
return "" // These cards don't appear in the personalization menus | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
WordPress/Resources/AppImages.xcassets/personalize.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"filename" : "personalize.pdf", | ||
"idiom" : "universal" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
Binary file added
BIN
+1.51 KB
WordPress/Resources/AppImages.xcassets/personalize.imageset/personalize.pdf
Binary file not shown.
Oops, something went wrong.