diff --git a/WelsonJS.Augmented/WelsonJS.Launcher/editor.html b/WelsonJS.Augmented/WelsonJS.Launcher/editor.html
index 9a72022..f04f2c6 100644
--- a/WelsonJS.Augmented/WelsonJS.Launcher/editor.html
+++ b/WelsonJS.Augmented/WelsonJS.Launcher/editor.html
@@ -28,6 +28,10 @@
#editor {
flex: 3;
}
+
+ #mapView {
+ flex: 3;
+ }
#promptEditor {
flex: 1;
@@ -60,6 +64,7 @@
}
};
+
@@ -103,7 +108,8 @@
loadResource("http://localhost:3000/ajax/libs/metroui/dev/lib/metro.css", "text/css", "sha384-4XgOiXH2ZMaWt5s5B35yKi7EAOabhZvx7wO8Jr71q2vZ+uONdRza/6CsK2kpyocd"),
loadResource("http://localhost:3000/ajax/libs/metroui/dev/lib/icons.css", "text/css", "sha384-FuLND994etg+RtnpPSPMyNBvL+fEz+xGhbN61WUWuDEeZ+wJzcQ8SGqAMuI5hWrt"),
loadResource("http://localhost:3000/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.css", "text/css", "sha384-06yHXpYRlHEPaR4AS0fB/W+lMN09Zh5e1XMtfkNQdHV38OlhfkOEW5M+pCj3QskC"),
- loadResource("http://localhost:3000/ajax/libs/jsoneditor/10.1.3/jsoneditor.min.css", "text/css", "sha384-cj1rYBc4/dVYAknZMTkVCDRL6Knzugf32igVqsuFW0iRWFHKH8Ci8+ekC8gNsFZ+")
+ loadResource("http://localhost:3000/ajax/libs/jsoneditor/10.1.3/jsoneditor.min.css", "text/css", "sha384-cj1rYBc4/dVYAknZMTkVCDRL6Knzugf32igVqsuFW0iRWFHKH8Ci8+ekC8gNsFZ+"),
+ loadResource("http://localhost:3000/ajax/libs/leaflet/1.9.4/leaflet.min.css", "text/css", "sha384-c6Rcwz4e4CITMbu/NBmnNS8yN2sC3cUElMEMfP3vqqKFp7GOYaaBBCqmaWBjmkjb")
]).then(() => {
const _e = React.createElement;
@@ -128,9 +134,9 @@
}
function RibbonMenu({
- onOpenFileClick, onSaveFileClick, onCopliotClick, onAzureAiClick,
+ onOpenFileClick, onSaveFileClick, onCopliotClick, onAzureCognitiveClick,
onSavePromptClick, onLoadPromptClick, onQueryWhoisClick, onQueryDnsClick,
- onQueryIpClick
+ onQueryIpClick, onMapClick
}) {
const fileButtons = [
{
@@ -147,9 +153,9 @@
}
];
- const aiButtons = [
+ const cognitiveToolsButtons = [
{ id: 'btnCopilot', icon: 'mif-rocket', caption: 'Copilot', onClick: onCopliotClick },
- { id: 'btnAzureAi', icon: 'mif-rocket', caption: 'Azure AI', onClick: onAzureAiClick },
+ { id: 'btnAzureCognitive', icon: 'mif-rocket', caption: 'Azure', onClick: onAzureCognitiveClick },
{ id: 'btnSavePrompt', icon: 'mif-floppy-disks', caption: 'Save', onClick: onSavePromptClick },
{ id: 'btnLoadPrompt', icon: 'mif-file-upload', caption: 'Load', onClick: onLoadPromptClick }
];
@@ -157,7 +163,8 @@
const networkToolsButtons = [
{ id: 'btnWhois', icon: 'mif-earth', caption: 'Whois', onClick: onQueryWhoisClick },
{ id: 'btnQueryDns', icon: 'mif-earth', caption: 'DNS', onClick: onQueryDnsClick },
- { id: 'btnQueryIp', icon: 'mif-user-secret', caption: 'IP', onClick: onQueryIpClick }
+ { id: 'btnQueryIp', icon: 'mif-user-secret', caption: 'IP', onClick: onQueryIpClick },
+ { id: 'btnMap', icon: 'mif-rocket', caption: 'Map', onClick: onMapClick }
];
return _e(
@@ -170,14 +177,14 @@
_e('div', { className: 'content-holder' },
_e('div', { className: 'section active', id: 'editor-tab' },
_e(Group, { title: 'File', buttons: fileButtons }),
- _e(Group, { title: 'Generative AI', buttons: aiButtons }),
- _e(Group, { title: 'Network tools', buttons: networkToolsButtons })
+ _e(Group, { title: 'Cognitive Tools (AI)', buttons: cognitiveToolsButtons }),
+ _e(Group, { title: 'Network Tools', buttons: networkToolsButtons })
)
)
);
}
- function Editor({ editorRef }) {
+ function Editor({ editorRef, visible }) {
const containerRef = React.useRef(null);
const getSuggestions = (word, range) => axios.get(`/completion/${encodeURIComponent(word)}`)
@@ -232,6 +239,11 @@
editorRef.current = instance;
});
}, []);
+
+ React.useEffect(() => {
+ // toggle the display style attribute
+ containerRef.current.style.display = (visible ? "" : "none");
+ }, [visible]);
return _e('div', { id: 'editor', ref: containerRef });
}
@@ -281,6 +293,64 @@
return _e('div', { id: 'promptEditor', ref: containerRef });
}
+
+ function MapView({ mapViewRef, visible }) {
+ const containerRef = React.useRef(null);
+
+ // init once
+ React.useEffect(() => {
+ if (!containerRef.current)
+ return;
+
+ if (typeof L === "undefined" || !L || !L.map) {
+ console.error("[MapView] Leaflet (L) is not loaded.");
+ return;
+ }
+
+ if (mapViewRef && mapViewRef.current && mapViewRef.current._leaflet_id)
+ return;
+
+ const map = L.map(containerRef.current, {
+ zoomControl: true,
+ attributionControl: true
+ }).setView([37.5665, 126.9780], 12);
+
+ L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
+ maxZoom: 19,
+ attribution: '© OpenStreetMap contributors'
+ }).addTo(map);
+
+ if (mapViewRef)
+ mapViewRef.current = map;
+
+ return function () {
+ try {
+ if (mapViewRef && mapViewRef.current === map)
+ mapViewRef.current = null;
+
+ map.remove();
+ } catch (e) {}
+ };
+ }, []);
+
+ // handle show/hide toggles
+ React.useEffect(() => {
+ // when becoming visible, leaflet needs a resize recalculation
+ const map = mapViewRef ? mapViewRef.current : null;
+ if (!map || !map.invalidateSize)
+ return;
+
+ // toggle the display style attribute
+ containerRef.current.style.display = (visible ? "block" : "none");
+
+ // defer until after layout/display change
+ setTimeout(function () {
+ try { map.invalidateSize(); } catch (e) {}
+ }, 0);
+ }, [visible]);
+
+ return _e('div', { id: 'mapView', ref: containerRef });
+ }
function App() {
const editorRef = React.useRef(null);
@@ -288,6 +358,8 @@
const settingsRef = React.useRef({});
const fileNameRef = React.useRef('sayhello.js');
const promptMessagesRef = React.useRef([]);
+ const mapViewRef = React.useRef(null);
+ const [showMap, setShowMap] = React.useState(false);
const fetchSettings = () => axios.get(`/settings`)
.then(response => {
@@ -472,7 +544,7 @@
}
};
- const sendMessageToAzureAi = () => {
+ const sendMessageToAzureCognitive = () => {
const promptMessage = prompt("Enter a prompt message:", '');
if (!promptMessage || promptMessage.trim() == '') {
alert("A prompt message is required.");
@@ -647,6 +719,10 @@
appendTextToEditor(`\n// Failed to query the IP: ${error.message}`);
});
};
+
+ function toggleMap() {
+ setShowMap(v => !v);
+ }
React.useEffect(() => {
window.addEventListener('resize', () => {
@@ -662,15 +738,17 @@
onOpenFileClick: openFile,
onSaveFileClick: saveFile,
onCopliotClick: sendMessageToCopilot,
- onAzureAiClick: sendMessageToAzureAi,
+ onAzureCognitiveClick: sendMessageToAzureCognitive,
onSavePromptClick: savePromptMessages,
onLoadPromptClick: loadPromptMessages,
onQueryWhoisClick: queryWhois,
onQueryDnsClick: queryDns,
- onQueryIpClick: queryIp
+ onQueryIpClick: queryIp,
+ onMapClick: toggleMap
}),
_e('div', { id: 'container' },
- _e(Editor, { editorRef }),
+ _e(Editor, { editorRef: editorRef, visible: !showMap }),
+ _e(MapView, { mapViewRef: mapViewRef, visible: showMap }),
_e(PromptEditor, { promptEditorRef, promptMessagesRef })
),
_e('div', { className: 'banner' }, _e('a', { href: 'https://github.com/gnh1201/welsonjs' }, '❤️ Contribute this project')),