Skip to content

Commit 8d3bc0c

Browse files
author
Yann Leflour
committed
prepare 1.1.5
1 parent a6209b3 commit 8d3bc0c

File tree

6 files changed

+78
-20
lines changed

6 files changed

+78
-20
lines changed

doc/setup-preview-url.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
- The preview url should accept a `filePath` query parameter
1717
- The preview page, should load the Component from the `filePath` query parameter dynamically and render it
18+
- The preview page should be able to take a screenshot of itself and send it back
19+
- It should listen for a `message` event in the shape of `{ action: 'take-screenshot', shapeid: string }`
20+
- It should respond using `window.parent.postMessage({ screenshot: data, shapeid: event.data.shapeid }, '*');`
21+
- If the screenshot is not sent back, after a timeout, a blank element will be rendered instead
22+
- See the [sveltekit instructions](./setup-preview-url/sveltekit.md) for an example
1823
- The preview page should have hot reloading / live reload enabled
1924
- The preview url should be added to `ui-sketcher.previewUrl` in settings.json without any query parameters (e.g. `http://localhost:3000/preview`)
2025

doc/setup-preview-url/sveltekit.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,61 @@
1010
File path: `src/routes/(preview)/preview/+page.svelte`
1111

1212
```svelte
13+
<script context="module" lang="ts">
14+
declare const html2canvas: (element: HTMLElement, options?: any) => Promise<HTMLCanvasElement>;
15+
</script>
16+
1317
<script lang="ts">
18+
import { onMount } from 'svelte';
1419
import { page } from '$app/stores';
1520
1621
$: componentPath = '../../../../' + $page.url.searchParams.get('filePath');
1722
$: componentPromise = componentPath
1823
? import(/* @vite-ignore */ componentPath).then((data) => data.default)
1924
: null;
25+
26+
onMount(() => {
27+
console.debug('Listening for screenshot requests');
28+
window.addEventListener(
29+
'message',
30+
function (event) {
31+
if (event.data.action === 'take-screenshot' && event.data.shapeid) {
32+
html2canvas(document.body, {
33+
useCors: true,
34+
foreignObjectRendering: true,
35+
allowTaint: true,
36+
})
37+
.then(function (canvas) {
38+
const data = canvas.toDataURL('image/png');
39+
// console.debug('Sending screenshot to parent', data);
40+
window.parent.postMessage({ screenshot: data, shapeid: event.data.shapeid }, '*');
41+
})
42+
.catch((e) => {
43+
console.error(e);
44+
});
45+
}
46+
},
47+
false,
48+
);
49+
50+
// and prevent the user from pinch-zooming into the iframe
51+
document.body.addEventListener(
52+
'wheel',
53+
(e) => {
54+
if (!e.ctrlKey) return;
55+
e.preventDefault();
56+
},
57+
{ passive: false },
58+
);
59+
});
2060
</script>
2161
62+
<svelte:head>
63+
<script
64+
src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"
65+
></script>
66+
</svelte:head>
67+
2268
{#await componentPromise}
2369
<h1>Loading...</h1>
2470
{:then Component}
@@ -27,4 +73,5 @@ File path: `src/routes/(preview)/preview/+page.svelte`
2773
<h1>Error loading component</h1>
2874
<pre>{error.message}</pre>
2975
{/await}
76+
3077
```

ui-sketcher-extension/CHANGELOG.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,38 @@
11
# Change Log
22

3-
## [1.1.4] - 2023-26-09
3+
## [1.1.5] - 2023-11-28
4+
5+
### Changed
6+
7+
- Preview now requires the page to handle a window event and respond with a base64 screenshot. Please make sure to check the preview URL setup guide
8+
- The generated screenshot will now be included in the rendered result
9+
10+
## [1.1.4] - 2023-11-26
411

512
### Fixed
613

714
- Error when closing the panel manually and closing the file after
815

9-
## [1.1.3] - 2023-23-09
16+
## [1.1.3] - 2023-11-23
1017

1118
### Fixed
1219

1320
- Allow pasting images from clipboard
1421
- Allow embeddings from urls
1522

16-
## [1.1.2] - 2023-22-09
23+
## [1.1.2] - 2023-11-22
1724

1825
### Fixed
1926

2027
- Prevent panel unmount from deleting the extension's state
2128

22-
## [1.1.1] - 2023-22-09
29+
## [1.1.1] - 2023-11-22
2330

2431
### Added
2532

2633
- Preview iframe can now be interacted with
2734

28-
## [1.1.0] - 2023-22-09
35+
## [1.1.0] - 2023-11-22
2936

3037
### Added
3138

@@ -51,7 +58,7 @@
5158

5259
- `ui-sketcher.includeFileInPrompt` setting
5360

54-
## [1.0.5] - 2023-21-09
61+
## [1.0.5] - 2023-11-21
5562

5663
### Added
5764

ui-sketcher-extension/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"url": "https://github.com/pAIrprogio/vscode-ui-sketcher"
2121
},
2222
"license": "MIT",
23-
"version": "1.1.4",
23+
"version": "1.1.5",
2424
"icon": "images/icon.png",
2525
"engines": {
2626
"vscode": "^1.84.0"

ui-sketcher-extension/src/ui-sketcher-webview.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ export class UiSketcherWebview {
160160
switch (message.command) {
161161
case "tldraw:export":
162162
const { base64, imageTexts } = message.payload;
163+
// vscode.env.clipboard.writeText(base64); // Copies base64 to clipboard for debugging
163164
await this.createCompletion(base64, imageTexts);
164165
return;
165166
default:

ui-sketcher-webview/src/PreviewShape.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ export class PreviewShapeUtil extends BaseBoxShapeUtil<PreviewShape> {
4646
_ctx: SvgExportContext
4747
): SVGElement | Promise<SVGElement> {
4848
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
49-
// while screenshot is the same as the old one, keep waiting for a new one
50-
return new Promise((resolve, _) => {
51-
if (window === undefined) return resolve(g);
5249

50+
if (!this.iframeRef.current?.contentWindow) return g;
51+
52+
const contentWindow = this.iframeRef.current.contentWindow;
53+
54+
return new Promise((resolve, _) => {
5355
const windowListener = (event: MessageEvent) => {
5456
if (event.data.screenshot && event.data?.shapeid === shape.id) {
5557
const image = document.createElementNS(
@@ -61,8 +63,8 @@ export class PreviewShapeUtil extends BaseBoxShapeUtil<PreviewShape> {
6163
"href",
6264
event.data.screenshot
6365
);
64-
image.setAttribute("width", shape.props.w.toString());
65-
image.setAttribute("height", shape.props.h.toString());
66+
image.setAttribute("width", (shape.props.w * 2).toString());
67+
image.setAttribute("height", (shape.props.h * 2).toString());
6668
g.appendChild(image);
6769
window.removeEventListener("message", windowListener);
6870
clearTimeout(timeOut);
@@ -77,14 +79,10 @@ export class PreviewShapeUtil extends BaseBoxShapeUtil<PreviewShape> {
7779
window.addEventListener("message", windowListener);
7880
//request new screenshot
7981

80-
if (this.iframeRef.current?.contentWindow) {
81-
this.iframeRef.current.contentWindow.postMessage(
82-
{ action: "take-screenshot", shapeid: shape.id },
83-
"*"
84-
);
85-
} else {
86-
console.log("iframe not found or not accessible");
87-
}
82+
contentWindow.postMessage(
83+
{ action: "take-screenshot", shapeid: shape.id },
84+
"*"
85+
);
8886
});
8987
}
9088

0 commit comments

Comments
 (0)