@loupekit/sdk 0.10.0 → 0.10.1-next.42
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/index.global.js +71 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +71 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2428,6 +2428,7 @@ var HttpAdapter = class {
|
|
|
2428
2428
|
};
|
|
2429
2429
|
|
|
2430
2430
|
// src/app.ts
|
|
2431
|
+
var SDK_VERSION = true ? "0.10.1" : "dev";
|
|
2431
2432
|
var DOCK_MODES = ["left", "right", "bottom", "float"];
|
|
2432
2433
|
var RECORD_MAX_MS = 2e4;
|
|
2433
2434
|
var MAX_FILES = 10;
|
|
@@ -2441,11 +2442,23 @@ function hash(s) {
|
|
|
2441
2442
|
}
|
|
2442
2443
|
function isTouchDevice() {
|
|
2443
2444
|
try {
|
|
2444
|
-
|
|
2445
|
+
if (window.matchMedia("(pointer: coarse)").matches) return true;
|
|
2446
|
+
if (window.matchMedia("(hover: none)").matches) return true;
|
|
2447
|
+
} catch {
|
|
2448
|
+
}
|
|
2449
|
+
if (typeof navigator !== "undefined" && (navigator.maxTouchPoints ?? 0) > 0) return true;
|
|
2450
|
+
return typeof window !== "undefined" && "ontouchstart" in window;
|
|
2451
|
+
}
|
|
2452
|
+
function coarsePointer() {
|
|
2453
|
+
try {
|
|
2454
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
2445
2455
|
} catch {
|
|
2446
2456
|
return false;
|
|
2447
2457
|
}
|
|
2448
2458
|
}
|
|
2459
|
+
function canShareScreen() {
|
|
2460
|
+
return typeof navigator.mediaDevices?.getDisplayMedia === "function";
|
|
2461
|
+
}
|
|
2449
2462
|
function dataUrlToFile(dataUrl, name) {
|
|
2450
2463
|
const m = /^data:([^;,]+)(;base64)?,([\s\S]*)$/.exec(dataUrl);
|
|
2451
2464
|
if (!m) return null;
|
|
@@ -2825,10 +2838,18 @@ var LoupeApp = class {
|
|
|
2825
2838
|
regionBtn.title = "Drag a free-size box, screenshot it, and comment";
|
|
2826
2839
|
regionBtn.onclick = () => this.setMode(this.mode === "region" ? "off" : "region");
|
|
2827
2840
|
const recordBtn = this.toolBtn(RECORD_ICON, "Record", "record");
|
|
2828
|
-
recordBtn.title = "Drag a box, record a screen video of it, and comment";
|
|
2841
|
+
recordBtn.title = isTouchDevice() ? "Record your screen, then describe the issue" : "Drag a box, record a screen video of it, and comment";
|
|
2829
2842
|
recordBtn.onclick = () => this.setMode(this.mode === "record" ? "off" : "record");
|
|
2830
|
-
|
|
2831
|
-
|
|
2843
|
+
if (canShareScreen()) {
|
|
2844
|
+
tools.append(inspectBtn, freeBtn, regionBtn, recordBtn);
|
|
2845
|
+
} else if (isTouchDevice()) {
|
|
2846
|
+
const cameraBtn = this.toolBtn(CAMERA_ICON, "Camera", "camera");
|
|
2847
|
+
cameraBtn.title = "Record a video with the camera and comment";
|
|
2848
|
+
cameraBtn.onclick = () => this.pickCameraVideo();
|
|
2849
|
+
tools.append(inspectBtn, freeBtn, regionBtn, cameraBtn);
|
|
2850
|
+
} else {
|
|
2851
|
+
tools.append(inspectBtn, freeBtn, regionBtn);
|
|
2852
|
+
}
|
|
2832
2853
|
const listHead = el("div", "listhead");
|
|
2833
2854
|
listHead.append(document.createTextNode("Comments"));
|
|
2834
2855
|
this.countEl = el("span", "count", "0");
|
|
@@ -3003,6 +3024,37 @@ var LoupeApp = class {
|
|
|
3003
3024
|
file ? [file] : []
|
|
3004
3025
|
);
|
|
3005
3026
|
}
|
|
3027
|
+
/**
|
|
3028
|
+
* Touch devices with no screen recorder (every iOS browser) can still report a video:
|
|
3029
|
+
* record one with the camera. Opens the native recorder and hands the clip to the
|
|
3030
|
+
* composer exactly like the screen capture does.
|
|
3031
|
+
*/
|
|
3032
|
+
pickCameraVideo() {
|
|
3033
|
+
this.setMode("off");
|
|
3034
|
+
const input = document.createElement("input");
|
|
3035
|
+
input.type = "file";
|
|
3036
|
+
input.accept = "video/*";
|
|
3037
|
+
input.setAttribute("capture", "environment");
|
|
3038
|
+
input.style.display = "none";
|
|
3039
|
+
input.onchange = () => {
|
|
3040
|
+
const file = input.files?.[0];
|
|
3041
|
+
input.remove();
|
|
3042
|
+
if (!file) return;
|
|
3043
|
+
const docX = window.scrollX + window.innerWidth / 2;
|
|
3044
|
+
const docY = window.scrollY + window.innerHeight / 2;
|
|
3045
|
+
const docW = Math.max(1, document.documentElement.scrollWidth);
|
|
3046
|
+
const docH = Math.max(1, document.documentElement.scrollHeight);
|
|
3047
|
+
const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };
|
|
3048
|
+
this.openComposer(
|
|
3049
|
+
{ kind: "free", offset, point: { x: docX, y: docY }, label: "Camera video \xB7 attached" },
|
|
3050
|
+
8,
|
|
3051
|
+
window.innerHeight / 2,
|
|
3052
|
+
[file]
|
|
3053
|
+
);
|
|
3054
|
+
};
|
|
3055
|
+
this.shadow.appendChild(input);
|
|
3056
|
+
input.click();
|
|
3057
|
+
}
|
|
3006
3058
|
/** Capture the selected viewport rect, then open the composer for a region comment. */
|
|
3007
3059
|
async finishRegion(vp) {
|
|
3008
3060
|
this.selbox.style.display = "none";
|
|
@@ -3097,6 +3149,10 @@ var LoupeApp = class {
|
|
|
3097
3149
|
document.addEventListener("click", this.onFreeClick, true);
|
|
3098
3150
|
} else if (mode === "region" && isTouchDevice()) {
|
|
3099
3151
|
void this.captureViewportForComposer();
|
|
3152
|
+
} else if (mode === "record" && isTouchDevice()) {
|
|
3153
|
+
const vp = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };
|
|
3154
|
+
this.setMode("off");
|
|
3155
|
+
void this.finishRecording(vp);
|
|
3100
3156
|
} else if (mode === "region" || mode === "record") {
|
|
3101
3157
|
document.addEventListener("pointerdown", this.onRegionDown, true);
|
|
3102
3158
|
}
|
|
@@ -3252,8 +3308,16 @@ var LoupeApp = class {
|
|
|
3252
3308
|
screenshot,
|
|
3253
3309
|
recording,
|
|
3254
3310
|
attachments: await this.uploadAttachments(files),
|
|
3255
|
-
//
|
|
3256
|
-
|
|
3311
|
+
// The screen this was captured on, plus enough to tell a stale bundle from a real
|
|
3312
|
+
// bug when someone reports "it still doesn't work" (see Comment.viewport).
|
|
3313
|
+
viewport: {
|
|
3314
|
+
w: window.innerWidth,
|
|
3315
|
+
h: window.innerHeight,
|
|
3316
|
+
v: SDK_VERSION,
|
|
3317
|
+
touch: isTouchDevice(),
|
|
3318
|
+
coarse: coarsePointer(),
|
|
3319
|
+
gdm: canShareScreen()
|
|
3320
|
+
},
|
|
3257
3321
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3258
3322
|
};
|
|
3259
3323
|
await this.store.save(comment);
|
|
@@ -3638,6 +3702,7 @@ var I_CLOSE = svg(
|
|
|
3638
3702
|
var REGION_ICON = `<svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden="true"><rect x="1.5" y="2.5" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4" stroke-dasharray="2.4 1.8"/></svg>`;
|
|
3639
3703
|
var NOTE_ICON = `<svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden="true"><path d="M2 2.5h11v7.5H6l-3 2.5v-2.5H2z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/></svg>`;
|
|
3640
3704
|
var RECORD_ICON = `<svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden="true"><rect x="1.5" y="2.5" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4" stroke-dasharray="2.4 1.8"/><circle cx="7.5" cy="7.5" r="2.4" fill="currentColor"/></svg>`;
|
|
3705
|
+
var CAMERA_ICON = `<svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden="true"><rect x="1.2" y="3.8" width="9.2" height="7.4" rx="1.6" stroke="currentColor" stroke-width="1.3"/><path d="M10.4 7.3l3.4-2v4.4l-3.4-2z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/></svg>`;
|
|
3641
3706
|
var I_GITHUB = `<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 .2a8 8 0 0 0-2.5 15.6c.4.07.55-.17.55-.38v-1.3c-2.2.48-2.67-1.07-2.67-1.07-.36-.92-.88-1.16-.88-1.16-.72-.5.05-.48.05-.48.8.056 1.22.82 1.22.82.71 1.22 1.87.87 2.33.66.07-.52.28-.87.5-1.07-1.76-.2-3.6-.88-3.6-3.9 0-.86.3-1.57.82-2.12-.08-.2-.36-1 .08-2.1 0 0 .67-.21 2.2.8a7.6 7.6 0 0 1 4 0c1.53-1.02 2.2-.8 2.2-.8.44 1.1.16 1.9.08 2.1.5.55.82 1.26.82 2.12 0 3.03-1.85 3.7-3.61 3.9.28.24.54.72.54 1.46v2.16c0 .21.14.46.55.38A8 8 0 0 0 8 .2z"/></svg>`;
|
|
3642
3707
|
var I_SLACK = `<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M3.4 10.1a1.6 1.6 0 1 1-1.6-1.6h1.6v1.6zm.8 0a1.6 1.6 0 0 1 3.2 0v4a1.6 1.6 0 1 1-3.2 0v-4zM5.8 3.4a1.6 1.6 0 1 1 1.6-1.6v1.6H5.8zm0 .8a1.6 1.6 0 0 1 0 3.2h-4a1.6 1.6 0 1 1 0-3.2h4zm6.7 1.6a1.6 1.6 0 1 1 1.6 1.6h-1.6V5.8zm-.8 0a1.6 1.6 0 0 1-3.2 0v-4a1.6 1.6 0 1 1 3.2 0v4zm-1.6 6.7a1.6 1.6 0 1 1-1.6 1.6v-1.6h1.6zm0-.8a1.6 1.6 0 0 1 0-3.2h4a1.6 1.6 0 1 1 0 3.2h-4z"/></svg>`;
|
|
3643
3708
|
var I_TELEGRAM = `<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.7 5.4-1.24 5.85c-.09.41-.34.51-.69.32l-1.9-1.4-.92.88c-.1.1-.19.19-.38.19l.14-1.93 3.5-3.17c.15-.13-.03-.2-.24-.07l-4.32 2.72-1.86-.58c-.4-.13-.41-.4.09-.6l7.26-2.8c.34-.12.63.08.52.6z"/></svg>`;
|