diff --git a/Shared/Resources/GlobalKeyboardShortcuts.plist b/Shared/Resources/GlobalKeyboardShortcuts.plist
index 4c6f3662c..88e4eac90 100644
--- a/Shared/Resources/GlobalKeyboardShortcuts.plist
+++ b/Shared/Resources/GlobalKeyboardShortcuts.plist
@@ -106,11 +106,11 @@
title
- Open in Browser
+ Open in App Browser
key
[return]
action
- openInBrowser:
+ openFeedInAppBrowser:
key
diff --git a/Shared/UserNotifications/UserNotificationManager.swift b/Shared/UserNotifications/UserNotificationManager.swift
index 2f37a2438..6ddbad025 100644
--- a/Shared/UserNotifications/UserNotificationManager.swift
+++ b/Shared/UserNotifications/UserNotificationManager.swift
@@ -47,14 +47,20 @@ private extension UserNotificationManager {
let content = UNMutableNotificationContent()
content.title = webFeed.nameForDisplay
- content.body = ArticleStringFormatter.truncatedTitle(article)
- if content.body.isEmpty {
- content.body = ArticleStringFormatter.truncatedSummary(article)
+
+ if !ArticleStringFormatter.truncatedTitle(article).isEmpty {
+ content.subtitle = ArticleStringFormatter.truncatedTitle(article)
}
-
+
+ content.body = ArticleStringFormatter.truncatedSummary(article)
+
+ content.threadIdentifier = webFeed.webFeedID
+ content.summaryArgument = "\(webFeed.nameForDisplay)"
+ content.summaryArgumentCount = 1
+
content.sound = UNNotificationSound.default
content.userInfo = [UserInfoKey.articlePath: article.pathUserInfo]
-
+
let request = UNNotificationRequest.init(identifier: "articleID:\(article.articleID)", content: content, trigger: nil)
UNUserNotificationCenter.current().add(request)
}
diff --git a/iOS/Article/ArticleViewController.swift b/iOS/Article/ArticleViewController.swift
index 9bd609774..b43783b64 100644
--- a/iOS/Article/ArticleViewController.swift
+++ b/iOS/Article/ArticleViewController.swift
@@ -256,6 +256,7 @@ class ArticleViewController: UIViewController {
}
// MARK: Keyboard Shortcuts
+
@objc func navigateToTimeline(_ sender: Any?) {
coordinator.navigateToTimeline()
}
@@ -277,7 +278,10 @@ class ArticleViewController: UIViewController {
func stopArticleExtractorIfProcessing() {
currentWebViewController?.stopArticleExtractorIfProcessing()
}
-
+
+ func openInAppBrowser() {
+ currentWebViewController?.openInAppBrowser()
+ }
}
// MARK: WebViewControllerDelegate
diff --git a/iOS/Article/WebViewController.swift b/iOS/Article/WebViewController.swift
index e7270b919..83dba122d 100644
--- a/iOS/Article/WebViewController.swift
+++ b/iOS/Article/WebViewController.swift
@@ -227,7 +227,15 @@ class WebViewController: UIViewController {
activityViewController.popoverPresentationController?.barButtonItem = popOverBarButtonItem
present(activityViewController, animated: true)
}
-
+
+ func openInAppBrowser() {
+ guard let preferredLink = article?.preferredLink, let url = URL(string: preferredLink) else {
+ return
+ }
+
+ let vc = SFSafariViewController(url: url)
+ present(vc, animated: true)
+ }
}
// MARK: ArticleExtractorDelegate
diff --git a/iOS/KeyboardManager.swift b/iOS/KeyboardManager.swift
index c463fcde2..9129a4032 100644
--- a/iOS/KeyboardManager.swift
+++ b/iOS/KeyboardManager.swift
@@ -177,6 +177,9 @@ private extension KeyboardManager {
let openInBrowserTitle = NSLocalizedString("Open In Browser", comment: "Open In Browser")
keys.append(KeyboardManager.createKeyCommand(title: openInBrowserTitle, action: "openInBrowser:", input: UIKeyCommand.inputRightArrow, modifiers: [.command]))
+ let openInAppBrowserTitle = NSLocalizedString("Open In App Browser", comment: "Open In App Browser")
+ keys.append(KeyboardManager.createKeyCommand(title: openInAppBrowserTitle, action: "openInAppBrowser:", input: "\r", modifiers: []))
+
let toggleReadTitle = NSLocalizedString("Toggle Read Status", comment: "Toggle Read Status")
keys.append(KeyboardManager.createKeyCommand(title: toggleReadTitle, action: "toggleRead:", input: "u", modifiers: [.command, .shift]))
diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift
index accf4b67e..57babb007 100644
--- a/iOS/MasterFeed/MasterFeedViewController.swift
+++ b/iOS/MasterFeed/MasterFeedViewController.swift
@@ -11,6 +11,7 @@ import Account
import Articles
import RSCore
import RSTree
+import SafariServices
class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
@@ -458,7 +459,18 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
self.reloadAllVisibleCells()
}
}
-
+
+ @objc func markAllAsRead(_ sender: Any) {
+ guard let indexPath = tableView.indexPathForSelectedRow, let contentView = tableView.cellForRow(at: indexPath)?.contentView else {
+ return
+ }
+
+ let title = NSLocalizedString("Mark All as Read", comment: "Mark All as Read")
+ MarkAsReadAlertController.confirm(self, coordinator: coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
+ self?.coordinator.markAllAsReadInTimeline()
+ }
+ }
+
// MARK: API
func restoreSelectionIfNecessary(adjustScroll: Bool) {
@@ -503,7 +515,14 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
func focus() {
becomeFirstResponder()
}
-
+
+ func openInAppBrowser() {
+ if let indexPath = coordinator.currentFeedIndexPath,
+ let url = coordinator.homePageURLForFeed(indexPath) {
+ let vc = SFSafariViewController(url: url)
+ present(vc, animated: true)
+ }
+ }
}
// MARK: UIContextMenuInteractionDelegate
diff --git a/iOS/RootSplitViewController.swift b/iOS/RootSplitViewController.swift
index 33bd740c1..4117a0ee7 100644
--- a/iOS/RootSplitViewController.swift
+++ b/iOS/RootSplitViewController.swift
@@ -81,6 +81,14 @@ class RootSplitViewController: UISplitViewController {
@objc func openInBrowser(_ sender: Any?) {
coordinator.showBrowserForCurrentArticle()
}
+
+ @objc func openInAppBrowser(_ sender: Any?) {
+ coordinator.showInAppBrowserForCurrentArticle()
+ }
+
+ @objc func openFeedInAppBrowser(_ sender: Any?) {
+ coordinator.showInAppBrowserForCurrentFeed()
+ }
@objc func articleSearch(_ sender: Any?) {
coordinator.showSearch()
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index 64abb8d3d..22d1f30a3 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -12,6 +12,7 @@ import Account
import Articles
import RSCore
import RSTree
+import SafariServices
enum PanelMode {
case unset
@@ -1183,6 +1184,14 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
UIApplication.shared.open(url, options: [:])
}
+
+ func showInAppBrowserForCurrentArticle() {
+ articleViewController?.openInAppBrowser()
+ }
+
+ func showInAppBrowserForCurrentFeed() {
+ masterFeedViewController.openInAppBrowser()
+ }
func navigateToFeeds() {
masterFeedViewController?.focus()