diff --git a/.gitignore b/.gitignore index 51163b4ba..a8f61c017 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,13 @@ fastlane/Preview.html fastlane/screenshots fastlane/test_output +<<<<<<< HEAD /Shared/Secrets.swift *.py[cod] +======= +/Shared/Secrets.swift +*.py[cod] + +>>>>>>> mac-release diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index f344a7c26..9b3137d4d 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -89,6 +89,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(inspectableObjectsDidChange(_:)), name: .InspectableObjectsDidChange, object: nil) + NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(didWakeNotification(_:)), name: NSWorkspace.didWakeNotification, object: nil) appDelegate = self } @@ -268,10 +269,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, } func applicationDidBecomeActive(_ notification: Notification) { - // It’s possible there’s a refresh timer set to go off in the past. - // In that case, refresh now and update the timer. - refreshTimer?.fireOldTimer() - syncTimer?.fireOldTimer() + fireOldTimers() } func applicationDidResignActive(_ notification: Notification) { @@ -328,6 +326,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, refreshTimer?.update() updateDockBadge() } + + @objc func didWakeNotification(_ note: Notification) { + fireOldTimers() + } // MARK: Main Window func windowControllerWithName(_ storyboardName: String) -> NSWindowController { @@ -624,6 +626,13 @@ extension AppDelegate { private extension AppDelegate { + func fireOldTimers() { + // It’s possible there’s a refresh timer set to go off in the past. + // In that case, refresh now and update the timer. + refreshTimer?.fireOldTimer() + syncTimer?.fireOldTimer() + } + func createReaderWindow() -> MainWindowController { return windowControllerWithName("MainWindow") as! MainWindowController diff --git a/Mac/MainWindow/Detail/DetailViewController.swift b/Mac/MainWindow/Detail/DetailViewController.swift index f5039d07e..c7d2c2497 100644 --- a/Mac/MainWindow/Detail/DetailViewController.swift +++ b/Mac/MainWindow/Detail/DetailViewController.swift @@ -58,8 +58,12 @@ final class DetailViewController: NSViewController, WKUIDelegate { currentWebViewController = webViewController(for: mode) } - func canScrollDown(_ completion: @escaping (Bool) -> Void) { - currentWebViewController.canScrollDown(completion) + func stopMediaPlayback() { + currentWebViewController.stopMediaPlayback() + } + + func canScrollDown(_ callback: @escaping (Bool) -> Void) { + currentWebViewController.canScrollDown(callback) } override func scrollPageDown(_ sender: Any?) { diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 6fd4a2de1..c99c39a99 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -136,6 +136,12 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { reloadArticleImage() } + // MARK: Media Functions + + func stopMediaPlayback() { + webView.evaluateJavaScript("stopMediaPlayback();") + } + // MARK: Scrolling func canScrollDown(_ completion: @escaping (Bool) -> Void) { diff --git a/Mac/MainWindow/Detail/styleSheet.css b/Mac/MainWindow/Detail/styleSheet.css index 4fd43f4ba..85c06aaf7 100644 --- a/Mac/MainWindow/Detail/styleSheet.css +++ b/Mac/MainWindow/Detail/styleSheet.css @@ -1,11 +1,14 @@ body { margin-top: 20px; margin-bottom: 64px; - margin-left: 64px; - margin-right: 64px; + margin-left: auto; + margin-right: auto; + padding-left: 64px; + padding-right: 64px; font-family: -apple-system; font-size: 18px; word-wrap: break-word; /* break long words or URLs */ + max-width: 44em; } a { @@ -161,7 +164,7 @@ code, pre { padding: 0; } -img, figure, iframe, div { +img, figure, div { max-width: 100%; height: auto !important; margin: 0 auto; @@ -173,6 +176,11 @@ video { margin: 0 auto; } +iframe { + max-width: 100%; + margin: 0 auto; +} + figcaption { font-size: 14px; line-height: 1.3em; @@ -239,7 +247,6 @@ img[src*="share-buttons"] { display: none !important; } - /* Newsfoot specific styles. Structural styles come first, theme styles second */ .newsfoot-footnote-container { position: relative; @@ -372,3 +379,8 @@ sup > div > a[href^='#fn']:hover { } +/* Site specific styles */ +.wp-smiley { + height: 1em; + max-height: 1em; +} diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index 39a7c3000..6c70ec92c 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -457,6 +457,14 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { } +// MARK: NSWindowDelegate + +extension MainWindowController: NSWindowDelegate { + func windowWillClose(_ notification: Notification) { + detailViewController?.stopMediaPlayback() + } +} + // MARK: - SidebarDelegate extension MainWindowController: SidebarDelegate { diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index 8e0ea0a0d..a951fbd11 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -306,7 +306,7 @@ protocol SidebarDelegate: class { func deleteNodes(_ nodes: [Node]) { let nodesToDelete = treeController.normalizedSelectedNodes(nodes) - guard let undoManager = undoManager, let deleteCommand = DeleteCommand(nodesToDelete: nodesToDelete, undoManager: undoManager, errorHandler: ErrorHandler.present) else { + guard let undoManager = undoManager, let deleteCommand = DeleteCommand(nodesToDelete: nodesToDelete, treeController: treeController, undoManager: undoManager, errorHandler: ErrorHandler.present) else { return } diff --git a/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift b/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift index e5fb0f393..defd7f186 100644 --- a/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift @@ -31,7 +31,7 @@ class AccountsFeedbinWindowController: NSWindowController { usernameTextField.stringValue = credentials.username actionButton.title = NSLocalizedString("Update", comment: "Update") } else { - actionButton.title = NSLocalizedString("Create", comment: "Create") + actionButton.title = NSLocalizedString("Add Account", comment: "Add Account") } } diff --git a/Shared/Article Rendering/ArticleRenderer.swift b/Shared/Article Rendering/ArticleRenderer.swift index 92f0de19c..50a9204b6 100644 --- a/Shared/Article Rendering/ArticleRenderer.swift +++ b/Shared/Article Rendering/ArticleRenderer.swift @@ -264,5 +264,6 @@ private extension Article { } return url } + } diff --git a/Shared/Article Rendering/main.js b/Shared/Article Rendering/main.js index f11730264..2a3c07337 100644 --- a/Shared/Article Rendering/main.js +++ b/Shared/Article Rendering/main.js @@ -84,6 +84,17 @@ function reloadArticleImage(imageSrc) { image.src = imageSrc; } +function stopMediaPlayback() { + document.querySelectorAll("iframe").forEach(element => { + var iframeSrc = element.src; + element.src = iframeSrc; + }); + + document.querySelectorAll("video, audio").forEach(element => { + element.pause(); + }); +} + function error() { document.body.innerHTML = "error"; } diff --git a/Shared/Commands/DeleteCommand.swift b/Shared/Commands/DeleteCommand.swift index 4567c7fa2..991b7b430 100644 --- a/Shared/Commands/DeleteCommand.swift +++ b/Shared/Commands/DeleteCommand.swift @@ -14,6 +14,7 @@ import Articles final class DeleteCommand: UndoableCommand { + let treeController: TreeController? let undoManager: UndoManager let undoActionName: String var redoActionName: String { @@ -23,7 +24,7 @@ final class DeleteCommand: UndoableCommand { private let itemSpecifiers: [SidebarItemSpecifier] - init?(nodesToDelete: [Node], undoManager: UndoManager, errorHandler: @escaping (Error) -> ()) { + init?(nodesToDelete: [Node], treeController: TreeController? = nil, undoManager: UndoManager, errorHandler: @escaping (Error) -> ()) { guard DeleteCommand.canDelete(nodesToDelete) else { return nil @@ -32,6 +33,7 @@ final class DeleteCommand: UndoableCommand { return nil } + self.treeController = treeController self.undoActionName = actionName self.undoManager = undoManager self.errorHandler = errorHandler @@ -44,10 +46,22 @@ final class DeleteCommand: UndoableCommand { } func perform() { - itemSpecifiers.forEach { $0.delete() {} } - registerUndo() + + let group = DispatchGroup() + itemSpecifiers.forEach { + group.enter() + $0.delete() { + group.leave() + } + } + + group.notify(queue: DispatchQueue.main) { + self.treeController?.rebuild() + self.registerUndo() + } + } - + func undo() { itemSpecifiers.forEach { $0.restore() } registerRedo() diff --git a/iOS/Resources/main_ios.js b/iOS/Resources/main_ios.js index a6c3da6e1..269dc0ce0 100644 --- a/iOS/Resources/main_ios.js +++ b/iOS/Resources/main_ios.js @@ -145,17 +145,6 @@ function postRenderProcessing() { inlineVideos(); } -function stopMediaPlayback() { - document.querySelectorAll("iframe").forEach(element => { - var iframeSrc = element.src; - element.src = iframeSrc; - }); - - document.querySelectorAll("video, audio").forEach(element => { - element.pause(); - }); -} - window.addEventListener('DOMContentLoaded', (event) => { window.webkit.messageHandlers.domContentLoaded.postMessage(""); });