@loupekit/sdk 0.9.3-next.38 → 0.9.3
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 +6 -64
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +6 -64
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -308,14 +308,6 @@ var STYLES = (
|
|
|
308
308
|
page stays visible and tappable; the list returns when the tool closes. */
|
|
309
309
|
.dock.inspecting { height: auto !important; }
|
|
310
310
|
.dock.inspecting .listhead, .dock.inspecting .list { display: none; }
|
|
311
|
-
/* The composer is a bottom sheet on a phone: full width, thumb-reachable, and it
|
|
312
|
-
scrolls when the on-screen keyboard is up. JS sets its position inline (hence the
|
|
313
|
-
!important) \u2014 on small screens the sheet wins. */
|
|
314
|
-
.composer {
|
|
315
|
-
top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
|
|
316
|
-
width: auto !important; max-height: 80vh; overflow-y: auto;
|
|
317
|
-
border-radius: 16px 16px 0 0; padding-bottom: 16px;
|
|
318
|
-
}
|
|
319
311
|
}
|
|
320
312
|
`
|
|
321
313
|
);
|
|
@@ -2439,26 +2431,6 @@ function hash(s) {
|
|
|
2439
2431
|
for (let i = 0; i < s.length; i++) h = h * 31 + s.charCodeAt(i) | 0;
|
|
2440
2432
|
return h;
|
|
2441
2433
|
}
|
|
2442
|
-
function isTouchDevice() {
|
|
2443
|
-
try {
|
|
2444
|
-
return typeof window.matchMedia === "function" && window.matchMedia("(pointer: coarse)").matches;
|
|
2445
|
-
} catch {
|
|
2446
|
-
return false;
|
|
2447
|
-
}
|
|
2448
|
-
}
|
|
2449
|
-
function dataUrlToFile(dataUrl, name) {
|
|
2450
|
-
const m = /^data:([^;,]+)(;base64)?,([\s\S]*)$/.exec(dataUrl);
|
|
2451
|
-
if (!m) return null;
|
|
2452
|
-
const [, type, b64, payload = ""] = m;
|
|
2453
|
-
try {
|
|
2454
|
-
const raw = b64 ? atob(payload) : decodeURIComponent(payload);
|
|
2455
|
-
const bytes = new Uint8Array(raw.length);
|
|
2456
|
-
for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
|
|
2457
|
-
return new File([bytes], name, { type: type || "image/png" });
|
|
2458
|
-
} catch {
|
|
2459
|
-
return null;
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
2434
|
var LoupeApp = class {
|
|
2463
2435
|
constructor(cfg) {
|
|
2464
2436
|
this.comments = [];
|
|
@@ -2827,7 +2799,7 @@ var LoupeApp = class {
|
|
|
2827
2799
|
const recordBtn = this.toolBtn(RECORD_ICON, "Record", "record");
|
|
2828
2800
|
recordBtn.title = "Drag a box, record a screen video of it, and comment";
|
|
2829
2801
|
recordBtn.onclick = () => this.setMode(this.mode === "record" ? "off" : "record");
|
|
2830
|
-
const canRecord =
|
|
2802
|
+
const canRecord = typeof navigator.mediaDevices?.getDisplayMedia === "function";
|
|
2831
2803
|
tools.append(inspectBtn, freeBtn, regionBtn, ...canRecord ? [recordBtn] : []);
|
|
2832
2804
|
const listHead = el("div", "listhead");
|
|
2833
2805
|
listHead.append(document.createTextNode("Comments"));
|
|
@@ -2975,34 +2947,6 @@ var LoupeApp = class {
|
|
|
2975
2947
|
const region = { x: vp.x + window.scrollX, y: vp.y + window.scrollY, w: vp.w, h: vp.h, rel };
|
|
2976
2948
|
return { region, element: centerEl };
|
|
2977
2949
|
}
|
|
2978
|
-
/**
|
|
2979
|
-
* Touch path for the Region tool: capture what is on screen right now and open the
|
|
2980
|
-
* composer with it already attached. The reporter scrolls to the part of the page they
|
|
2981
|
-
* mean FIRST, then taps Region — no drag, so nothing fights the page scroll.
|
|
2982
|
-
*/
|
|
2983
|
-
async captureViewportForComposer() {
|
|
2984
|
-
const vp = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };
|
|
2985
|
-
const capture = this.cfg.captureRegion ?? captureRegionScreenshot;
|
|
2986
|
-
let shot;
|
|
2987
|
-
try {
|
|
2988
|
-
shot = await capture(vp);
|
|
2989
|
-
} catch {
|
|
2990
|
-
shot = void 0;
|
|
2991
|
-
}
|
|
2992
|
-
const file = shot ? dataUrlToFile(shot, "screenshot.png") : null;
|
|
2993
|
-
const docX = window.scrollX + vp.w / 2;
|
|
2994
|
-
const docY = window.scrollY + vp.h / 2;
|
|
2995
|
-
const docW = Math.max(1, document.documentElement.scrollWidth);
|
|
2996
|
-
const docH = Math.max(1, document.documentElement.scrollHeight);
|
|
2997
|
-
const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };
|
|
2998
|
-
this.setMode("off");
|
|
2999
|
-
this.openComposer(
|
|
3000
|
-
{ kind: "free", offset, point: { x: docX, y: docY }, label: "Screenshot \xB7 attached" },
|
|
3001
|
-
8,
|
|
3002
|
-
window.innerHeight / 2,
|
|
3003
|
-
file ? [file] : []
|
|
3004
|
-
);
|
|
3005
|
-
}
|
|
3006
2950
|
/** Capture the selected viewport rect, then open the composer for a region comment. */
|
|
3007
2951
|
async finishRegion(vp) {
|
|
3008
2952
|
this.selbox.style.display = "none";
|
|
@@ -3086,6 +3030,7 @@ var LoupeApp = class {
|
|
|
3086
3030
|
document.removeEventListener("click", this.onClick, true);
|
|
3087
3031
|
document.removeEventListener("click", this.onFreeClick, true);
|
|
3088
3032
|
document.removeEventListener("pointerdown", this.onRegionDown, true);
|
|
3033
|
+
document.documentElement.style.touchAction = mode === "region" || mode === "record" ? "none" : "";
|
|
3089
3034
|
if (mode === "off") return;
|
|
3090
3035
|
document.addEventListener("keydown", this.onKey, true);
|
|
3091
3036
|
this.closeComposer();
|
|
@@ -3095,14 +3040,12 @@ var LoupeApp = class {
|
|
|
3095
3040
|
document.addEventListener("click", this.onClick, true);
|
|
3096
3041
|
} else if (mode === "free") {
|
|
3097
3042
|
document.addEventListener("click", this.onFreeClick, true);
|
|
3098
|
-
} else if (mode === "region" && isTouchDevice()) {
|
|
3099
|
-
void this.captureViewportForComposer();
|
|
3100
3043
|
} else if (mode === "region" || mode === "record") {
|
|
3101
3044
|
document.addEventListener("pointerdown", this.onRegionDown, true);
|
|
3102
3045
|
}
|
|
3103
3046
|
}
|
|
3104
3047
|
// ---- composer -------------------------------------------------------------
|
|
3105
|
-
openComposer(target, x, y
|
|
3048
|
+
openComposer(target, x, y) {
|
|
3106
3049
|
this.pending = target;
|
|
3107
3050
|
const isRecording = target.kind === "region" && !!target.recording;
|
|
3108
3051
|
const c = this.composer;
|
|
@@ -3110,14 +3053,14 @@ var LoupeApp = class {
|
|
|
3110
3053
|
const label = el(
|
|
3111
3054
|
"div",
|
|
3112
3055
|
"target",
|
|
3113
|
-
target.kind === "element" ? describe(target.element) : target.kind === "region" ? isRecording ? `\u23FA Recording \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` : `Region \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` :
|
|
3056
|
+
target.kind === "element" ? describe(target.element) : target.kind === "region" ? isRecording ? `\u23FA Recording \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` : `Region \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` : "Free note \xB7 anywhere on the page"
|
|
3114
3057
|
);
|
|
3115
3058
|
const title = el("input", "title");
|
|
3116
3059
|
title.type = "text";
|
|
3117
3060
|
title.placeholder = "Title \u2014 one line: what's wrong, or what you need";
|
|
3118
3061
|
const ta = el("textarea");
|
|
3119
3062
|
ta.placeholder = isRecording ? "Describe the issue in this recording\u2026" : target.kind === "region" ? "Describe the issue in this area\u2026" : target.kind === "free" ? "Describe this note\u2026" : "Describe what should change here\u2026";
|
|
3120
|
-
const files =
|
|
3063
|
+
const files = [];
|
|
3121
3064
|
const attach = el("div", "attach");
|
|
3122
3065
|
const pick = el("button", "pick", "\uFF0B Attach images / videos");
|
|
3123
3066
|
const input = document.createElement("input");
|
|
@@ -3159,7 +3102,6 @@ var LoupeApp = class {
|
|
|
3159
3102
|
};
|
|
3160
3103
|
pick.onclick = () => input.click();
|
|
3161
3104
|
attach.append(pick, input, chips, err);
|
|
3162
|
-
if (files.length) drawChips();
|
|
3163
3105
|
const row = el("div", "row");
|
|
3164
3106
|
let box = null;
|
|
3165
3107
|
if (target.kind !== "free" && !isRecording) {
|
|
@@ -3191,7 +3133,7 @@ var LoupeApp = class {
|
|
|
3191
3133
|
const left = Math.min(Math.max(8, x + 12), window.innerWidth - w - 8);
|
|
3192
3134
|
const top = Math.min(Math.max(8, y + 12), window.innerHeight - h - 8);
|
|
3193
3135
|
Object.assign(c.style, { display: "block", left: left + "px", top: top + "px" });
|
|
3194
|
-
|
|
3136
|
+
ta.focus();
|
|
3195
3137
|
}
|
|
3196
3138
|
closeComposer() {
|
|
3197
3139
|
this.composer.style.display = "none";
|