Add new extension API to allow extension to load and save data in preferences.json

This commit is contained in:
Luc
2024-06-13 18:46:14 +08:00
parent bf315ecbb3
commit 9df6af0ba2
15 changed files with 192 additions and 44 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,45 +1,45 @@
<script type="text/javascript">
function sendMessage(msg){
window.parent.postMessage(msg, '*');
}
function onclickBtn(){
const selectElement = document.getElementById('request_id');
id_requested = selectElement.value
sendMessage({type:'capabilities', target:'webui', id:document.getElementById('request_id').value,});
function sendMessage(msg) {
window.parent.postMessage(msg, '*');
}
function processMessage(eventMsg){
if (eventMsg.data.type && (!eventMsg.data.id||eventMsg.data.id==document.getElementById('request_id').value)){
if (eventMsg.data.type=="capabilities"){
const line = eventMsg.data.content
const resultPanel = document.getElementById("output");
let res = JSON.stringify(line.response," ","\n")
while (res.includes("\n\n")) {
res = res.replace("\n\n", "\n");
}
resultPanel.innerHTML = res;
}
function onclickBtn() {
const selectElement = document.getElementById('request_id');
id_requested = selectElement.value
sendMessage({ type: 'capabilities', target: 'webui', id: document.getElementById('request_id').value, });
}
function processMessage(eventMsg) {
if (eventMsg.data.type && (!eventMsg.data.id || eventMsg.data.id == document.getElementById('request_id').value)) {
if (eventMsg.data.type == "capabilities") {
const line = eventMsg.data.content
const resultPanel = document.getElementById("output");
let res = JSON.stringify(line.response, " ", "\n")
while (res.includes("\n\n")) {
res = res.replace("\n\n", "\n");
}
resultPanel.innerHTML = res;
}
}
}
window.onload = (event) => {
window.addEventListener("message", processMessage, false);
}
</script>
<div class="container">
<select id="request_id" class="form-select column">
<option value="connection">connection</option>
<option value="features">features</option>
<option value="interface">interface</option>
<option value="settings">settings</option>
</select>
<button class="btn m-1" onclick="onclickBtn();">Capabilities</button>
<pre class="container m-2" id="output">
<select id="request_id" class="form-select column">
<option value="connection">connection</option>
<option value="features">features</option>
<option value="interface">interface</option>
<option value="settings">settings</option>
<option value="extensions">extensions</option>
</select>
<button class="btn m-1" onclick="onclickBtn();">Capabilities</button>
<pre class="container m-2" id="output">
</pre>
</div>
</div>

View File

@@ -0,0 +1,45 @@
<script type="text/javascript">
function sendMessage(msg) {
window.parent.postMessage(msg, '*');
}
function onclickBtn() {
const contentTxt = "{'" + document.getElementById('value_name').value + "':'" + document.getElementById('value_data').value + "'}"
sendMessage({ type: 'extensionsData', target: 'webui', id: document.getElementById('extension_name').value, content: contentTxt });
}
function processMessage(eventMsg) {
if (eventMsg.data.type) {
if (eventMsg.data.type == "extensionsData") {
const line = eventMsg.data.content
const resultPanel = document.getElementById("output");
let res = JSON.stringify(line.response, " ", "\n")
while (res.includes("\n\n")) {
res = res.replace("\n\n", "\n");
}
resultPanel.innerHTML = res;
}
}
}
window.onload = (event) => {
window.addEventListener("message", processMessage, false);
}
</script>
<div class="container">
<div class="form-group">
<label class="form-label" for="extension_name">Extension Name:</label><input class="form-input" id="extension_name"
type="text" value="myextension">
<label class="form-label" for="value_name">Value Name:</label><input class="form-input" id="value_name" type="text"
value="xmax">
<label class="form-label" for="value_data">Value:</label><input class="form-input" id="value_data" type="text"
value="100">
<button class="btn m-1" onclick="onclickBtn();">Save</button>
</div>
<div id="output"></div>
</div>

View File

@@ -24,7 +24,10 @@ import { machineSettings, iconsTarget } from "../targets"
import { ConnectionContainer } from "./connection"
import { MainContainer } from "./main"
import { useUiContext, useUiContextFn } from "../contexts/UiContext"
import { useSettingsContext } from "../contexts/SettingsContext"
import {
useSettingsContext,
useSettingsContextFn,
} from "../contexts/SettingsContext"
import { useSettings, useHttpQueue } from "../hooks"
import { useEffect } from "preact/hooks"
import { showLogin, showKeepConnected, showModal } from "../components/Modal"
@@ -65,8 +68,12 @@ const ViewContainer = () => {
const ContentContainer = () => {
let displayIcon = {}
const { getConnectionSettings, getInterfaceSettings } = useSettings()
const { connectionSettings, interfaceSettings, featuresSettings } =
useSettingsContext()
const {
connectionSettings,
interfaceSettings,
featuresSettings,
extensionsSettings,
} = useSettingsContext()
const { createNewRequest } = useHttpQueue()
const { toasts, modals } = useUiContext()
const iconsList = { ...iconsTarget, ...iconsFeather }
@@ -381,7 +388,6 @@ const ContentContainer = () => {
}
break
case "icon":
console.log(eventMsg.data.id)
const iconToSend = iconsFeather[eventMsg.data.id]
//Temporary DOM
const tempElement = document.createElement("div")
@@ -391,7 +397,6 @@ const ContentContainer = () => {
const iconSvgString = tempElement.firstChild.outerHTML
//Delete the temporary DOM
tempElement.remove()
console.log(iconSvgString)
dispatchToExtensions(
"icon",
@@ -401,35 +406,128 @@ const ContentContainer = () => {
},
eventMsg.data.id
)
break
case "extensionsData":
//Get extension name
const section = eventMsg.data.id
//Get extensions settings
const data = eventMsg.data.content
//Some sanity check
if (!extensionsSettings.current.extensions) {
extensionsSettings.current.extensions = {}
}
if (!extensionsSettings.current.extensions[section]) {
extensionsSettings.current.extensions[section] = {}
}
//Update the settings
//Note: it will overwrite the whole section
extensionsSettings.current.extensions[section] = data
//now stringify and save
const preferencestosave = JSON.stringify(
extensionsSettings.current,
null,
" "
)
//Create a blob
const blob = new Blob([preferencestosave], {
type: "application/json",
})
//Create a file
const preferencesFileName =
useSettingsContextFn.getValue("HostUploadPath") +
"preferences.json"
const formDataExtensions = new FormData()
const file_to_save = new File([blob], preferencesFileName)
formDataExtensions.append(
"path",
useSettingsContextFn.getValue("HostUploadPath")
)
formDataExtensions.append("creatPath", "true")
formDataExtensions.append(
preferencesFileName + "S",
preferencestosave.length
)
formDataExtensions.append(
"myfiles",
file_to_save,
preferencesFileName
)
//Send the file
createNewRequest(
espHttpURL(useSettingsContextFn.getValue("HostTarget")),
{
method: "POST",
id: "preferences",
body: formDataExtensions,
},
{
onSuccess: (result) => {
toasts.addToast({
content: T("S62"),
type: "success",
})
dispatchToExtensions(
"extensionsData",
{
response: { status: "success" },
initiator: eventMsg.data,
},
eventMsg.data.id
)
},
onFail: (error) => {
toasts.addToast({
content: T("S44"),
type: "Error",
})
dispatchToExtensions(
"extensionsData",
{
response: { status: "error" },
initiator: eventMsg.data,
},
eventMsg.data.id
)
},
}
)
break
case "capabilities":
let response = {}
switch (eventMsg.data.id) {
case "connection":
console.log(connectionSettings.current)
response = JSON.parse(
JSON.stringify(connectionSettings.current)
)
break
case "settings":
console.log(machineSettings)
response = JSON.parse(
JSON.stringify(machineSettings)
)
break
break
case "interface":
console.log(interfaceSettings.current)
response = JSON.parse(
JSON.stringify(interfaceSettings.current)
)
break
case "features":
console.log(featuresSettings.current)
response = JSON.parse(
JSON.stringify(featuresSettings.current)
)
break
case "extensions":
if (extensionsSettings.current.extensions) {
response = JSON.parse(
JSON.stringify(
extensionsSettings.current.extensions
)
)
} else {
response = "{}"
}
break
default:
response = {}
}

View File

@@ -17,7 +17,7 @@
*/
import { h } from "preact"
import { webUIbuild } from "../../targets"
export const webUIversion = "3.0.0-a61"
export const webUIversion = "3.0.0-a62"
export const Esp3dVersion = () => (
<span>
{webUIversion}.{webUIbuild}

View File

@@ -34,6 +34,7 @@ const SettingsContextProvider = ({ children }) => {
const interfaceValues = useRef({})
const connectionValues = useRef({})
const featuresValues = useRef({})
const extensionsValues = useRef({})
const pollingInterval = useRef([])
useSettingsContextFn.getValue = (val) => connectionValues.current[val]
@@ -71,6 +72,7 @@ const SettingsContextProvider = ({ children }) => {
interfaceSettings: interfaceValues,
connectionSettings: connectionValues,
featuresSettings: featuresValues,
extensionsSettings: extensionsValues,
activity: { startPolling, stopPolling },
}

View File

@@ -57,7 +57,7 @@ const useSettings = () => {
const { createNewRequest } = useHttpQueue()
const { toasts, modals, connection, uisettings } = useUiContext()
const { processData } = useTargetContextFn
const { interfaceSettings, connectionSettings, activity } =
const { interfaceSettings, connectionSettings, extensionsSettings, activity } =
useSettingsContext()
const { defaultRoute, setActiveRoute } = useRouterContext()
const sendCommand = (cmd, id) => {
@@ -379,6 +379,7 @@ const useSettings = () => {
{
onSuccess: (result) => {
const jsonResult = JSON.parse(result)
extensionsSettings.current =JSON.parse(JSON.stringify(jsonResult))
const [preferences, haserrors] = importPreferences(
defaultPreferences,
jsonResult

View File

@@ -47,7 +47,7 @@ const InterfaceTab = () => {
const { toasts, modals, connection } = useUiContext()
const { createNewRequest, abortRequest } = useHttpQueue()
const { getInterfaceSettings } = useSettings()
const { interfaceSettings, connectionSettings } = useSettingsContext()
const { interfaceSettings, connectionSettings,extensionsSettings } = useSettingsContext()
const [isLoading, setIsLoading] = useState(false)
const [showSave, setShowSave] = useState(true)
const inputFile = useRef(null)
@@ -304,8 +304,10 @@ const InterfaceTab = () => {
}
const SaveSettings = () => {
const settings_to_save = exportPreferences(interfaceSettings.current, false)
settings_to_save.extensions=extensionsSettings.current.extensions
const preferencestosave = JSON.stringify(
exportPreferences(interfaceSettings.current, false),
settings_to_save,
null,
" "
)