Skip to content
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

[Gutenberg] Autosave #12489

Merged
merged 5 commits into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ target 'WordPress' do
## Gutenberg (React Native)
## =====================
##
gutenberg :tag => 'v1.13.0'
## gutenberg :commit => '719c111dc0f927e6fa2cfa382f9678d14e5506cd'
gutenberg :commit => 'dd3a6d6730d8265ed76acb0f60e3ddad89902c1e'

## Third party libraries
## =====================
Expand Down
114 changes: 57 additions & 57 deletions Podfile.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ class AztecPostViewController: UIViewController, PostEditor {
return Debouncer(delay: PostEditorDebouncerConstants.autoSavingDelay, callback: debouncerCallback)
}()

lazy var autosaver = Autosaver { [weak self] in
self?.mapUIContentToPostAndSave(immediate: true)
}

// MARK: - Styling Options

private lazy var optionsTablePresenter = OptionsTablePresenter(presentingViewController: self, presentingTextView: editorView.richTextView)
Expand Down Expand Up @@ -1306,7 +1310,7 @@ extension AztecPostViewController: UITextViewDelegate {
}

func textViewDidChange(_ textView: UITextView) {
mapUIContentToPostAndSave()
autosaver.contentDidChange()
refreshPlaceholderVisibility()

switch textView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,6 @@ class GutenbergViewController: UIViewController, PostEditor {
})
}

// MARK: - Auto save post

static let autoSaveInterval: TimeInterval = 5

var autoSaveTimer: Timer?

// MARK: - Set content

func setTitle(_ title: String) {
Expand Down Expand Up @@ -176,6 +170,10 @@ class GutenbergViewController: UIViewController, PostEditor {
return Debouncer(delay: PostEditorDebouncerConstants.autoSavingDelay, callback: debouncerCallback)
}()

lazy var autosaver = Autosaver { [weak self] in
self?.requestHTML(for: .autoSave)
}

/// Media Library Data Source
///
lazy var mediaLibraryDataSource: MediaLibraryPickerDataSource = {
Expand Down Expand Up @@ -228,7 +226,6 @@ class GutenbergViewController: UIViewController, PostEditor {
}

deinit {
stopAutoSave()
gutenberg.invalidate()
attachmentDelegate.cancelAllPendingMediaRequests()
}
Expand Down Expand Up @@ -336,6 +333,9 @@ extension GutenbergViewController {
// MARK: - GutenbergBridgeDelegate

extension GutenbergViewController: GutenbergBridgeDelegate {
func editorDidAutosave() {
autosaver.contentDidChange()
}

func gutenbergDidRequestMedia(from source: MediaPickerSource, filter: [MediaFilter]?, with callback: @escaping MediaPickerDidPickMediaCallback) {
let flags = mediaFilterFlags(using: filter)
Expand Down Expand Up @@ -503,16 +503,11 @@ extension GutenbergViewController: GutenbergBridgeDelegate {
}

func gutenbergDidMount(unsupportedBlockNames: [String]) {
startAutoSave()
if !editorSession.started {
editorSession.start(unsupportedBlocks: unsupportedBlockNames)
}
}

func editorDidAutosave() {
// Currently using native side `autoSaveTimer` for autosave purposes.
}

func gutenbergDidEmitLog(message: String, logLevel: LogLevel) {
switch logLevel {
case .trace:
Expand Down Expand Up @@ -617,22 +612,6 @@ extension GutenbergViewController: PostEditorNavigationBarManagerDelegate {
}
}

// MARK: - Auto Save

extension GutenbergViewController {

func startAutoSave() {
autoSaveTimer = Timer.scheduledTimer(withTimeInterval: GutenbergViewController.autoSaveInterval, repeats: true, block: { [weak self](timer) in
self?.requestHTML(for: .autoSave)
})
}

func stopAutoSave() {
autoSaveTimer?.invalidate()
autoSaveTimer = nil
}
}

// MARK: - Constants

private extension GutenbergViewController {
Expand Down
38 changes: 38 additions & 0 deletions WordPress/Classes/ViewRelated/Post/Autosaver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/// Post autosave helper that triggers an action after X ammount of changes or Y time of inactivity.
///
class Autosaver {
private let action: (() -> Void)
private let changesThreshold: Int
private var changesCount = 0
private let delay: Double
private lazy var debouncer = Debouncer(delay: delay, callback: { [weak self] in
self?.triggerAutosave()
})

private func triggerAutosave() {
changesCount = 0
action()
}

/// Instantiates an instance of Autosaver
/// - Parameter changesThreshold: Ammount of changes allowed before autosaving. Default 50 changes.
/// - Parameter delay: Maximum time of inactivity before autosaving. Default 1 second.
/// - Parameter action: The action to be triggered when autosave is fired.
///
init(changesThreshold: Int = 50, delay: Double = 1, action: @escaping () -> Void) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaults are taken from WPAndroid.

self.changesThreshold = changesThreshold
self.action = action
self.delay = delay
}

/// Call this method everytime the post content changes to trigger the autosave action at the most appropiate time
///
func contentDidChange() {
changesCount += 1
if changesCount > changesThreshold {
triggerAutosave()
} else {
debouncer.call()
}
}
}
2 changes: 2 additions & 0 deletions WordPress/Classes/ViewRelated/Post/PostEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ protocol PostEditor: class, UIViewControllerTransitioningDelegate {
/// Closure to call when the editor needs to be replaced with a different editor
/// First argument is the existing editor, second argument is the replacement editor
var replaceEditor: (EditorViewController, EditorViewController) -> () { get }

var autosaver: Autosaver { get set }
}

extension PostEditor {
Expand Down
4 changes: 4 additions & 0 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,7 @@
7E8980CA22E8C7A600C567B0 /* BlogToBlogMigration87to88.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8980C922E8C7A600C567B0 /* BlogToBlogMigration87to88.swift */; };
7E92828921090E9A00BBD8A3 /* notifications-pingback.json in Resources */ = {isa = PBXBuildFile; fileRef = 7E92828821090E9A00BBD8A3 /* notifications-pingback.json */; };
7E929CD12110D4F200BCAD88 /* FormattableRangesFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E929CD02110D4F200BCAD88 /* FormattableRangesFactory.swift */; };
7E92A1FB233CB1B7006D281B /* Autosaver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E92A1FA233CB1B7006D281B /* Autosaver.swift */; };
7E987F562108017B00CAFB88 /* NotificationContentRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E987F552108017B00CAFB88 /* NotificationContentRouter.swift */; };
7E987F58210811CC00CAFB88 /* NotificationContentRouterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E987F57210811CC00CAFB88 /* NotificationContentRouterTests.swift */; };
7E987F5A2108122A00CAFB88 /* NotificationUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E987F592108122A00CAFB88 /* NotificationUtility.swift */; };
Expand Down Expand Up @@ -3047,6 +3048,7 @@
7E8980C922E8C7A600C567B0 /* BlogToBlogMigration87to88.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BlogToBlogMigration87to88.swift; path = "87-88/BlogToBlogMigration87to88.swift"; sourceTree = "<group>"; };
7E92828821090E9A00BBD8A3 /* notifications-pingback.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "notifications-pingback.json"; sourceTree = "<group>"; };
7E929CD02110D4F200BCAD88 /* FormattableRangesFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattableRangesFactory.swift; sourceTree = "<group>"; };
7E92A1FA233CB1B7006D281B /* Autosaver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Autosaver.swift; sourceTree = "<group>"; };
7E987F552108017B00CAFB88 /* NotificationContentRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContentRouter.swift; sourceTree = "<group>"; };
7E987F57210811CC00CAFB88 /* NotificationContentRouterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContentRouterTests.swift; sourceTree = "<group>"; };
7E987F592108122A00CAFB88 /* NotificationUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationUtility.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5681,6 +5683,7 @@
570BFD8A22823D7B007859A8 /* PostActionSheet.swift */,
570265142298921800F2214C /* PostListTableViewHandler.swift */,
57047A4E22A961BC00B461DF /* PostSearchHeader.swift */,
7E92A1FA233CB1B7006D281B /* Autosaver.swift */,
);
name = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -11442,6 +11445,7 @@
9A38DC6D218899FB006A409B /* DiffAbstractValue.swift in Sources */,
177B4C252123161900CF8084 /* GiphyPicker.swift in Sources */,
17B7C8C120EE2A870042E260 /* Routes+Notifications.swift in Sources */,
7E92A1FB233CB1B7006D281B /* Autosaver.swift in Sources */,
9A341E5621997A340036662E /* BlogAuthor.swift in Sources */,
9A341E5721997A340036662E /* Blog+BlogAuthors.swift in Sources */,
7E3AB3DB20F52654001F33B6 /* ActivityContentStyles.swift in Sources */,
Expand Down