diff --git a/package-lock.json b/package-lock.json
index a92712b..2b881d9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16463,6 +16463,11 @@
"resolved": "https://registry.npmjs.org/redux-optimist/-/redux-optimist-1.0.0.tgz",
"integrity": "sha512-AG1v8o6UZcGXTEH2jVcWG6KD+gEix+Cj9JXAAzln9MPkauSVd98H7N7EOOyT/v4c9N1mJB4sm1zfspGlLDkUEw=="
},
+ "redux-undo": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/redux-undo/-/redux-undo-1.0.1.tgz",
+ "integrity": "sha512-0yFPT+FUgwxCEiS0Mg5T1S4tkgjR8h6sJRY9CW4EMsbJOf1SxO289TbJmlzhRouCHacdDF+powPjrjLHoJYxWQ=="
+ },
"reflect.ownkeys": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
diff --git a/package.json b/package.json
index c6db140..ed44cad 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,9 @@
},
"devDependencies": {
"@wordpress/env": "^2.0.0",
+ "@wordpress/data-controls": "^1.14.0",
"@wordpress/eslint-plugin": "^7.2.0",
+ "@wordpress/keycodes": "^2.13.0",
"@wordpress/scripts": "^12.2.0",
"autoprefixer": "^9.8.6",
"css-loader": "^4.3.0",
@@ -44,6 +46,7 @@
"@wordpress/format-library": "^1.23.0",
"@wordpress/i18n": "^3.15.0",
"@wordpress/interface": "^0.8.0",
- "@wordpress/media-utils": "^1.16.0"
+ "@wordpress/media-utils": "^1.16.0",
+ "redux-undo": "^1.0.1"
}
}
diff --git a/src/components/block-editor/index.js b/src/components/block-editor/index.js
index 88ae320..8f05c8d 100644
--- a/src/components/block-editor/index.js
+++ b/src/components/block-editor/index.js
@@ -23,7 +23,8 @@ import {
import Sidebar from 'components/sidebar';
function BlockEditor( { settings: _settings } ) {
- const [ blocks, updateBlocks ] = useState( [] );
+ const blocks = useSelect((select) => select("getdavesbe").getBlocks());
+ const { updateBlocks } = useDispatch("getdavesbe");
const { createInfoNotice } = useDispatch( 'core/notices' );
const canUserCreateMedia = useSelect( ( select ) => {
@@ -47,17 +48,17 @@ function BlockEditor( { settings: _settings } ) {
};
}, [ canUserCreateMedia, _settings ] );
- useEffect( () => {
- const storedBlocks = window.localStorage.getItem( 'getdavesbeBlocks' );
+ // useEffect( () => {
+ // const storedBlocks = window.localStorage.getItem( 'getdavesbeBlocks' );
- if ( storedBlocks?.length ) {
- handleUpdateBlocks(() => parse(storedBlocks));
- createInfoNotice( 'Blocks loaded', {
- type: 'snackbar',
- isDismissible: true,
- } );
- }
- }, [] );
+ // if ( storedBlocks?.length ) {
+ // handleUpdateBlocks(() => parse(storedBlocks));
+ // createInfoNotice( 'Blocks loaded', {
+ // type: 'snackbar',
+ // isDismissible: true,
+ // } );
+ // }
+ // }, [] );
/**
* Wrapper for updating blocks. Required as `onInput` callback passed to
@@ -70,8 +71,9 @@ function BlockEditor( { settings: _settings } ) {
}
function handlePersistBlocks( newBlocks ) {
- updateBlocks( newBlocks );
- window.localStorage.setItem( 'getdavesbeBlocks', serialize( newBlocks ) );
+ updateBlocks( newBlocks, true );
+ // persistBlocks(newBlocks);
+ // window.localStorage.setItem( 'getdavesbeBlocks', serialize( newBlocks ) );
}
return (
diff --git a/src/components/header/index.js b/src/components/header/index.js
index e2cb932..4619802 100644
--- a/src/components/header/index.js
+++ b/src/components/header/index.js
@@ -3,17 +3,27 @@
*/
import { __ } from '@wordpress/i18n';
+
+import HistoryUndo from './undo';
+import HistoryRedo from "./redo";
+
export default function Header() {
+ function handleUndo() {
+ console.log( 'undo' );
+ }
return (
- { __( 'Standalone Block Editor', 'getdavesbe' ) }
+ {__("Standalone Block Editor", "getdavesbe")}
+
+
+
);
}
diff --git a/src/components/header/redo.js b/src/components/header/redo.js
new file mode 100644
index 0000000..45e60a7
--- /dev/null
+++ b/src/components/header/redo.js
@@ -0,0 +1,35 @@
+import { __ } from '@wordpress/i18n';
+import { Button } from '@wordpress/components';
+import { withSelect, withDispatch } from '@wordpress/data';
+import { compose } from '@wordpress/compose';
+import { displayShortcut } from '@wordpress/keycodes';
+import { redo as redoIcon } from '@wordpress/icons';
+
+
+function HistoryRedo( { hasRedo, redo, ...props } ) {
+ return (
+
+ );
+}
+
+const EnhancedHistoryRedo = compose( [
+ withSelect( ( select ) => ( {
+ hasRedo: select( 'getdavesbe' ).hasRedo(),
+ } ) ),
+ withDispatch( ( dispatch ) => ( {
+ redo: dispatch( 'getdavesbe' ).redo,
+ } ) ),
+] )( HistoryRedo );
+
+export default EnhancedHistoryRedo;
diff --git a/src/components/header/undo.js b/src/components/header/undo.js
new file mode 100644
index 0000000..4b65815
--- /dev/null
+++ b/src/components/header/undo.js
@@ -0,0 +1,35 @@
+import { __ } from '@wordpress/i18n';
+import { Button } from '@wordpress/components';
+import { withSelect, withDispatch } from '@wordpress/data';
+import { compose } from '@wordpress/compose';
+import { displayShortcut } from '@wordpress/keycodes';
+import { undo as undoIcon } from '@wordpress/icons';
+
+
+function HistoryUndo( { hasUndo, undo, ...props } ) {
+ return (
+
+ );
+}
+
+const EnhancedHistoryUndo = compose( [
+ withSelect( ( select ) => ( {
+ hasUndo: select( 'getdavesbe' ).hasUndo(),
+ } ) ),
+ withDispatch( ( dispatch ) => ( {
+ undo: dispatch( 'getdavesbe' ).undo,
+ } ) ),
+] )( HistoryUndo );
+
+export default EnhancedHistoryUndo;
diff --git a/src/index.js b/src/index.js
index 71781cd..aff1a3b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,11 +3,15 @@ import { render } from '@wordpress/element';
import { registerCoreBlocks } from '@wordpress/block-library';
import Editor from './editor';
+import './store';
+
import './styles.scss';
-domReady( function() {
+domReady( function () {
const settings = window.getdaveSbeSettings || {};
registerCoreBlocks();
- render( , document.getElementById( 'getdave-sbe-block-editor' ) );
+ render(
+ ,
+ document.getElementById( 'getdave-sbe-block-editor' )
+ );
} );
-
diff --git a/src/store/action-types.js b/src/store/action-types.js
new file mode 100644
index 0000000..11b60d8
--- /dev/null
+++ b/src/store/action-types.js
@@ -0,0 +1,4 @@
+export const UPDATE_BLOCKS = "UPDATE_BLOCKS";
+export const PERSIST_BLOCKS = "PERSIST_BLOCKS";
+export const FETCH_BLOCKS_FROM_STORAGE = "FETCH_BLOCKS_FROM_STORAGE";
+export const PERSIST_BLOCKS_TO_STORAGE = "PERSIST_BLOCKS_TO_STORAGE";
\ No newline at end of file
diff --git a/src/store/actions.js b/src/store/actions.js
new file mode 100644
index 0000000..1d9e184
--- /dev/null
+++ b/src/store/actions.js
@@ -0,0 +1,43 @@
+import {
+ UPDATE_BLOCKS,
+ PERSIST_BLOCKS,
+ FETCH_BLOCKS_FROM_STORAGE,
+ PERSIST_BLOCKS_TO_STORAGE,
+} from "./action-types";
+import { ActionCreators as ReduxUndo } from "redux-undo";
+
+
+export function undo() {
+ return ReduxUndo.undo();
+}
+
+export function redo() {
+ return ReduxUndo.redo();
+}
+
+export function *updateBlocks( blocks, persist = false ) {
+
+ if( persist ) {
+ yield persistBlocksToStorage(blocks);
+ }
+
+ return {
+ type: persist ? PERSIST_BLOCKS : UPDATE_BLOCKS,
+ blocks,
+ };
+}
+
+export function fetchBlocksFromStorage() {
+ return {
+ type: FETCH_BLOCKS_FROM_STORAGE,
+ };
+};
+
+export function persistBlocksToStorage(blocks) {
+ return {
+ type: PERSIST_BLOCKS_TO_STORAGE,
+ blocks,
+ };
+}
+
+
diff --git a/src/store/controls.js b/src/store/controls.js
new file mode 100644
index 0000000..0ade00e
--- /dev/null
+++ b/src/store/controls.js
@@ -0,0 +1,21 @@
+import {
+ FETCH_BLOCKS_FROM_STORAGE,
+ PERSIST_BLOCKS_TO_STORAGE,
+} from "./action-types";
+import { serialize } from "@wordpress/blocks";
+
+export default {
+ [PERSIST_BLOCKS_TO_STORAGE](action) {
+ return new Promise((resolve, reject) => {
+ window.localStorage.setItem("getdavesbeBlocks", serialize(action.blocks));
+ resolve(action.blocks);
+ });
+ },
+ [FETCH_BLOCKS_FROM_STORAGE]() {
+ return new Promise((resolve, reject) => {
+ const storedBlocks =
+ window.localStorage.getItem("getdavesbeBlocks") || [];
+ resolve(storedBlocks);
+ });
+ },
+};
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..e6e7d15
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,30 @@
+/**
+ * WordPress dependencies
+ */
+import { registerStore } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import reducer from './reducer';
+import * as selectors from './selectors';
+import * as actions from './actions';
+import * as resolvers from "./resolvers";
+import controls from './controls';
+
+/**
+ * Module Constants
+ */
+const MODULE_KEY = 'getdavesbe';
+
+const store = registerStore(MODULE_KEY, {
+ reducer,
+ selectors,
+ actions,
+ controls,
+ resolvers,
+});
+
+window.getDaveStore = store;
+
+export default store;
diff --git a/src/store/reducer.js b/src/store/reducer.js
new file mode 100644
index 0000000..0cdd95c
--- /dev/null
+++ b/src/store/reducer.js
@@ -0,0 +1,24 @@
+
+import undoable, { groupByActionTypes, includeAction } from "redux-undo";
+
+
+
+import { UPDATE_BLOCKS, PERSIST_BLOCKS } from "./action-types";
+
+function blocksReducer(state = [], action) {
+ switch (action.type) {
+ case UPDATE_BLOCKS:
+ case PERSIST_BLOCKS:
+ const { blocks } = action;
+
+ return {
+ blocks,
+ };
+ }
+
+ return state;
+}
+
+export default undoable(blocksReducer, {
+ filter: includeAction(PERSIST_BLOCKS),
+});
diff --git a/src/store/resolvers.js b/src/store/resolvers.js
new file mode 100644
index 0000000..802f464
--- /dev/null
+++ b/src/store/resolvers.js
@@ -0,0 +1,10 @@
+import { parse } from "@wordpress/blocks";
+import { fetchBlocksFromStorage, updateBlocks } from "./actions";
+
+export function *getBlocks() {
+ const rawBlocks = yield fetchBlocksFromStorage();
+ const persist = false;
+ const blocks = parse(rawBlocks);
+ yield updateBlocks(blocks, persist);
+ return blocks;
+}
\ No newline at end of file
diff --git a/src/store/selectors.js b/src/store/selectors.js
new file mode 100644
index 0000000..14417b2
--- /dev/null
+++ b/src/store/selectors.js
@@ -0,0 +1,19 @@
+import { createRegistrySelector } from '@wordpress/data';
+
+
+
+
+
+
+export const getBlocks = ( state ) => {
+ return state.present.blocks || [];
+}
+
+export const hasUndo = (state) => {
+ return state.past?.length;
+};
+
+export const hasRedo = (state) => {
+ return state.future?.length;
+};
+
diff --git a/src/styles.scss b/src/styles.scss
index 029a0db..7f5523e 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -4,6 +4,7 @@
@import "~@wordpress/base-styles/breakpoints";
@import "~@wordpress/base-styles/animations";
@import "~@wordpress/base-styles/z-index";
+@import "~@wordpress/interface/src/style.scss";
diff --git a/webpack.config.js b/webpack.config.js
index d3b3be0..eae530b 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -15,7 +15,8 @@ module.exports = {
...defaultConfig.resolve,
// alias directories to paths you can use in import() statements
alias: {
- components: path.join( paths.srcDir, 'components' ),
+ components: path.join(paths.srcDir, "components"),
+ store: path.join(paths.srcDir, "store"),
},
},
};