Skip to content

Commit

Permalink
Support opening archived items in reader
Browse files Browse the repository at this point in the history
  • Loading branch information
David Skuza authored and dskuza committed Jan 28, 2022
1 parent d409bd3 commit 322c551
Show file tree
Hide file tree
Showing 28 changed files with 768 additions and 504 deletions.
1 change: 1 addition & 0 deletions PocketKit/Sources/Analytics/Context/UIContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ extension UIContext {
case itemFavorite = "item_favorite"
case itemUnfavorite = "item_unfavorite"
case itemShare = "item_share"
case itemSave = "item_save"
case slateDetail = "discover_topic"
case recommendation = "recommendation"
case reportItem = "report_item"
Expand Down
10 changes: 3 additions & 7 deletions PocketKit/Sources/PocketKit/Activity/PocketItemActivity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,9 @@ struct PocketItemActivity: PocketActivity {
}

let activityItems: [Any]

init(item: SavedItem, additionalText: String? = nil) {
self.activityItems = Self.activityItems(for: item.readerURL, additionalText: additionalText)
}

init(recommendation: Slate.Recommendation, additionalText: String? = nil) {
self.activityItems = Self.activityItems(for: recommendation.readerURL, additionalText: additionalText)

init(url: URL?, additionalText: String? = nil) {
self.activityItems = Self.activityItems(for: url, additionalText: additionalText)
}

private static func activityItems(for url: URL?, additionalText: String?) -> [Any] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import UIKit
/// Wrapping items in a `UIActivityItemSource` is a signal that tells
/// the system that we want some separation between the items being shared.
///
/// See usages in ArticleViewController for more info.
/// See usages in ReadableViewController for more info.
///
class ActivityItemSource: NSObject, UIActivityItemSource {
private let item: Any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ private extension Style {
}

struct ArticleMetadataPresenter {
private let readable: Readable
private let readableViewModel: ReadableViewModel
private let readerSettings: ReaderSettings

init(readable: Readable, readerSettings: ReaderSettings) {
self.readable = readable
init(readableViewModel: ReadableViewModel, readerSettings: ReaderSettings) {
self.readableViewModel = readableViewModel
self.readerSettings = readerSettings
}

var attributedTitle: NSAttributedString? {
guard let title = readable.title else {
guard let title = readableViewModel.title else {
return nil
}

Expand All @@ -57,15 +57,15 @@ struct ArticleMetadataPresenter {
let byline = NSMutableAttributedString()
let style = Style.byline(modifier: readerSettings)

if let authors = readable.authors, !authors.isEmpty {
if let authors = readableViewModel.authors, !authors.isEmpty {
let authorNames = authors.compactMap { $0.name }
let authorNamesString = ListFormatter.localizedString(byJoining: authorNames) as NSString
let attributedAuthorNames = NSMutableAttributedString(string: authorNamesString as String, style: style)

byline.append(attributedAuthorNames)
}

if let domain = readable.domain {
if let domain = readableViewModel.domain {
if !byline.string.isEmpty {
byline.append(NSAttributedString(string: "", style: style))
}
Expand All @@ -77,7 +77,7 @@ struct ArticleMetadataPresenter {
}

var attributedPublishedDate: NSAttributedString? {
readable.publishDate
readableViewModel.publishDate
.flatMap { $0.formatted(date: .long, time: .omitted) }
.flatMap { NSAttributedString(string: $0, style: .publishedDate(modifier: readerSettings)) }
}
Expand Down
36 changes: 0 additions & 36 deletions PocketKit/Sources/PocketKit/Article/Item+Readable.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import UIKit

class UnsupportedComponentPresenter: ArticleComponentPresenter {
private let mainViewModel: MainViewModel
private let readable: Readable?
private let readableViewModel: ReadableViewModel?

init(
mainViewModel: MainViewModel,
readable: Readable?
readableViewModel: ReadableViewModel?
) {
self.mainViewModel = mainViewModel
self.readable = readable
self.readableViewModel = readableViewModel
}

func cell(for indexPath: IndexPath, in collectionView: UICollectionView) -> UICollectionViewCell {
Expand All @@ -31,6 +31,6 @@ class UnsupportedComponentPresenter: ArticleComponentPresenter {
}

private func handleShowInWebReaderButtonTap() {
mainViewModel.presentedWebReaderURL = readable?.readerURL
mainViewModel.presentedWebReaderURL = readableViewModel?.url
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import UIKit

class VimeoComponentPresenter: ArticleComponentPresenter {
private let oEmbedService: OEmbedService
private let readable: Readable?
private let readableViewModel: ReadableViewModel?
private let component: VideoComponent
private let mainViewModel: MainViewModel

Expand All @@ -14,13 +14,13 @@ class VimeoComponentPresenter: ArticleComponentPresenter {

init(
oEmbedService: OEmbedService,
readable: Readable?,
readableViewModel: ReadableViewModel?,
component: VideoComponent,
mainViewModel: MainViewModel,
onContentLoaded: @escaping () -> Void
) {
self.oEmbedService = oEmbedService
self.readable = readable
self.readableViewModel = readableViewModel
self.component = component
self.mainViewModel = mainViewModel
self.onContentLoaded = onContentLoaded
Expand Down Expand Up @@ -88,7 +88,7 @@ class VimeoComponentPresenter: ArticleComponentPresenter {

extension VimeoComponentPresenter: VimeoComponentCellDelegate {
func vimeoComponentCellDidTapOpenInWebView(_ cell: VimeoComponentCell) {
mainViewModel.presentedWebReaderURL = readable?.readerURL
mainViewModel.presentedWebReaderURL = readableViewModel?.url
}

func vimeoComponentCell(_ cell: VimeoComponentCell, didNavigateToURL url: URL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import UIKit
class YouTubeVideoComponentPresenter: ArticleComponentPresenter {
private let component: VideoComponent
private let mainViewModel: MainViewModel
private let readable: Readable?
private let readableViewModel: ReadableViewModel?

private var cancellable: AnyCancellable? = nil

init(
component: VideoComponent,
mainViewModel: MainViewModel,
readable: Readable?
readableViewModel: ReadableViewModel?
) {
self.component = component
self.mainViewModel = mainViewModel
self.readable = readable
self.readableViewModel = readableViewModel
}

func size(for availableWidth: CGFloat) -> CGSize {
Expand Down Expand Up @@ -66,6 +66,6 @@ class YouTubeVideoComponentPresenter: ArticleComponentPresenter {
}

private func handleShowInWebReaderButtonTap() {
mainViewModel.presentedWebReaderURL = readable?.readerURL
mainViewModel.presentedWebReaderURL = readableViewModel?.url
}
}
21 changes: 0 additions & 21 deletions PocketKit/Sources/PocketKit/Article/Readable.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,37 @@ import Analytics
import Kingfisher


protocol ReadableViewControllerDelegate: AnyObject {
func readableViewController(_ controller: ReadableViewController, willOpenURL url: URL)
func readableViewControlled(_ controller: ReadableViewController, shareWithAdditionalText text: String?)
}

class ArticleViewController: UIViewController {
class ReadableViewController: UIViewController {
private var metadata: ArticleMetadataPresenter?

var presenters: [ArticleComponentPresenter]?

var item: Readable? {
var readableViewModel: ReadableViewModel? {
didSet {
metadata = item.flatMap { item -> ArticleMetadataPresenter in
metadata = readableViewModel.flatMap { readableViewModel -> ArticleMetadataPresenter in
ArticleMetadataPresenter(
readable: item,
readableViewModel: readableViewModel,
readerSettings: readerSettings
)
}

presenters = item?.components?.filter { !$0.isEmpty }.map { presenter(for: $0) }
presenters = readableViewModel?.components?.filter { !$0.isEmpty }.map { presenter(for: $0) }

DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}

weak var delegate: ReadableViewControllerDelegate? = nil

private var contexts: [Context] {
guard let item = item, let url = item.readerURL else {
guard let viewModel = readableViewModel, let url = viewModel.url else {
return []
}

Expand Down Expand Up @@ -102,15 +108,15 @@ class ArticleViewController: UIViewController {
}
}

extension ArticleViewController: UICollectionViewDelegate {
extension ReadableViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? YouTubeVideoComponentCell {
cell.pause()
}
}
}

extension ArticleViewController: UICollectionViewDataSource {
extension ReadableViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
guard let presenters = presenters else {
return 0
Expand All @@ -125,7 +131,7 @@ extension ArticleViewController: UICollectionViewDataSource {
) -> Int {
switch section {
case 0:
return item == nil ? 0 : 1
return readableViewModel == nil ? 0 : 1
default:
return presenters?.count ?? 0
}
Expand Down Expand Up @@ -158,31 +164,24 @@ extension ArticleViewController: UICollectionViewDataSource {
}
}

extension ArticleViewController: ArticleComponentTextCellDelegate {
extension ReadableViewController: ArticleComponentTextCellDelegate {
func articleComponentTextCell(
_ cell: ArticleComponentTextCell,
didShareText selectedText: String?
) {
guard let item = item, let activity = item.shareActivity(additionalText: selectedText) else {
return
}

viewModel.sharedActivity = activity
delegate?.readableViewControlled(self, shareWithAdditionalText: selectedText)
}

func articleComponentTextCell(
_ cell: ArticleComponentTextCell,
shouldOpenURL url: URL
) -> Bool {
let contentOpen = ContentOpenEvent(destination: .external, trigger: .click)
let link = UIContext.articleView.link
let contexts = contexts + [link]
tracker.track(event: contentOpen, contexts)
delegate?.readableViewController(self, willOpenURL: url)
return true
}
}

extension ArticleViewController {
extension ReadableViewController {
enum Constants {
static let metaSectionContentInsets = NSDirectionalEdgeInsets(
top: 16,
Expand Down Expand Up @@ -258,7 +257,7 @@ extension ArticleViewController {
}
}

extension ArticleViewController {
extension ReadableViewController {
func presenter(for component: ArticleComponent) -> ArticleComponentPresenter {
switch component {
case .text(let component):
Expand All @@ -278,7 +277,7 @@ extension ArticleViewController {
case .numberedList(let component):
return ListComponentPresenter(component: component, readerSettings: readerSettings)
case .table:
return UnsupportedComponentPresenter(mainViewModel: viewModel, readable: item)
return UnsupportedComponentPresenter(mainViewModel: viewModel, readableViewModel: readableViewModel)
case .blockquote(let component):
return BlockquoteComponentPresenter(component: component, readerSettings: readerSettings)
case .video(let component):
Expand All @@ -287,22 +286,22 @@ extension ArticleViewController {
return YouTubeVideoComponentPresenter(
component: component,
mainViewModel: viewModel,
readable: item
readableViewModel: readableViewModel
)
case .vimeoLink, .vimeoIframe, .vimeoMoogaloop:
return VimeoComponentPresenter(
oEmbedService: OEmbedService(session: URLSession.shared),
readable: item,
readableViewModel: readableViewModel,
component: component,
mainViewModel: viewModel
) { [weak self] in
self?.layout.invalidateLayout()
}
default:
return UnsupportedComponentPresenter(mainViewModel: viewModel, readable: item)
return UnsupportedComponentPresenter(mainViewModel: viewModel, readableViewModel: readableViewModel)
}
default:
return UnsupportedComponentPresenter(mainViewModel: viewModel, readable: item)
return UnsupportedComponentPresenter(mainViewModel: viewModel, readableViewModel: readableViewModel)
}
}
}
Loading

0 comments on commit 322c551

Please sign in to comment.