Skip to content

Commit

Permalink
Progressing #20 #5 - exporting of maps.
Browse files Browse the repository at this point in the history
  • Loading branch information
damonsk committed Jan 11, 2024
1 parent c77ccb3 commit c55c815
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 40 deletions.
130 changes: 119 additions & 11 deletions extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,48 @@ import {
let client: LanguageClient;

function activate(context) {
const onDidExportAsSvg = async (svgMarkup) => {
console.log('[extension.ts] onDidExportAsSvg -- ');
const options = {
defaultUri: vscode.Uri.file('untitled.svg'),
};

const saveUri = await vscode.window.showSaveDialog(options);

if (saveUri) {
const fs = require('fs');
const path = saveUri.fsPath;

fs.writeFileSync(path, svgMarkup);

vscode.window.showInformationMessage(
`Wardley Map SVG file saved to ${path}`
);
}
};
const onDidExportAsPng = async (arrayBuffer) => {
console.log('[extension.ts] onDidExportAsPng -- ');

const options = {
defaultUri: vscode.Uri.file('untitled.png'),
};

const saveUri = await vscode.window.showSaveDialog(options);

if (saveUri) {
const fs = require('fs');
const path = saveUri.fsPath;

const buffer = Buffer.from(arrayBuffer);

fs.writeFileSync(path, buffer);

vscode.window.showInformationMessage(
`Wardley Map PNG file saved to ${path}`
);
}
};

let panelInstances = [];
console.log(
'Congratulations, your extension "' +
Expand Down Expand Up @@ -53,18 +95,26 @@ function activate(context) {
'vscode-wardley-maps.display-map',
function () {
const editor = vscode.window.activeTextEditor;

if (editor !== undefined) {
console.log(
'[extension.ts] vscode-wardley-maps.display-map -- ' +
editor.document.fileName
);
const mapFileName = editor.document.fileName;

panelInstances[editor.document.fileName] = new ViewLoader(
context,
editor,
editor.document.fileName
);
panelInstances[editor.document.fileName].setActiveEditor(editor);
if (panelInstances[mapFileName]) {
panelInstances[mapFileName].reveal(vscode.ViewColumn.Beside);
} else {
console.log(
'[extension.ts] vscode-wardley-maps.display-map -- ' + mapFileName
);

panelInstances[mapFileName] = new ViewLoader(
context,
editor,
mapFileName,
onDidExportAsSvg,
onDidExportAsPng
);
panelInstances[mapFileName].setActiveEditor(editor);
}
}
}
),
Expand All @@ -91,10 +141,68 @@ function activate(context) {
panelInstances[editor.document.fileName] = new ViewLoader(
context,
editor,
editor.document.fileName
editor.document.fileName,
onDidExportAsSvg,
onDidExportAsPng
);
panelInstances[editor.document.fileName].setActiveEditor(editor);
}
),
vscode.commands.registerCommand(
'vscode-wardley-maps.export-map-svg',
async function () {
const editor = vscode.window.activeTextEditor;

if (editor) {
console.log(
'[extension.ts] vscode-wardley-maps.export-map-svg -- ' +
editor.document.fileName
);

if (panelInstances[editor.document.fileName] != undefined) {
panelInstances[editor.document.fileName].postMessage(
'exportAsSvg',
'exportAsSvg'
);
} else {
vscode.window.showErrorMessage(
'Please make sure Map View has been rendered (Wardley Maps: Display Map).'
);
}
} else {
vscode.window.showErrorMessage(
'Please make sure Map Text document has focus.'
);
}
}
),
vscode.commands.registerCommand(
'vscode-wardley-maps.export-map-png',
async function () {
const editor = vscode.window.activeTextEditor;

if (editor) {
console.log(
'[extension.ts] vscode-wardley-maps.export-map-png -- ' +
editor.document.fileName
);

if (panelInstances[editor.document.fileName] != undefined) {
panelInstances[editor.document.fileName].postMessage(
'exportAsPng',
'exportAsPng'
);
} else {
vscode.window.showErrorMessage(
'Please make sure Map View has been rendered (Wardley Maps: Display Map).'
);
}
} else {
vscode.window.showErrorMessage(
'Please make sure Map Text document has focus.'
);
}
}
)
);

Expand Down
24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,23 @@
"activationEvents": [
"onCommand:vscode-wardley-maps.display-map",
"onCommand:vscode-wardley-maps.example-map",
"onCommand:vscode-wardley-maps.export-map-svg",
"onLanguage:wardleymap"
],
"main": "./extension/out/extension.js",
"contributes": {
"webviews": {
"contentSecurityPolicy": {
"default-src": "'none'",
"connect-src": "vscode-resource:",
"img-src": [
"data:",
"data:image/svg+xml",
"https://*.vscode-cdn.net",
"https:"
]
}
},
"configuration": {
"type": "object",
"title": "Example configuration",
Expand Down Expand Up @@ -63,6 +76,16 @@
"command": "vscode-wardley-maps.example-map",
"title": "Example Map",
"category": "Wardley Maps"
},
{
"command": "vscode-wardley-maps.export-map-svg",
"title": "Export Map as SVG",
"category": "Wardley Maps"
},
{
"command": "vscode-wardley-maps.export-map-png",
"title": "Export Map as PNG",
"category": "Wardley Maps"
}
],
"languages": [
Expand Down Expand Up @@ -156,6 +179,7 @@
"bootstrap": "^4.5.3",
"concat-map": "^0.0.2",
"core-js": "^3.34.0",
"dom-to-image-more": "^3.2.0",
"lodash.merge": "^4.6.2",
"prop-types": "^15.8.1",
"react": "18.2.0",
Expand Down
79 changes: 60 additions & 19 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { Converter } from 'wmlandscape';
import { ModKeyPressedProvider } from 'wmlandscape';
import { FeatureSwitchesProvider } from 'wmlandscape';
import { FeatureSwitches } from 'wmlandscape';
import domtoimage from 'dom-to-image-more';

const App = () => {
let vscodeFeatureSwitches = {
...FeatureSwitches.featureSwitches,
showToggleFullscreen: false,
};

console.log({ vscodeFeatureSwitches, ...FeatureSwitches.featureSwitches });

const [mapText, setMapText] = useState('');
const [mapTitle, setMapTitle] = useState('Untitled Map');
const [mapComponents, setMapComponents] = useState([]);
Expand Down Expand Up @@ -118,7 +117,61 @@ const App = () => {
}
};

React.useEffect(() => {
function exportToPng() {
const createData = () =>
new Promise((resolve) => {
const mapNode = mapRef.current; // Make sure mapRef.current is a valid DOM node
domtoimage
.toBlob(mapNode)
.then((blob) => {
const reader = new FileReader();
reader.onloadend = () => {
const arrayBuffer = reader.result;
// Send the arrayBuffer back to the extension
window.postMessage({
command: 'didExportAsPng',
val: arrayBuffer,
});
resolve();
};
reader.readAsArrayBuffer(blob);
})
.catch((error) => {
console.error('Error generating image:', error);
resolve(null);
});
});

createData();
}

function exportToSvg() {
const svgMapText = mapRef.current
.getElementsByTagName('svg')[0]
.outerHTML.replace(/ /g, ' ');
window.postMessage({
command: 'didExportAsSvg',
val: `<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">${svgMapText}`,
});
}

useEffect(() => {
const messageHandler = (e) => {
const message = e.data;
console.log('[[App.js::messageHandler', message);
switch (message.command) {
case 'text':
mutateMapTextIn(message.val);
break;
case 'exportAsSvg':
exportToSvg();
break;
case 'exportAsPng':
exportToPng();
break;
}
};

const debouncedHandleResize = debounce(() => {
setMapDimensions({ width: getWidth(), height: getHeight() });
}, 1000);
Expand All @@ -127,16 +180,18 @@ const App = () => {
setMapDimensions({ width: getWidth(), height: getHeight() });
};

window.addEventListener('message', (e) => messageHandler(e));
window.addEventListener('resize', debouncedHandleResize);
window.addEventListener('load', initialLoad);

return function cleanup() {
window.removeEventListener('message', (e) => messageHandler(e));
window.removeEventListener('resize', debouncedHandleResize);
window.removeEventListener('load', initialLoad);
};
});
}, []);

React.useEffect(() => {
useEffect(() => {
try {
var r = new Converter(vscodeFeatureSwitches).parse(mapText);
setMapTitle(r.title);
Expand Down Expand Up @@ -173,20 +228,6 @@ const App = () => {
}, [highlightLine]);

useEffect(() => {
const textChangeBinding = (e) => {
const message = e.data;
switch (message.command) {
case 'text':
mutateMapTextIn(message.val);
break;
}
};
window.addEventListener('message', (e) => textChangeBinding(e));
return () =>
window.removeEventListener('message', (e) => textChangeBinding(e));
}, [mutateMapTextIn]);

React.useEffect(() => {
switch (mapStyle) {
case 'colour':
case 'color':
Expand Down
Loading

0 comments on commit c55c815

Please sign in to comment.