ugly-app 0.1.143 → 0.1.144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/client/Screenshot.d.ts +3 -1
- package/dist/client/Screenshot.d.ts.map +1 -1
- package/dist/client/Screenshot.js +39 -2
- package/dist/client/Screenshot.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/version.ts +1 -1
- package/src/client/Screenshot.ts +41 -2
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.144";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Captures a screenshot of the current
|
|
2
|
+
* Captures a screenshot of the current tab as a base64-encoded PNG.
|
|
3
|
+
* Uses getDisplayMedia with preferCurrentTab for pixel-perfect capture.
|
|
4
|
+
* Falls back to html2canvas if getDisplayMedia is unavailable.
|
|
3
5
|
* Returns null if capture fails.
|
|
4
6
|
*/
|
|
5
7
|
export declare function captureScreenshot(): Promise<string | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Screenshot.d.ts","sourceRoot":"","sources":["../../src/client/Screenshot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Screenshot.d.ts","sourceRoot":"","sources":["../../src/client/Screenshot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+DhE"}
|
|
@@ -1,8 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Captures a screenshot of the current
|
|
2
|
+
* Captures a screenshot of the current tab as a base64-encoded PNG.
|
|
3
|
+
* Uses getDisplayMedia with preferCurrentTab for pixel-perfect capture.
|
|
4
|
+
* Falls back to html2canvas if getDisplayMedia is unavailable.
|
|
3
5
|
* Returns null if capture fails.
|
|
4
6
|
*/
|
|
5
7
|
export async function captureScreenshot() {
|
|
8
|
+
// Try native screen capture first (Chrome 104+)
|
|
9
|
+
try {
|
|
10
|
+
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
11
|
+
video: { displaySurface: 'browser' },
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
preferCurrentTab: true,
|
|
14
|
+
});
|
|
15
|
+
const track = stream.getVideoTracks()[0];
|
|
16
|
+
if (track) {
|
|
17
|
+
// Use a video element to grab a single frame
|
|
18
|
+
const video = document.createElement('video');
|
|
19
|
+
video.srcObject = stream;
|
|
20
|
+
video.muted = true;
|
|
21
|
+
await video.play();
|
|
22
|
+
// Wait one frame for the video to render
|
|
23
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
24
|
+
const canvas = document.createElement('canvas');
|
|
25
|
+
canvas.width = video.videoWidth;
|
|
26
|
+
canvas.height = video.videoHeight;
|
|
27
|
+
const ctx = canvas.getContext('2d');
|
|
28
|
+
if (ctx) {
|
|
29
|
+
ctx.drawImage(video, 0, 0);
|
|
30
|
+
track.stop();
|
|
31
|
+
video.srcObject = null;
|
|
32
|
+
return canvas.toDataURL('image/png').split(',')[1];
|
|
33
|
+
}
|
|
34
|
+
track.stop();
|
|
35
|
+
video.srcObject = null;
|
|
36
|
+
}
|
|
37
|
+
stream.getTracks().forEach((t) => t.stop());
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// getDisplayMedia not available or user denied — fall back to html2canvas
|
|
41
|
+
}
|
|
42
|
+
// Fallback: html2canvas
|
|
6
43
|
try {
|
|
7
44
|
const html2canvas = (await import('html2canvas')).default;
|
|
8
45
|
const canvas = await html2canvas(document.body, {
|
|
@@ -18,7 +55,7 @@ export async function captureScreenshot() {
|
|
|
18
55
|
windowHeight: window.innerHeight,
|
|
19
56
|
ignoreElements: (el) => el.getAttribute('data-id') === 'feedback-button',
|
|
20
57
|
});
|
|
21
|
-
return canvas.toDataURL('image/png').split(',')[1];
|
|
58
|
+
return canvas.toDataURL('image/png').split(',')[1];
|
|
22
59
|
}
|
|
23
60
|
catch (err) {
|
|
24
61
|
console.warn('[Screenshot] Capture failed:', err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Screenshot.js","sourceRoot":"","sources":["../../src/client/Screenshot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Screenshot.js","sourceRoot":"","sources":["../../src/client/Screenshot.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.144";
|
package/src/client/Screenshot.ts
CHANGED
|
@@ -1,8 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Captures a screenshot of the current
|
|
2
|
+
* Captures a screenshot of the current tab as a base64-encoded PNG.
|
|
3
|
+
* Uses getDisplayMedia with preferCurrentTab for pixel-perfect capture.
|
|
4
|
+
* Falls back to html2canvas if getDisplayMedia is unavailable.
|
|
3
5
|
* Returns null if capture fails.
|
|
4
6
|
*/
|
|
5
7
|
export async function captureScreenshot(): Promise<string | null> {
|
|
8
|
+
// Try native screen capture first (Chrome 104+)
|
|
9
|
+
try {
|
|
10
|
+
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
11
|
+
video: { displaySurface: 'browser' },
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
preferCurrentTab: true,
|
|
14
|
+
} as DisplayMediaStreamOptions & { preferCurrentTab: boolean });
|
|
15
|
+
const track = stream.getVideoTracks()[0];
|
|
16
|
+
if (track) {
|
|
17
|
+
// Use a video element to grab a single frame
|
|
18
|
+
const video = document.createElement('video');
|
|
19
|
+
video.srcObject = stream;
|
|
20
|
+
video.muted = true;
|
|
21
|
+
await video.play();
|
|
22
|
+
|
|
23
|
+
// Wait one frame for the video to render
|
|
24
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
25
|
+
|
|
26
|
+
const canvas = document.createElement('canvas');
|
|
27
|
+
canvas.width = video.videoWidth;
|
|
28
|
+
canvas.height = video.videoHeight;
|
|
29
|
+
const ctx = canvas.getContext('2d');
|
|
30
|
+
if (ctx) {
|
|
31
|
+
ctx.drawImage(video, 0, 0);
|
|
32
|
+
track.stop();
|
|
33
|
+
video.srcObject = null;
|
|
34
|
+
return canvas.toDataURL('image/png').split(',')[1];
|
|
35
|
+
}
|
|
36
|
+
track.stop();
|
|
37
|
+
video.srcObject = null;
|
|
38
|
+
}
|
|
39
|
+
stream.getTracks().forEach((t) => t.stop());
|
|
40
|
+
} catch {
|
|
41
|
+
// getDisplayMedia not available or user denied — fall back to html2canvas
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Fallback: html2canvas
|
|
6
45
|
try {
|
|
7
46
|
const html2canvas = (await import('html2canvas')).default as unknown as (
|
|
8
47
|
element: HTMLElement,
|
|
@@ -23,7 +62,7 @@ export async function captureScreenshot(): Promise<string | null> {
|
|
|
23
62
|
ignoreElements: (el: Element) =>
|
|
24
63
|
el.getAttribute('data-id') === 'feedback-button',
|
|
25
64
|
});
|
|
26
|
-
return canvas.toDataURL('image/png').split(',')[1];
|
|
65
|
+
return canvas.toDataURL('image/png').split(',')[1];
|
|
27
66
|
} catch (err) {
|
|
28
67
|
console.warn('[Screenshot] Capture failed:', err);
|
|
29
68
|
return null;
|