diff --git a/public/index.html b/public/index.html index fa9513519..7f6368cee 100644 --- a/public/index.html +++ b/public/index.html @@ -4921,6 +4921,6 @@ - + diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index c161c2577..fd8820380 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -1,21 +1,180 @@ + const settings_html = ` -
-
+
+

Extensions

- +
+ +

Auto-connect

+
+
Not connected
+
+

Active extensions

+
    +
+
-` -const urlKey = 'extensions_url'; -const defaultUrl = "http://localhost:5100"; +`; -$(document).ready(async function() { +const settings_style = ` + +`; + +const urlKey = 'extensions_url'; +const autoConnectKey = 'extensions_autoconnect'; +const defaultUrl = "http://localhost:5100"; +let connectedToApi = false; +let extensions = []; + +async function connectClickHandler() { + const baseUrl = $("#extensions_url").val(); + localStorage.setItem(urlKey, baseUrl); + await connectToApi(baseUrl); +} + +function autoConnectInputHandler() { + const value = $(this).prop('checked'); + localStorage.setItem(autoConnectKey, value.toString()); + + if (value && !connectedToApi) { + $("#extensions_connect").trigger('click'); + } +} + +async function connectToApi(baseUrl) { + const url = new URL(baseUrl); + url.pathname = '/api/extensions'; + const getExtensionsResult = await fetch(url, { method: 'GET' }); + + if (getExtensionsResult.ok) { + const data = await getExtensionsResult.json(); + extensions = data.extensions; + applyExtensions(baseUrl); + } + + updateStatus(getExtensionsResult.ok); +} + +function updateStatus(success) { + connectedToApi = success; + const _text = success ? 'Connected to API' : 'Could not connect to API'; + const _class = success ? 'success' : 'failed'; + $('#extensions_status').text(_text); + $('#extensions_status').attr('class', _class); + + if (success && extensions.length) { + $('#extensions_loaded').show(200); + $('#extensions_list').empty(); + + for (let extension of extensions) { + $('#extensions_list').append(`
  • ${extension.metadata.display_name}
  • `); + } + } +} + +function applyExtensions(baseUrl) { + const url = new URL(baseUrl); + + if (!Array.isArray(extensions) || extensions.length === 0) { + return; + } + + for (let extension of extensions) { + if (extension.metadata.js) { + url.pathname = `/api/script/${extension.name}`; + const src = url.toString(); + + if ($(`script[src="${src}"]`).length === 0) { + const script = document.createElement('script'); + script.type = 'module'; + script.src = src; + $('body').append(script); + } + + } + + if (extension.metadata.css) { + url.pathname = `/api/style/${extension.name}`; + const href = url.toString(); + + if ($(`link[href="${href}"]`).length === 0) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = href; + $('head').append(link); + } + } + } +} + +$(document).ready(async function () { const url = localStorage.getItem(urlKey) ?? defaultUrl; + const autoConnect = Boolean(localStorage.getItem(autoConnectKey)) ?? false; $('#rm_api_block').append(settings_html); + $('head').append(settings_style); $("#extensions_url").val(url); - $("#extensions_connect").on('click', function() { - const url = $("#extensions_url").val(); - localStorage.setItem(urlKey, url); - alert('click!'); - }); + $("#extensions_connect").on('click', connectClickHandler); + $("#extensions_autoconnect").on('input', autoConnectInputHandler); + $("#extensions_autoconnect").prop('checked', autoConnect).trigger('input'); }); \ No newline at end of file