mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] playground: save changes to local storage
closes #316 closes #101
This commit is contained in:
+84
-24
@@ -1,5 +1,5 @@
|
|||||||
import { SAMPLES } from "./samples.js";
|
import { SAMPLES } from "./samples.js";
|
||||||
const {useState, useRef} = owl.hooks;
|
const { useState, useRef, onMounted, onWillUnmount } = owl.hooks;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Constants, helpers, utils
|
// Constants, helpers, utils
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -150,6 +150,51 @@ Promise.all([loadTemplates(), owl.utils.whenReady()]).then(start);
|
|||||||
return zip.generateAsync({ type: "blob" });
|
return zip.generateAsync({ type: "blob" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// SAMPLES
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
function loadSamples() {
|
||||||
|
let result = SAMPLES.slice();
|
||||||
|
const localSample = localStorage.getItem("owl-playground-local-sample");
|
||||||
|
if (localSample) {
|
||||||
|
const { js, css, xml } = JSON.parse(localSample);
|
||||||
|
result.unshift({
|
||||||
|
description: "Local Storage Code",
|
||||||
|
code: js,
|
||||||
|
xml,
|
||||||
|
css
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveLocalSample(js, css, xml) {
|
||||||
|
const str = JSON.stringify({ js, css, xml });
|
||||||
|
localStorage.setItem("owl-playground-local-sample", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteLocalSample() {
|
||||||
|
localStorage.removeItem("owl-playground-local-sample");
|
||||||
|
}
|
||||||
|
|
||||||
|
function useSamples() {
|
||||||
|
const samples = loadSamples();
|
||||||
|
const component = owl.Component._current;
|
||||||
|
let interval;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const state = component.state;
|
||||||
|
interval = setInterval(() => {
|
||||||
|
if (component.isDirty) {
|
||||||
|
saveLocalSample(state.js, state.css, state.xml);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
onWillUnmount(() => {
|
||||||
|
clearInterval(interval);
|
||||||
|
});
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Tabbed editor
|
// Tabbed editor
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -157,13 +202,14 @@ class TabbedEditor extends owl.Component {
|
|||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
this.state = useState({
|
this.state = useState({
|
||||||
currentTab: props.js ? "js" : props.xml ? "xml" : "css"
|
currentTab: props.js !== false ? "js" : props.xml ? "xml" : "css"
|
||||||
});
|
});
|
||||||
this.setTab = owl.utils.debounce(this.setTab, 250, true);
|
this.setTab = owl.utils.debounce(this.setTab, 250, true);
|
||||||
|
|
||||||
this.sessions = {};
|
this.sessions = {};
|
||||||
this._setupSessions(props);
|
this._setupSessions(props);
|
||||||
this.editorNode = useRef("editor");
|
this.editorNode = useRef("editor");
|
||||||
|
this._updateCode = this._updateCode.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -175,18 +221,14 @@ class TabbedEditor extends owl.Component {
|
|||||||
this.editor.setSession(this.sessions[this.state.currentTab]);
|
this.editor.setSession(this.sessions[this.state.currentTab]);
|
||||||
const tabSize = this.state.currentTab === "xml" ? 2 : 4;
|
const tabSize = this.state.currentTab === "xml" ? 2 : 4;
|
||||||
this.editor.session.setOption("tabSize", tabSize);
|
this.editor.session.setOption("tabSize", tabSize);
|
||||||
this.editor.on("blur", () => {
|
this.editor.on("blur", this._updateCode);
|
||||||
const editorValue = this.editor.getValue();
|
this.interval = setInterval(this._updateCode, 3000);
|
||||||
const propsValue = this.props[this.state.currentTab];
|
|
||||||
if (editorValue !== propsValue) {
|
|
||||||
this.trigger("updateCode", {
|
|
||||||
type: this.state.currentTab,
|
|
||||||
value: editorValue
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
willUnmount() {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
this.editor.off("blur", this._updateCode);
|
||||||
|
}
|
||||||
willUpdateProps(nextProps) {
|
willUpdateProps(nextProps) {
|
||||||
this._setupSessions(nextProps);
|
this._setupSessions(nextProps);
|
||||||
}
|
}
|
||||||
@@ -195,13 +237,15 @@ class TabbedEditor extends owl.Component {
|
|||||||
const session = this.sessions[this.state.currentTab];
|
const session = this.sessions[this.state.currentTab];
|
||||||
let content = this.props[this.state.currentTab];
|
let content = this.props[this.state.currentTab];
|
||||||
if (content === false) {
|
if (content === false) {
|
||||||
const tab = this.props.js ? "js" : this.props.xml ? "xml" : "css";
|
const tab = this.props.js !== false ? "js" : this.props.xml ? "xml" : "css";
|
||||||
content = this.props[tab];
|
content = this.props[tab];
|
||||||
this.state.currentTab = tab;
|
this.state.currentTab = tab;
|
||||||
}
|
}
|
||||||
session.setValue(content, -1);
|
if (this.editor.getValue() !== content) {
|
||||||
this.editor.setSession(session);
|
session.setValue(content, -1);
|
||||||
this.editor.resize();
|
this.editor.setSession(session);
|
||||||
|
this.editor.resize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTab(tab) {
|
setTab(tab) {
|
||||||
@@ -230,7 +274,7 @@ class TabbedEditor extends owl.Component {
|
|||||||
|
|
||||||
_setupSessions(props) {
|
_setupSessions(props) {
|
||||||
for (let tab of ["js", "xml", "css"]) {
|
for (let tab of ["js", "xml", "css"]) {
|
||||||
if (props[tab] && !this.sessions[tab]) {
|
if (props[tab] !== false && !this.sessions[tab]) {
|
||||||
this.sessions[tab] = new ace.EditSession(props[tab], MODES[tab]);
|
this.sessions[tab] = new ace.EditSession(props[tab], MODES[tab]);
|
||||||
this.sessions[tab].setOption("useWorker", false);
|
this.sessions[tab].setOption("useWorker", false);
|
||||||
const tabSize = tab === "xml" ? 2 : 4;
|
const tabSize = tab === "xml" ? 2 : 4;
|
||||||
@@ -239,6 +283,17 @@ class TabbedEditor extends owl.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateCode() {
|
||||||
|
const editorValue = this.editor.getValue();
|
||||||
|
const propsValue = this.props[this.state.currentTab];
|
||||||
|
if (editorValue !== propsValue) {
|
||||||
|
this.trigger("updateCode", {
|
||||||
|
type: this.state.currentTab,
|
||||||
|
value: editorValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -248,12 +303,13 @@ class App extends owl.Component {
|
|||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
super(...args);
|
super(...args);
|
||||||
this.version = owl.__info__.version;
|
this.version = owl.__info__.version;
|
||||||
this.SAMPLES = SAMPLES;
|
this.SAMPLES = useSamples();
|
||||||
|
this.isDirty = false;
|
||||||
|
|
||||||
this.state = useState({
|
this.state = useState({
|
||||||
js: SAMPLES[0].code,
|
js: this.SAMPLES[0].code,
|
||||||
css: SAMPLES[0].css || "",
|
css: this.SAMPLES[0].css || "",
|
||||||
xml: SAMPLES[0].xml || DEFAULT_XML,
|
xml: this.SAMPLES[0].xml || DEFAULT_XML,
|
||||||
error: false,
|
error: false,
|
||||||
displayWelcome: true,
|
displayWelcome: true,
|
||||||
splitLayout: true,
|
splitLayout: true,
|
||||||
@@ -302,10 +358,12 @@ class App extends owl.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSample(ev) {
|
setSample(ev) {
|
||||||
const sample = SAMPLES.find(s => s.description === ev.target.value);
|
const sample = this.SAMPLES.find(s => s.description === ev.target.value);
|
||||||
this.state.js = sample.code;
|
this.state.js = sample.code;
|
||||||
this.state.css = sample.css || "";
|
this.state.css = sample.css || "";
|
||||||
this.state.xml = sample.xml || DEFAULT_XML;
|
this.state.xml = sample.xml || DEFAULT_XML;
|
||||||
|
deleteLocalSample();
|
||||||
|
this.isDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get leftPaneStyle() {
|
get leftPaneStyle() {
|
||||||
@@ -338,7 +396,10 @@ class App extends owl.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
updateCode(ev) {
|
updateCode(ev) {
|
||||||
this.state[ev.detail.type] = ev.detail.value;
|
if (this.state[ev.detail.type] !== ev.detail.value) {
|
||||||
|
this.state[ev.detail.type] = ev.detail.value;
|
||||||
|
this.isDirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
toggleLayout() {
|
toggleLayout() {
|
||||||
this.state.splitLayout = !this.state.splitLayout;
|
this.state.splitLayout = !this.state.splitLayout;
|
||||||
@@ -363,7 +424,6 @@ class App extends owl.Component {
|
|||||||
}
|
}
|
||||||
App.components = { TabbedEditor };
|
App.components = { TabbedEditor };
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Application initialization
|
// Application initialization
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user