-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reader: Add announcement card #23197
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
34e5ad7
Simplify stream header configuration logic
dvdchr e9cddfd
Tweak ReaderTagStreamHeader's constraint priorities to avoid conflict
dvdchr f978026
Minor refactor to prep for the announcement header insertion
dvdchr d03b4ad
Implement announcement card UI
dvdchr 133a742
Localize strings, refactor view generation
dvdchr daa8358
Hook Done button implementation and animate dismissal
dvdchr 45d58e4
Tweak announcement card display logic for the Discover stream
dvdchr 437b4f0
Add remote feature flag and convenience object for checking feature s…
dvdchr 660f3f2
Implement dismiss flag functionality
dvdchr 55102ff
Update announcement card background color
dvdchr 0b55919
Don't show announcement card when content is filtered
dvdchr e2a312a
Add ReaderAnnouncementHeaderView to WordPress target
dvdchr be6ec3d
Remove image from a11y hierarchy
dvdchr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
190 changes: 190 additions & 0 deletions
190
WordPress/Classes/ViewRelated/Reader/ReaderAnnouncementHeaderView.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,190 @@ | ||
import SwiftUI | ||
import DesignSystem | ||
|
||
class ReaderAnnouncementHeaderView: UITableViewHeaderFooterView, ReaderStreamHeader { | ||
|
||
weak var delegate: ReaderStreamHeaderDelegate? | ||
|
||
private let header: ReaderAnnouncementHeader | ||
|
||
init(doneButtonTapped: (() -> Void)? = nil) { | ||
self.header = ReaderAnnouncementHeader { [doneButtonTapped] in | ||
doneButtonTapped?() | ||
} | ||
|
||
super.init(reuseIdentifier: ReaderSiteHeaderView.classNameWithoutNamespaces()) | ||
setupViews() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
private func setupViews() { | ||
let view = UIView.embedSwiftUIView(self.header) | ||
addSubview(view) | ||
NSLayoutConstraint.activate([ | ||
view.topAnchor.constraint(equalTo: topAnchor), | ||
view.bottomAnchor.constraint(equalTo: bottomAnchor), | ||
view.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), | ||
view.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor) | ||
]) | ||
|
||
applyBackgroundColor(Constants.backgroundColor) | ||
addBottomBorder(withColor: .separator) | ||
} | ||
|
||
private func applyBackgroundColor(_ color: UIColor) { | ||
let backgroundView = UIView(frame: bounds) | ||
backgroundView.backgroundColor = color | ||
self.backgroundView = backgroundView | ||
} | ||
|
||
// MARK: ReaderStreamHeader | ||
|
||
func enableLoggedInFeatures(_ enable: Bool) { | ||
// no-op | ||
} | ||
|
||
func configureHeader(_ topic: ReaderAbstractTopic) { | ||
// no-op; this header doesn't rely on the supplied topic. | ||
} | ||
|
||
fileprivate struct Constants { | ||
static let backgroundColor = UIColor.systemBackground | ||
} | ||
} | ||
|
||
// TODO: ReaderAnnouncementItem / Models | ||
|
||
// MARK: - SwiftUI View | ||
|
||
fileprivate struct ReaderAnnouncementHeader: View { | ||
|
||
// Determines what features should be listed (and its order). | ||
let entries: [Entry] = [.tagsStream, .readingPreferences] | ||
|
||
var onButtonTap: (() -> Void)? = nil | ||
|
||
var body: some View { | ||
VStack(alignment: .leading, spacing: .DS.Padding.double) { | ||
Text(Strings.title) | ||
.font(.callout) | ||
.fontWeight(.semibold) | ||
|
||
ForEach(entries, id: \.title) { entry in | ||
announcementEntryView(entry) | ||
} | ||
|
||
DSButton(title: Strings.buttonTitle, | ||
style: DSButtonStyle(emphasis: .primary, size: .large)) { | ||
onButtonTap?() | ||
} | ||
} | ||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) | ||
.padding(.vertical, .DS.Padding.medium) | ||
.background(Color(ReaderAnnouncementHeaderView.Constants.backgroundColor)) | ||
} | ||
|
||
// MARK: Constants | ||
|
||
private struct Strings { | ||
static let title = NSLocalizedString( | ||
"reader.announcement.title", | ||
value: "New in Reader", | ||
comment: "Title text for the announcement card component in the Reader." | ||
) | ||
static let buttonTitle = NSLocalizedString( | ||
"reader.announcement.button", | ||
value: "Done", | ||
comment: "Text for a button that dismisses the announcement card in the Reader." | ||
) | ||
} | ||
} | ||
|
||
// MARK: - Announcement Item | ||
|
||
fileprivate extension ReaderAnnouncementHeader { | ||
|
||
struct Entry { | ||
static let tagsStream = Entry( | ||
imageName: "reader-menu-tags", | ||
title: NSLocalizedString( | ||
"reader.announcement.entry.tagsStream.title", | ||
value: "Tags Stream", | ||
comment: "The title part of the feature announcement content for Tags Stream." | ||
), | ||
description: NSLocalizedString( | ||
"reader.announcement.entry.tagsStream.description", | ||
value: "Tap the dropdown at the top and select Tags to access streams from your followed tags.", | ||
comment: "The description part of the feature announcement content for Tags Stream." | ||
) | ||
) | ||
|
||
static let readingPreferences = Entry( | ||
imageName: "reader-reading-preferences", | ||
title: NSLocalizedString( | ||
"reader.announcement.entry.readingPreferences.title", | ||
value: "Reading Preferences", | ||
comment: "The title part of the feature announcement content for Reading Preferences." | ||
), | ||
description: NSLocalizedString( | ||
"reader.announcement.entry.readingPreferences.description", | ||
value: "Choose colors and fonts that suit you. When you’re reading a post tap the AA icon at the top of the screen.", | ||
comment: "The description part of the feature announcement content for Reading Preferences." | ||
) | ||
) | ||
|
||
let imageName: String | ||
let title: String | ||
let description: String | ||
} | ||
|
||
@ViewBuilder | ||
func announcementEntryView(_ entry: Entry) -> some View { | ||
HStack(spacing: .DS.Padding.double) { | ||
Image(entry.imageName, bundle: nil) | ||
.renderingMode(.template) | ||
.resizable() | ||
.frame(width: 24, height: 24) | ||
.padding(12) | ||
.foregroundColor(Color(.systemBackground)) | ||
.background(.primary) | ||
.clipShape(Circle()) | ||
.accessibilityHidden(true) | ||
|
||
VStack(alignment: .leading, spacing: 1) { | ||
Text(entry.title) | ||
.font(.callout) | ||
.fontWeight(.semibold) | ||
Text(entry.description) | ||
.font(.footnote) | ||
.foregroundStyle(.secondary) | ||
} | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Reader Announcement Coordinator | ||
|
||
class ReaderAnnouncementCoordinator { | ||
|
||
let repository: UserPersistentRepository = UserPersistentStoreFactory.instance() | ||
|
||
lazy var canShowAnnouncement: Bool = { | ||
return !isDismissed && RemoteFeatureFlag.readerAnnouncementCard.enabled() | ||
}() | ||
|
||
var isDismissed: Bool { | ||
get { | ||
repository.bool(forKey: Constants.key) | ||
} | ||
set { | ||
repository.set(newValue, forKey: Constants.key) | ||
} | ||
} | ||
|
||
private struct Constants { | ||
static let key = "readerAnnouncementCardDismissedKey" | ||
} | ||
} |
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this file needs to be added to the WordPress target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I've added it in e2a312a.