Skip to content

Commit

Permalink
[RNMobile] Add autosave to mobile apps (#17329)
Browse files Browse the repository at this point in the history
* [RNMobile] Fix crash when adding separator

* Build: remove global install of latest npm since we want to use the paired node/npm version (#17134)

* Build: remove global install of latest npm since we want to use the paired node/npm version
* Also update travis to remove --latest-npm flag

* [RNMobile] Try dark mode (iOS) (#17067)

* Adding dark mode component implemented on list and list block

* Adding DarkMode handling to RichText, ToolBar and SafeArea

* Mobile: Using DarkMode as HOC

* iOS DarkMode: Modified colors on block list and block container

* iOS DarkMode: Improved Header Toolbar colors

* iOS DarkMode: Removing background from buttons

* iOS DarkMode warning and unsupported

* iOS DarkMode: MediaPlaceholder

* iOS DarkMode: BottomSheets

* iOS DarkMode: Inserter

* iOS DarkMode: DefaultBlockAppender

* iOS DarkMode: PostTite

* Update hardcoded colors with variables

* iOS DarkMode: Fix bottom-sheet cell value color

* iOS DarkMode: More - PageBreak - Add Block Here

* iOS DarkMode: Better text color

* iOS Darkmode: Code block

* iOS DarkMode: HTML View

* iOS DarkMode: Improve colors on SafeArea

* Fix toolbar not avoiding keyboard regression

* Fix native unit tests

* Fix gutenberg-mobile unit tests

* Adding RNDarkMode mocks

* RNMobile: Fix crash when viewing HTML on iOS

* [RNMobile] Remove toolbar from html view

* [RNMobile] Fix MaxListenersExceededWarning caused by dark-mode event emitter (#17186)

* Fix MaxListenersExceededWarning caused by dark-mode event emitter

* Checking for setMaxListeners trying to avoid CI error

* Adding remove listener to DarkMode HOC

* DarkMode: Binding this.onModeChanged to `this`

* DarkMode: Adding conditional needed to pass UI Tests on CI

* Fix focus title on new posts regression (#17180)

* BottomSheet: Setting DashIcon color directly when theme is default (light) (#17193)

* Add a preliminary version of the AutosaveMonitor for mobile that calls the "bridge" and asks the native side to save the content

* Add autosave mock function for tests

* Fix merge conflicts

* Fix lint

* Re-add autosave on mobile that was removed erroneously during import-merge from rnmobile/master

* Remove native variant of AutosaveMonitor and introduces changes at  editor store level

* Default to false for `isEditedPostAutosaveable` on mobile. There was a typo in the returing value on the previous commit.

* Make sure to consider edits to the Title when checking if auto-save is needed

* Fix lint
  • Loading branch information
daniloercoli authored Sep 19, 2019
1 parent 264b178 commit 648a1b9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/edit-post/src/components/layout/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Component } from '@wordpress/element';
import { withSelect } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { HTMLTextInput, KeyboardAvoidingView, ReadableContentView, withTheme } from '@wordpress/components';
import { AutosaveMonitor } from '@wordpress/editor';

/**
* Internal dependencies
Expand Down Expand Up @@ -116,6 +117,7 @@ class Layout extends Component {

return (
<SafeAreaView style={ useStyle( styles.container, styles.containerDark ) } onLayout={ this.onRootViewLayout }>
<AutosaveMonitor />
<View style={ useStyle( styles.background, styles.backgroundDark ) }>
{ isHtmlView ? this.renderHTML() : this.renderVisual() }
</View>
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/components/index.native.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

// Post Related Components
export { default as AutosaveMonitor } from './autosave-monitor';
export { default as PostTitle } from './post-title';
export { default as EditorHistoryRedo } from './editor-history/redo';
export { default as EditorHistoryUndo } from './editor-history/undo';
Expand Down
13 changes: 13 additions & 0 deletions packages/editor/src/store/actions.native.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* External dependencies
*/
import RNReactNativeGutenbergBridge from 'react-native-gutenberg-bridge';

export * from './actions.js';

Expand All @@ -14,3 +18,12 @@ export function togglePostTitleSelection( isSelected = true ) {
isSelected,
};
}

/**
* Action generator used in signalling that the post should autosave.
*
* @param {Object?} options Extra flags to identify the autosave.
*/
export function* autosave( ) {
RNReactNativeGutenbergBridge.editorDidAutosave();
}
4 changes: 4 additions & 0 deletions packages/editor/src/store/reducer.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import {
editorSettings,
} from './reducer.js';

import { EDITOR_SETTINGS_DEFAULTS } from './defaults.js';

EDITOR_SETTINGS_DEFAULTS.autosaveInterval = 2; // This is a way to override default on mobile

export * from './reducer.js';

/**
Expand Down
42 changes: 42 additions & 0 deletions packages/editor/src/store/selectors.native.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/**
* WordPress dependencies
*/
import { createRegistrySelector } from '@wordpress/data';

/**
* Internal dependencies
*/
import {
isEditedPostDirty,
isEditedPostSaveable,
hasChangedContent,
} from './selectors.js';

export * from './selectors.js';

Expand All @@ -11,3 +24,32 @@ export * from './selectors.js';
export function isPostTitleSelected( state ) {
return state.postTitle.isSelected;
}

/**
* Returns true if the post can be autosaved, or false otherwise.
*
* @param {Object} state Global application state.
* @param {Object} autosave A raw autosave object from the REST API.
*
* @return {boolean} Whether the post can be autosaved.
*/
export const isEditedPostAutosaveable = createRegistrySelector( ( ) => function( state ) {
// A post must contain a title, an excerpt, or non-empty content to be valid for autosaving.
if ( ! isEditedPostSaveable( state ) ) {
return false;
}

// To avoid an expensive content serialization, use the content dirtiness
// flag in place of content field comparison against the known autosave.
// This is not strictly accurate, and relies on a tolerance toward autosave
// request failures for unnecessary saves.
if ( hasChangedContent( state ) ) {
return true;
}

if ( isEditedPostDirty( state ) ) {
return true;
}

return false;
} );
1 change: 1 addition & 0 deletions test/native/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jest.mock( 'react-native-gutenberg-bridge', () => {
subscribeUpdateHtml: jest.fn(),
subscribeMediaAppend: jest.fn(),
editorDidMount: jest.fn(),
editorDidAutosave: jest.fn(),
subscribeMediaUpload: jest.fn(),
requestMediaPickFromMediaLibrary: jest.fn(),
requestMediaPickFromDeviceLibrary: jest.fn(),
Expand Down

0 comments on commit 648a1b9

Please sign in to comment.