@mindbowser_inc/ui-feedback-plugin 0.5.0 → 0.6.0
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var O = (e, t, r) =>
|
|
1
|
+
var me = Object.defineProperty;
|
|
2
|
+
var ge = (e, t, r) => t in e ? me(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
3
|
+
var O = (e, t, r) => ge(e, typeof t != "symbol" ? t + "" : t, r);
|
|
4
4
|
const I = /* @__PURE__ */ new Set();
|
|
5
5
|
let R = {
|
|
6
6
|
active: !1,
|
|
@@ -18,18 +18,18 @@ function A() {
|
|
|
18
18
|
function k(e) {
|
|
19
19
|
R = { ...R, ...e }, I.forEach((t) => t(R));
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function oe(e) {
|
|
22
22
|
return I.add(e), () => I.delete(e);
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function re() {
|
|
25
25
|
if (R.userName) return R.userName;
|
|
26
26
|
const e = localStorage.getItem("ufp_user_name");
|
|
27
27
|
return e ? (k({ userName: e }), e) : null;
|
|
28
28
|
}
|
|
29
|
-
function
|
|
29
|
+
function ie(e) {
|
|
30
30
|
localStorage.setItem("ufp_user_name", e), k({ userName: e });
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function Q(e) {
|
|
33
33
|
try {
|
|
34
34
|
const t = new URL(e);
|
|
35
35
|
return t.origin + t.pathname;
|
|
@@ -37,7 +37,7 @@ function J(e) {
|
|
|
37
37
|
return e;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
function
|
|
40
|
+
function xe(e) {
|
|
41
41
|
return `
|
|
42
42
|
:host {
|
|
43
43
|
--ufp-primary: ${e};
|
|
@@ -592,15 +592,15 @@ function ye(e) {
|
|
|
592
592
|
}
|
|
593
593
|
`;
|
|
594
594
|
}
|
|
595
|
-
const
|
|
595
|
+
const ye = {
|
|
596
596
|
"bottom-right": { bottom: "24px", right: "24px" },
|
|
597
597
|
"bottom-left": { bottom: "24px", left: "24px" },
|
|
598
598
|
"top-right": { top: "24px", right: "24px" },
|
|
599
599
|
"top-left": { top: "24px", left: "24px" }
|
|
600
|
-
}, q = "#6366f1",
|
|
601
|
-
function
|
|
602
|
-
const
|
|
603
|
-
Object.assign(
|
|
600
|
+
}, q = "#6366f1", Z = "#4f46e5", ee = "#4338ca";
|
|
601
|
+
function ve(e, t, r, n) {
|
|
602
|
+
const o = document.createElement("div");
|
|
603
|
+
Object.assign(o.style, {
|
|
604
604
|
position: "fixed",
|
|
605
605
|
zIndex: "2147483647",
|
|
606
606
|
display: "flex",
|
|
@@ -609,10 +609,10 @@ function be(e, t, r, o) {
|
|
|
609
609
|
boxShadow: "0 4px 20px rgba(0,0,0,0.28), 0 1px 4px rgba(0,0,0,0.16)",
|
|
610
610
|
overflow: "hidden",
|
|
611
611
|
userSelect: "none",
|
|
612
|
-
...
|
|
612
|
+
...ye[t]
|
|
613
613
|
});
|
|
614
614
|
const a = document.createElement("button");
|
|
615
|
-
a.id = "ufp-btn-annotate", a.title = "Add feedback annotation",
|
|
615
|
+
a.id = "ufp-btn-annotate", a.title = "Add feedback annotation", te(a), a.style.padding = "10px 16px 10px 14px", a.innerHTML = `
|
|
616
616
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" style="flex-shrink:0">
|
|
617
617
|
<path d="M12 20h9"/>
|
|
618
618
|
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
|
|
@@ -622,25 +622,25 @@ function be(e, t, r, o) {
|
|
|
622
622
|
const p = document.createElement("div");
|
|
623
623
|
p.style.cssText = "width:1px;background:rgba(255,255,255,0.3);flex-shrink:0;";
|
|
624
624
|
const c = document.createElement("button");
|
|
625
|
-
c.id = "ufp-btn-panel", c.title = "View all comments",
|
|
625
|
+
c.id = "ufp-btn-panel", c.title = "View all comments", te(c), c.style.padding = "10px 14px", c.innerHTML = `
|
|
626
626
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" style="flex-shrink:0">
|
|
627
627
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
|
628
628
|
</svg>
|
|
629
629
|
<span id="ufp-panel-count" style="font-size:13px;font-weight:600;min-width:8px;text-align:center;"></span>
|
|
630
|
-
`,
|
|
631
|
-
const i =
|
|
630
|
+
`, o.appendChild(a), o.appendChild(p), o.appendChild(c), e.appendChild(o);
|
|
631
|
+
const i = o.querySelector("#ufp-annotate-label"), l = o.querySelector("#ufp-panel-count");
|
|
632
632
|
return a.addEventListener("click", (s) => {
|
|
633
|
-
if (s.stopPropagation(),
|
|
634
|
-
const
|
|
635
|
-
|
|
633
|
+
if (s.stopPropagation(), o._dragged) return;
|
|
634
|
+
const h = A();
|
|
635
|
+
h.active || (h.panelOpen ? (n(), setTimeout(r, 220)) : r());
|
|
636
636
|
}), c.addEventListener("click", (s) => {
|
|
637
|
-
s.stopPropagation(), !
|
|
638
|
-
}),
|
|
639
|
-
const
|
|
640
|
-
l.textContent =
|
|
641
|
-
}),
|
|
637
|
+
s.stopPropagation(), !o._dragged && (A().active || n());
|
|
638
|
+
}), ne(a, () => (A().panelOpen, q), Z), ne(c, () => A().panelOpen ? ee : q, Z), oe((s) => {
|
|
639
|
+
const h = s.comments.filter((v) => !v.resolved).length;
|
|
640
|
+
l.textContent = h > 0 ? String(h) : "", s.active ? (i.textContent = "Drawing…", a.style.opacity = "0.65", c.style.opacity = "0.65", a.style.pointerEvents = "none", c.style.pointerEvents = "none") : (i.textContent = "Feedback", a.style.opacity = "1", c.style.opacity = "1", a.style.pointerEvents = "auto", c.style.pointerEvents = "auto"), c.style.background = s.panelOpen ? ee : q;
|
|
641
|
+
}), be(o), o;
|
|
642
642
|
}
|
|
643
|
-
function
|
|
643
|
+
function te(e) {
|
|
644
644
|
Object.assign(e.style, {
|
|
645
645
|
display: "flex",
|
|
646
646
|
alignItems: "center",
|
|
@@ -654,23 +654,23 @@ function ee(e) {
|
|
|
654
654
|
transition: "background 0.12s"
|
|
655
655
|
});
|
|
656
656
|
}
|
|
657
|
-
function
|
|
657
|
+
function ne(e, t, r) {
|
|
658
658
|
e.addEventListener("mouseenter", () => {
|
|
659
659
|
e.style.background = r;
|
|
660
660
|
}), e.addEventListener("mouseleave", () => {
|
|
661
661
|
e.style.background = t();
|
|
662
662
|
});
|
|
663
663
|
}
|
|
664
|
-
function
|
|
665
|
-
let t = 0, r = 0,
|
|
664
|
+
function be(e) {
|
|
665
|
+
let t = 0, r = 0, n = 0, o = 0;
|
|
666
666
|
e.addEventListener("pointerdown", (a) => {
|
|
667
667
|
if (a.button !== 0) return;
|
|
668
668
|
t = a.clientX, r = a.clientY;
|
|
669
669
|
const p = e.getBoundingClientRect();
|
|
670
|
-
|
|
670
|
+
n = p.left, o = p.top, e._dragged = !1;
|
|
671
671
|
const c = (l) => {
|
|
672
|
-
const s = l.clientX - t,
|
|
673
|
-
!e._dragged && Math.sqrt(s * s +
|
|
672
|
+
const s = l.clientX - t, h = l.clientY - r;
|
|
673
|
+
!e._dragged && Math.sqrt(s * s + h * h) < 5 || (e._dragged = !0, e.style.left = `${Math.max(0, Math.min(window.innerWidth - e.offsetWidth, n + s))}px`, e.style.top = `${Math.max(0, Math.min(window.innerHeight - e.offsetHeight, o + h))}px`, e.style.right = "auto", e.style.bottom = "auto");
|
|
674
674
|
}, i = () => {
|
|
675
675
|
document.removeEventListener("pointermove", c), document.removeEventListener("pointerup", i), requestAnimationFrame(() => {
|
|
676
676
|
e._dragged = !1;
|
|
@@ -679,7 +679,7 @@ function we(e) {
|
|
|
679
679
|
document.addEventListener("pointermove", c), document.addEventListener("pointerup", i);
|
|
680
680
|
});
|
|
681
681
|
}
|
|
682
|
-
function
|
|
682
|
+
function we(e) {
|
|
683
683
|
return new Promise((t) => {
|
|
684
684
|
const r = document.createElement("div");
|
|
685
685
|
r.className = "ufp-modal-backdrop", r.innerHTML = `
|
|
@@ -699,42 +699,42 @@ function ke(e) {
|
|
|
699
699
|
</div>
|
|
700
700
|
</div>
|
|
701
701
|
`, e.appendChild(r);
|
|
702
|
-
const
|
|
703
|
-
|
|
704
|
-
|
|
702
|
+
const n = r.querySelector("#ufp-name-input"), o = r.querySelector("#ufp-name-submit");
|
|
703
|
+
n.addEventListener("input", () => {
|
|
704
|
+
o.disabled = n.value.trim().length === 0;
|
|
705
705
|
});
|
|
706
706
|
const a = () => {
|
|
707
|
-
const p =
|
|
708
|
-
p && (
|
|
707
|
+
const p = n.value.trim();
|
|
708
|
+
p && (ie(p), r.remove(), t(p));
|
|
709
709
|
};
|
|
710
|
-
|
|
710
|
+
o.addEventListener("click", a), n.addEventListener("keydown", (p) => {
|
|
711
711
|
p.key === "Enter" && a();
|
|
712
|
-
}), requestAnimationFrame(() =>
|
|
712
|
+
}), requestAnimationFrame(() => n.focus());
|
|
713
713
|
});
|
|
714
714
|
}
|
|
715
|
-
const L = "#6366f1",
|
|
715
|
+
const L = "#6366f1", z = 3;
|
|
716
716
|
function B(e, t = 1, r = 1) {
|
|
717
717
|
switch (e.type) {
|
|
718
718
|
case "pen": {
|
|
719
|
-
const
|
|
720
|
-
return
|
|
719
|
+
const n = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
720
|
+
return n.setAttribute("d", Ee(e.points, t, r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.width * Math.min(t, r))), n.setAttribute("fill", "none"), n.setAttribute("stroke-linecap", "round"), n.setAttribute("stroke-linejoin", "round"), n;
|
|
721
721
|
}
|
|
722
722
|
case "rect": {
|
|
723
|
-
const
|
|
724
|
-
return
|
|
723
|
+
const n = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
724
|
+
return n.setAttribute("x", String(e.x * t)), n.setAttribute("y", String(e.y * r)), n.setAttribute("width", String(e.width * t)), n.setAttribute("height", String(e.height * r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.strokeWidth * Math.min(t, r))), n.setAttribute("fill", "none"), n.setAttribute("rx", "3"), n;
|
|
725
725
|
}
|
|
726
726
|
case "circle": {
|
|
727
|
-
const
|
|
728
|
-
return
|
|
727
|
+
const n = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
|
|
728
|
+
return n.setAttribute("cx", String(e.cx * t)), n.setAttribute("cy", String(e.cy * r)), n.setAttribute("rx", String(e.rx * t)), n.setAttribute("ry", String(e.ry * r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.strokeWidth * Math.min(t, r))), n.setAttribute("fill", "none"), n;
|
|
729
729
|
}
|
|
730
730
|
case "arrow": {
|
|
731
|
-
const
|
|
732
|
-
return
|
|
731
|
+
const n = document.createElementNS("http://www.w3.org/2000/svg", "g"), o = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
732
|
+
return o.setAttribute("x1", String(e.x1 * t)), o.setAttribute("y1", String(e.y1 * r)), o.setAttribute("x2", String(e.x2 * t)), o.setAttribute("y2", String(e.y2 * r)), o.setAttribute("stroke", e.color), o.setAttribute("stroke-width", String(e.width * Math.min(t, r))), o.setAttribute("marker-end", "url(#ufp-arrowhead)"), n.appendChild(o), n;
|
|
733
733
|
}
|
|
734
734
|
}
|
|
735
735
|
}
|
|
736
|
-
function
|
|
737
|
-
const
|
|
736
|
+
function ke(e, t, r, n) {
|
|
737
|
+
const o = r / t.pageWidth, a = n / t.pageHeight;
|
|
738
738
|
e.innerHTML = "";
|
|
739
739
|
const p = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
740
740
|
p.innerHTML = `
|
|
@@ -742,58 +742,58 @@ function Ee(e, t, r, o) {
|
|
|
742
742
|
<polygon points="0 0, 10 3.5, 0 7" fill="${L}" />
|
|
743
743
|
</marker>
|
|
744
744
|
`, e.appendChild(p), t.shapes.forEach((c) => {
|
|
745
|
-
e.appendChild(B(c,
|
|
745
|
+
e.appendChild(B(c, o, a));
|
|
746
746
|
});
|
|
747
747
|
}
|
|
748
|
-
function
|
|
748
|
+
function Ee(e, t, r) {
|
|
749
749
|
if (e.length === 0) return "";
|
|
750
750
|
if (e.length === 1) {
|
|
751
|
-
const
|
|
752
|
-
return `M ${
|
|
751
|
+
const o = e[0];
|
|
752
|
+
return `M ${o.x * t} ${o.y * r}`;
|
|
753
753
|
}
|
|
754
|
-
let
|
|
755
|
-
for (let
|
|
756
|
-
|
|
757
|
-
return
|
|
754
|
+
let n = `M ${e[0].x * t} ${e[0].y * r}`;
|
|
755
|
+
for (let o = 1; o < e.length; o++)
|
|
756
|
+
n += ` L ${e[o].x * t} ${e[o].y * r}`;
|
|
757
|
+
return n;
|
|
758
758
|
}
|
|
759
|
-
function
|
|
760
|
-
if (window.scrollY === 0) return null;
|
|
761
|
-
const
|
|
759
|
+
function Se(e, t, r) {
|
|
760
|
+
if (window.scrollX === 0 && window.scrollY === 0) return null;
|
|
761
|
+
const n = window.innerWidth, o = window.innerHeight, a = document.elementsFromPoint(e, t).find((p) => p !== r);
|
|
762
762
|
for (let p = a ?? null; p && p !== document.documentElement; p = p.parentElement) {
|
|
763
763
|
const c = getComputedStyle(p);
|
|
764
764
|
if (c.position !== "fixed" && c.position !== "sticky") continue;
|
|
765
765
|
const i = p.getBoundingClientRect();
|
|
766
|
-
if (!(i.width >=
|
|
766
|
+
if (!(i.width >= n * 0.9 && i.height >= o * 0.9)) {
|
|
767
767
|
if (c.position === "sticky") {
|
|
768
|
-
if (i.top <
|
|
768
|
+
if (i.top < o * 0.25) return "top";
|
|
769
769
|
continue;
|
|
770
770
|
}
|
|
771
|
-
return
|
|
771
|
+
return o - i.bottom < i.top ? "bottom" : "top";
|
|
772
772
|
}
|
|
773
773
|
}
|
|
774
774
|
return null;
|
|
775
775
|
}
|
|
776
|
-
function
|
|
777
|
-
if (!t) return e;
|
|
776
|
+
function Ce(e, t, r) {
|
|
777
|
+
if (!t && !r) return e;
|
|
778
778
|
switch (e.type) {
|
|
779
779
|
case "pen":
|
|
780
|
-
return { ...e, points: e.points.map((
|
|
780
|
+
return { ...e, points: e.points.map((n) => ({ x: n.x + t, y: n.y + r })) };
|
|
781
781
|
case "rect":
|
|
782
|
-
return { ...e, y: e.y +
|
|
782
|
+
return { ...e, x: e.x + t, y: e.y + r };
|
|
783
783
|
case "circle":
|
|
784
|
-
return { ...e, cy: e.cy +
|
|
784
|
+
return { ...e, cx: e.cx + t, cy: e.cy + r };
|
|
785
785
|
case "arrow":
|
|
786
|
-
return { ...e, y1: e.y1 + t, y2: e.y2 +
|
|
786
|
+
return { ...e, x1: e.x1 + t, y1: e.y1 + r, x2: e.x2 + t, y2: e.y2 + r };
|
|
787
787
|
}
|
|
788
788
|
}
|
|
789
|
-
function
|
|
789
|
+
function Le(e) {
|
|
790
790
|
return new Promise((t) => {
|
|
791
791
|
let r = "pen";
|
|
792
|
-
const
|
|
793
|
-
let
|
|
792
|
+
const n = [];
|
|
793
|
+
let o = !1, a = 0, p = 0, c = [], i = null, l = null, s = !1, h = 0;
|
|
794
794
|
const v = [];
|
|
795
|
-
let
|
|
796
|
-
const b = () =>
|
|
795
|
+
let m = null;
|
|
796
|
+
const b = () => m ? { x: 0, y: 0 } : { x: window.scrollX, y: window.scrollY }, x = document.createElement("div");
|
|
797
797
|
x.style.cssText = "position:fixed;inset:0;z-index:2147483645;cursor:crosshair;background:rgba(99,102,241,0.04);touch-action:none;user-select:none;-webkit-user-select:none;";
|
|
798
798
|
const u = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
799
799
|
u.style.cssText = "position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;", u.innerHTML = `
|
|
@@ -811,16 +811,16 @@ function Me(e) {
|
|
|
811
811
|
N(), window.addEventListener("scroll", N, { passive: !0 });
|
|
812
812
|
function H() {
|
|
813
813
|
window.removeEventListener("scroll", N);
|
|
814
|
-
for (const d of
|
|
815
|
-
for (const d of
|
|
814
|
+
for (const d of X) window.removeEventListener(d, K, !0);
|
|
815
|
+
for (const d of Y) window.removeEventListener(d, G, !0);
|
|
816
816
|
x.remove(), P.remove(), l == null || l.remove();
|
|
817
817
|
}
|
|
818
818
|
function j() {
|
|
819
|
-
w.innerHTML = "", C.innerHTML = "",
|
|
819
|
+
w.innerHTML = "", C.innerHTML = "", n.forEach((d, g) => (v[g] ? C : w).appendChild(B(d)));
|
|
820
820
|
}
|
|
821
821
|
function _() {
|
|
822
822
|
let d = 0, g = 0, y = 0;
|
|
823
|
-
return
|
|
823
|
+
return n.forEach((f, E) => {
|
|
824
824
|
const S = v[E] ? 0 : window.scrollX, M = v[E] ? 0 : window.scrollY;
|
|
825
825
|
if (f.type === "pen" && f.points.length) {
|
|
826
826
|
const $ = f.points[f.points.length - 1];
|
|
@@ -831,10 +831,10 @@ function Me(e) {
|
|
|
831
831
|
anchorY: y > 0 ? g / y : window.innerHeight / 2
|
|
832
832
|
};
|
|
833
833
|
}
|
|
834
|
-
function ie() {
|
|
835
|
-
s = !0, n = !1, x.style.pointerEvents = "none", P.style.pointerEvents = "none", ae();
|
|
836
|
-
}
|
|
837
834
|
function ae() {
|
|
835
|
+
s = !0, o = !1, x.style.pointerEvents = "none", P.style.pointerEvents = "none", se();
|
|
836
|
+
}
|
|
837
|
+
function se() {
|
|
838
838
|
l && l.remove();
|
|
839
839
|
const { anchorX: d, anchorY: g } = _(), y = 300, f = 12;
|
|
840
840
|
let E = d + f, S = g + f;
|
|
@@ -861,22 +861,22 @@ function Me(e) {
|
|
|
861
861
|
color:#fff;opacity:0.45;transition:opacity 0.15s;">Submit</button>
|
|
862
862
|
</div>
|
|
863
863
|
`, e.appendChild(l);
|
|
864
|
-
const M = l.querySelector("#ufp-inline-text"), $ = l.querySelector("#ufp-popup-submit"),
|
|
864
|
+
const M = l.querySelector("#ufp-inline-text"), $ = l.querySelector("#ufp-popup-submit"), de = l.querySelector("#ufp-popup-cancel");
|
|
865
865
|
M.addEventListener("input", () => {
|
|
866
866
|
const W = M.value.trim().length > 0;
|
|
867
867
|
$.disabled = !W, $.style.opacity = W ? "1" : "0.45";
|
|
868
868
|
}), $.addEventListener("click", () => {
|
|
869
869
|
const W = M.value.trim();
|
|
870
870
|
if (!W) return;
|
|
871
|
-
const
|
|
871
|
+
const ue = _();
|
|
872
872
|
H();
|
|
873
|
-
const
|
|
874
|
-
t({ shapes: fe, text: W, ...
|
|
875
|
-
}),
|
|
873
|
+
const fe = n.map((J, he) => v[he] ? J : Ce(J, -window.scrollX, -window.scrollY));
|
|
874
|
+
t({ shapes: fe, text: W, ...ue });
|
|
875
|
+
}), de.addEventListener("click", () => {
|
|
876
876
|
H(), t(null);
|
|
877
877
|
}), requestAnimationFrame(() => M.focus());
|
|
878
878
|
}
|
|
879
|
-
const P =
|
|
879
|
+
const P = Me(
|
|
880
880
|
e,
|
|
881
881
|
(d) => {
|
|
882
882
|
r = d;
|
|
@@ -885,71 +885,71 @@ function Me(e) {
|
|
|
885
885
|
H(), t(null);
|
|
886
886
|
},
|
|
887
887
|
() => {
|
|
888
|
-
|
|
888
|
+
n.length !== 0 && (l && (l.remove(), l = null, x.style.pointerEvents = "auto", P.style.pointerEvents = "auto", s = !1), n.pop(), v.pop(), j());
|
|
889
889
|
}
|
|
890
890
|
);
|
|
891
891
|
e.appendChild(x);
|
|
892
|
-
const
|
|
892
|
+
const X = ["pointerdown", "pointermove", "pointerup", "pointercancel"], Y = ["mousedown", "mouseup", "click", "dblclick", "auxclick", "touchstart", "touchmove", "contextmenu", "dragstart", "selectstart"];
|
|
893
893
|
function V(d) {
|
|
894
894
|
const g = d.composedPath();
|
|
895
895
|
return g.includes(e.host) && !g.includes(x);
|
|
896
896
|
}
|
|
897
897
|
function G(d) {
|
|
898
|
-
V(d) || s && performance.now() >
|
|
898
|
+
V(d) || s && performance.now() > h || (d.preventDefault(), d.stopPropagation());
|
|
899
899
|
}
|
|
900
900
|
function K(d) {
|
|
901
901
|
if (s || V(d)) return;
|
|
902
902
|
d.stopPropagation();
|
|
903
903
|
const g = d;
|
|
904
|
-
d.type === "pointerdown" ?
|
|
904
|
+
d.type === "pointerdown" ? le(g) : d.type === "pointermove" ? pe(g) : d.type === "pointerup" ? ce(g) : d.type === "pointercancel" && (o = !1, i && (i.remove(), i = null));
|
|
905
905
|
}
|
|
906
|
-
function
|
|
906
|
+
function le(d) {
|
|
907
907
|
if (d.button === 0) {
|
|
908
908
|
d.preventDefault();
|
|
909
909
|
try {
|
|
910
910
|
x.setPointerCapture(d.pointerId);
|
|
911
911
|
} catch {
|
|
912
912
|
}
|
|
913
|
-
|
|
913
|
+
o = !0, m = Se(d.clientX, d.clientY, e.host), a = d.clientX + b().x, p = d.clientY + b().y, r === "pen" && (c = [{ x: a, y: p }]);
|
|
914
914
|
}
|
|
915
915
|
}
|
|
916
|
-
function
|
|
917
|
-
if (!
|
|
916
|
+
function pe(d) {
|
|
917
|
+
if (!o) return;
|
|
918
918
|
const g = d.clientX + b().x, y = d.clientY + b().y;
|
|
919
919
|
if (i && i.remove(), r === "pen")
|
|
920
|
-
c.push({ x: g, y }), i = B({ type: "pen", points: [...c], color: L, width:
|
|
920
|
+
c.push({ x: g, y }), i = B({ type: "pen", points: [...c], color: L, width: z });
|
|
921
921
|
else if (r === "rect") {
|
|
922
|
-
const f = { type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: Math.abs(g - a), height: Math.abs(y - p), color: L, strokeWidth:
|
|
922
|
+
const f = { type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: Math.abs(g - a), height: Math.abs(y - p), color: L, strokeWidth: z };
|
|
923
923
|
i = B(f);
|
|
924
924
|
} else if (r === "circle") {
|
|
925
|
-
const f = Math.abs(g - a) / 2, E = Math.abs(y - p) / 2, S = { type: "circle", cx: Math.min(a, g) + f, cy: Math.min(p, y) + E, rx: f, ry: E, color: L, strokeWidth:
|
|
925
|
+
const f = Math.abs(g - a) / 2, E = Math.abs(y - p) / 2, S = { type: "circle", cx: Math.min(a, g) + f, cy: Math.min(p, y) + E, rx: f, ry: E, color: L, strokeWidth: z };
|
|
926
926
|
i = B(S);
|
|
927
|
-
} else r === "arrow" && (i = B({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width:
|
|
928
|
-
i && (
|
|
927
|
+
} else r === "arrow" && (i = B({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width: z }));
|
|
928
|
+
i && (m ? C : w).appendChild(i);
|
|
929
929
|
}
|
|
930
|
-
function
|
|
931
|
-
if (!
|
|
932
|
-
|
|
930
|
+
function ce(d) {
|
|
931
|
+
if (!o) return;
|
|
932
|
+
h = performance.now() + 400, o = !1, i && (i.remove(), i = null);
|
|
933
933
|
const g = d.clientX + b().x, y = d.clientY + b().y;
|
|
934
934
|
let f = !1;
|
|
935
935
|
if (r === "pen" && c.length > 1)
|
|
936
|
-
|
|
936
|
+
n.push({ type: "pen", points: [...c], color: L, width: z }), c = [], f = !0;
|
|
937
937
|
else if (r === "rect") {
|
|
938
938
|
const E = Math.abs(g - a), S = Math.abs(y - p);
|
|
939
|
-
E > 4 && S > 4 && (
|
|
939
|
+
E > 4 && S > 4 && (n.push({ type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: E, height: S, color: L, strokeWidth: z }), f = !0);
|
|
940
940
|
} else if (r === "circle") {
|
|
941
941
|
const E = Math.abs(g - a) / 2, S = Math.abs(y - p) / 2;
|
|
942
|
-
E > 4 && S > 4 && (
|
|
943
|
-
} else r === "arrow" && Math.sqrt((g - a) ** 2 + (y - p) ** 2) > 10 && (
|
|
944
|
-
f && (v.push(
|
|
942
|
+
E > 4 && S > 4 && (n.push({ type: "circle", cx: Math.min(a, g) + E, cy: Math.min(p, y) + S, rx: E, ry: S, color: L, strokeWidth: z }), f = !0);
|
|
943
|
+
} else r === "arrow" && Math.sqrt((g - a) ** 2 + (y - p) ** 2) > 10 && (n.push({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width: z }), f = !0);
|
|
944
|
+
f && (v.push(m), j(), ae());
|
|
945
945
|
}
|
|
946
|
-
for (const d of
|
|
947
|
-
for (const d of
|
|
946
|
+
for (const d of X) window.addEventListener(d, K, { capture: !0, passive: !1 });
|
|
947
|
+
for (const d of Y) window.addEventListener(d, G, { capture: !0, passive: !1 });
|
|
948
948
|
});
|
|
949
949
|
}
|
|
950
|
-
function
|
|
951
|
-
const
|
|
952
|
-
return
|
|
950
|
+
function Me(e, t, r, n) {
|
|
951
|
+
const o = document.createElement("div");
|
|
952
|
+
return o.className = "ufp-toolbar", o.innerHTML = `
|
|
953
953
|
<span class="ufp-toolbar-label">Draw to annotate</span>
|
|
954
954
|
<div class="ufp-toolbar-sep"></div>
|
|
955
955
|
<button class="ufp-btn-icon active" data-tool="pen" title="Pen">
|
|
@@ -976,54 +976,54 @@ function Ae(e, t, r, o) {
|
|
|
976
976
|
</button>
|
|
977
977
|
<div class="ufp-toolbar-sep"></div>
|
|
978
978
|
<button class="ufp-btn ufp-btn-ghost" id="ufp-cancel-btn">Cancel</button>
|
|
979
|
-
`,
|
|
979
|
+
`, o.querySelectorAll("[data-tool]").forEach((a) => {
|
|
980
980
|
a.addEventListener("click", () => {
|
|
981
|
-
|
|
981
|
+
o.querySelectorAll("[data-tool]").forEach((p) => p.classList.remove("active")), a.classList.add("active"), t(a.dataset.tool);
|
|
982
982
|
});
|
|
983
|
-
}),
|
|
983
|
+
}), o.querySelector("#ufp-undo-btn").addEventListener("click", n), o.querySelector("#ufp-cancel-btn").addEventListener("click", r), e.appendChild(o), o;
|
|
984
984
|
}
|
|
985
985
|
function U(e) {
|
|
986
986
|
const t = Date.now() - e, r = Math.floor(t / 1e3);
|
|
987
987
|
if (r < 60) return "just now";
|
|
988
|
-
const
|
|
989
|
-
if (
|
|
990
|
-
const
|
|
991
|
-
if (
|
|
992
|
-
const a = Math.floor(
|
|
988
|
+
const n = Math.floor(r / 60);
|
|
989
|
+
if (n < 60) return `${n}m ago`;
|
|
990
|
+
const o = Math.floor(n / 60);
|
|
991
|
+
if (o < 24) return `${o}h ago`;
|
|
992
|
+
const a = Math.floor(o / 24);
|
|
993
993
|
return a < 7 ? `${a}d ago` : new Date(e).toLocaleDateString();
|
|
994
994
|
}
|
|
995
995
|
function D(e) {
|
|
996
996
|
return e.split(" ").filter(Boolean).slice(0, 2).map((t) => t[0].toUpperCase()).join("");
|
|
997
997
|
}
|
|
998
|
-
function
|
|
998
|
+
function T(e) {
|
|
999
999
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1000
1000
|
}
|
|
1001
|
-
function
|
|
1002
|
-
let
|
|
1001
|
+
function Ae(e, t, r, n) {
|
|
1002
|
+
let o = [...t];
|
|
1003
1003
|
const a = document.createElement("div");
|
|
1004
1004
|
a.className = "ufp-replies";
|
|
1005
|
-
const p = (
|
|
1005
|
+
const p = (m) => {
|
|
1006
1006
|
const b = a.querySelector(".ufp-replies-list");
|
|
1007
1007
|
b && b.remove();
|
|
1008
1008
|
const x = document.createElement("div");
|
|
1009
|
-
if (x.className = "ufp-replies-list", x.style.cssText = "display:flex;flex-direction:column;gap:12px;",
|
|
1009
|
+
if (x.className = "ufp-replies-list", x.style.cssText = "display:flex;flex-direction:column;gap:12px;", m.length > 0) {
|
|
1010
1010
|
const u = document.createElement("div");
|
|
1011
|
-
u.className = "ufp-replies-title", u.textContent = `${
|
|
1011
|
+
u.className = "ufp-replies-title", u.textContent = `${m.length} ${m.length === 1 ? "Reply" : "Replies"}`, x.appendChild(u), m.forEach((w) => {
|
|
1012
1012
|
const C = document.createElement("div");
|
|
1013
1013
|
C.className = "ufp-reply", C.innerHTML = `
|
|
1014
1014
|
<div class="ufp-reply-meta">
|
|
1015
1015
|
<div class="ufp-avatar" style="width:22px;height:22px;font-size:10px;">${D(w.authorName)}</div>
|
|
1016
|
-
<span class="ufp-reply-author">${
|
|
1016
|
+
<span class="ufp-reply-author">${T(w.authorName)}</span>
|
|
1017
1017
|
<span class="ufp-reply-time">${U(w.createdAt)}</span>
|
|
1018
1018
|
</div>
|
|
1019
|
-
<div class="ufp-reply-text">${
|
|
1019
|
+
<div class="ufp-reply-text">${T(w.text)}</div>
|
|
1020
1020
|
`, x.appendChild(C);
|
|
1021
1021
|
});
|
|
1022
1022
|
}
|
|
1023
1023
|
a.insertBefore(x, a.querySelector(".ufp-reply-input-area"));
|
|
1024
1024
|
}, c = document.createElement("div");
|
|
1025
1025
|
c.className = "ufp-reply-input-area";
|
|
1026
|
-
const i =
|
|
1026
|
+
const i = re();
|
|
1027
1027
|
c.innerHTML = `
|
|
1028
1028
|
<div class="ufp-reply-name-row">
|
|
1029
1029
|
<span class="ufp-reply-name-label">Replying as:</span>
|
|
@@ -1032,7 +1032,7 @@ function Te(e, t, r, o) {
|
|
|
1032
1032
|
id="ufp-reply-name"
|
|
1033
1033
|
type="text"
|
|
1034
1034
|
placeholder="Your name"
|
|
1035
|
-
value="${
|
|
1035
|
+
value="${T(i ?? "")}"
|
|
1036
1036
|
style="flex:1;"
|
|
1037
1037
|
/>
|
|
1038
1038
|
</div>
|
|
@@ -1047,30 +1047,30 @@ function Te(e, t, r, o) {
|
|
|
1047
1047
|
<button class="ufp-btn ufp-btn-primary" id="ufp-reply-submit" disabled style="font-size:13px;padding:7px 14px;">Reply</button>
|
|
1048
1048
|
</div>
|
|
1049
1049
|
`;
|
|
1050
|
-
const l = c.querySelector("#ufp-reply-name"), s = c.querySelector("#ufp-reply-text"),
|
|
1051
|
-
|
|
1050
|
+
const l = c.querySelector("#ufp-reply-name"), s = c.querySelector("#ufp-reply-text"), h = c.querySelector("#ufp-reply-submit"), v = () => {
|
|
1051
|
+
h.disabled = l.value.trim().length === 0 || s.value.trim().length === 0;
|
|
1052
1052
|
};
|
|
1053
|
-
return l.addEventListener("input", v), s.addEventListener("input", v),
|
|
1054
|
-
const
|
|
1055
|
-
if (!
|
|
1056
|
-
|
|
1053
|
+
return l.addEventListener("input", v), s.addEventListener("input", v), h.addEventListener("click", async () => {
|
|
1054
|
+
const m = l.value.trim(), b = s.value.trim();
|
|
1055
|
+
if (!m || !b) return;
|
|
1056
|
+
h.disabled = !0, h.textContent = "Sending…", ie(m);
|
|
1057
1057
|
const x = {
|
|
1058
1058
|
commentId: e,
|
|
1059
|
-
authorName:
|
|
1059
|
+
authorName: m,
|
|
1060
1060
|
text: b,
|
|
1061
1061
|
createdAt: Date.now()
|
|
1062
1062
|
};
|
|
1063
1063
|
try {
|
|
1064
1064
|
const w = { id: await r.addReply(x), ...x };
|
|
1065
|
-
s.value = "",
|
|
1065
|
+
s.value = "", h.textContent = "Reply", h.disabled = !0, o = [...o, w], p(o), n(w);
|
|
1066
1066
|
} catch (u) {
|
|
1067
|
-
console.error("[ui-feedback-plugin] Failed to save reply:", u),
|
|
1067
|
+
console.error("[ui-feedback-plugin] Failed to save reply:", u), h.disabled = !1, h.textContent = "Reply";
|
|
1068
1068
|
}
|
|
1069
|
-
}), a.appendChild(c), p(
|
|
1070
|
-
|
|
1069
|
+
}), a.appendChild(c), p(o), a.addReply = (m) => {
|
|
1070
|
+
o = [...o, m], p(o);
|
|
1071
1071
|
}, a;
|
|
1072
1072
|
}
|
|
1073
|
-
function ze(e, t, r,
|
|
1073
|
+
function ze(e, t, r, n, o, a, p, c) {
|
|
1074
1074
|
const i = document.createElement("div");
|
|
1075
1075
|
i.className = "ufp-detail", i.innerHTML = `
|
|
1076
1076
|
<div class="ufp-detail-image-area">
|
|
@@ -1105,11 +1105,11 @@ function ze(e, t, r, o, n, a, p, c) {
|
|
|
1105
1105
|
<div class="ufp-comment-meta">
|
|
1106
1106
|
<div class="ufp-avatar">${D(t.authorName)}</div>
|
|
1107
1107
|
<div>
|
|
1108
|
-
<div class="ufp-comment-author">${
|
|
1108
|
+
<div class="ufp-comment-author">${T(t.authorName)}</div>
|
|
1109
1109
|
<div class="ufp-comment-time">${U(t.createdAt)}</div>
|
|
1110
1110
|
</div>
|
|
1111
1111
|
</div>
|
|
1112
|
-
<div class="ufp-detail-comment-text">${
|
|
1112
|
+
<div class="ufp-detail-comment-text">${T(t.text)}</div>
|
|
1113
1113
|
<div class="ufp-detail-actions" id="ufp-detail-actions"></div>
|
|
1114
1114
|
</div>
|
|
1115
1115
|
<div id="ufp-detail-replies"></div>
|
|
@@ -1126,7 +1126,7 @@ function ze(e, t, r, o, n, a, p, c) {
|
|
|
1126
1126
|
style="vertical-align:middle;margin-right:4px"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/></svg>
|
|
1127
1127
|
Reopen
|
|
1128
1128
|
`, u.addEventListener("click", async () => {
|
|
1129
|
-
u.disabled = !0, u.textContent = "Reopening…", await
|
|
1129
|
+
u.disabled = !0, u.textContent = "Reopening…", await n.updateComment(t.id, { resolved: !1 }), a(t.id), i.remove(), k({ panelOpen: !0 });
|
|
1130
1130
|
}), l.appendChild(u);
|
|
1131
1131
|
} else {
|
|
1132
1132
|
const u = document.createElement("button");
|
|
@@ -1135,29 +1135,29 @@ function ze(e, t, r, o, n, a, p, c) {
|
|
|
1135
1135
|
style="vertical-align:middle;margin-right:4px"><polyline points="20 6 9 17 4 12"/></svg>
|
|
1136
1136
|
Mark Resolved
|
|
1137
1137
|
`, u.addEventListener("click", async () => {
|
|
1138
|
-
u.disabled = !0, u.textContent = "Resolving…", await
|
|
1138
|
+
u.disabled = !0, u.textContent = "Resolving…", await n.updateComment(t.id, { resolved: !0 }), o(t.id), i.remove(), k({ panelOpen: !0 });
|
|
1139
1139
|
}), l.appendChild(u);
|
|
1140
1140
|
}
|
|
1141
1141
|
const s = document.createElement("button");
|
|
1142
1142
|
s.className = "ufp-btn ufp-btn-ghost", s.style.fontSize = "13px", s.textContent = "Delete", s.addEventListener("click", async () => {
|
|
1143
|
-
confirm("Delete this comment and all its replies?") && (s.disabled = !0, await
|
|
1143
|
+
confirm("Delete this comment and all its replies?") && (s.disabled = !0, await n.deleteComment(t.id), p(t.id), i.remove(), k({ panelOpen: !0 }));
|
|
1144
1144
|
}), l.appendChild(s);
|
|
1145
|
-
const
|
|
1145
|
+
const h = i.querySelector("#ufp-detail-replies"), v = Ae(t.id, r, n, (u) => {
|
|
1146
1146
|
var w;
|
|
1147
1147
|
(w = v.addReply) == null || w.call(v, u), c == null || c(u);
|
|
1148
1148
|
});
|
|
1149
|
-
|
|
1150
|
-
const
|
|
1151
|
-
const u =
|
|
1152
|
-
b.setAttribute("viewBox", `0 0 ${u} ${w}`),
|
|
1149
|
+
h.appendChild(v);
|
|
1150
|
+
const m = i.querySelector(".ufp-detail-screenshot"), b = i.querySelector(".ufp-detail-annotation-svg"), x = () => {
|
|
1151
|
+
const u = m.clientWidth, w = m.clientHeight;
|
|
1152
|
+
b.setAttribute("viewBox", `0 0 ${u} ${w}`), ke(b, t.annotation, u, w), b.querySelectorAll("[marker-end]").forEach((C) => {
|
|
1153
1153
|
C.setAttribute("marker-end", "url(#ufp-detail-arrowhead)");
|
|
1154
1154
|
});
|
|
1155
1155
|
};
|
|
1156
|
-
|
|
1156
|
+
m.complete && m.naturalWidth > 0 ? x() : m.addEventListener("load", x);
|
|
1157
1157
|
}
|
|
1158
|
-
function
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1158
|
+
function Te(e, t, r) {
|
|
1159
|
+
const n = document.createElement("div");
|
|
1160
|
+
n.className = "ufp-panel", n.innerHTML = `
|
|
1161
1161
|
<div class="ufp-panel-header">
|
|
1162
1162
|
<span class="ufp-panel-title">Feedback</span>
|
|
1163
1163
|
<div style="display:flex;gap:8px;align-items:center;">
|
|
@@ -1177,19 +1177,19 @@ function Ne(e, t, r) {
|
|
|
1177
1177
|
<button class="ufp-filter-tab" data-filter="resolved">Resolved</button>
|
|
1178
1178
|
</div>
|
|
1179
1179
|
<div class="ufp-panel-list" id="ufp-comment-list"></div>
|
|
1180
|
-
`, e.appendChild(
|
|
1180
|
+
`, e.appendChild(n), n.querySelector("#ufp-panel-close").addEventListener("click", () => {
|
|
1181
1181
|
k({ panelOpen: !1 });
|
|
1182
|
-
}),
|
|
1182
|
+
}), n.querySelector("#ufp-new-feedback").addEventListener("click", () => {
|
|
1183
1183
|
k({ panelOpen: !1 }), r();
|
|
1184
|
-
}),
|
|
1184
|
+
}), n.querySelectorAll(".ufp-filter-tab").forEach((c) => {
|
|
1185
1185
|
c.addEventListener("click", () => {
|
|
1186
|
-
|
|
1186
|
+
n.querySelectorAll(".ufp-filter-tab").forEach((i) => i.classList.remove("active")), c.classList.add("active"), k({ filter: c.dataset.filter });
|
|
1187
1187
|
});
|
|
1188
1188
|
});
|
|
1189
|
-
const
|
|
1189
|
+
const o = n.querySelector("#ufp-comment-list"), a = /* @__PURE__ */ new Map(), p = async (c, i) => {
|
|
1190
1190
|
const l = c.filter((s) => i === "open" ? !s.resolved : s.resolved);
|
|
1191
|
-
if (
|
|
1192
|
-
|
|
1191
|
+
if (o.innerHTML = "", l.length === 0) {
|
|
1192
|
+
o.innerHTML = `
|
|
1193
1193
|
<div class="ufp-panel-empty">
|
|
1194
1194
|
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" opacity="0.4">
|
|
1195
1195
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
|
@@ -1207,30 +1207,30 @@ function Ne(e, t, r) {
|
|
|
1207
1207
|
} catch {
|
|
1208
1208
|
a.set(s.id, []);
|
|
1209
1209
|
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1210
|
+
o.appendChild(
|
|
1211
|
+
Ne(s, a, e, t)
|
|
1212
1212
|
);
|
|
1213
1213
|
}
|
|
1214
1214
|
};
|
|
1215
|
-
return
|
|
1216
|
-
|
|
1217
|
-
}),
|
|
1215
|
+
return oe(async (c) => {
|
|
1216
|
+
n.classList.toggle("open", c.panelOpen), c.panelOpen && await p(c.comments, c.filter);
|
|
1217
|
+
}), n;
|
|
1218
1218
|
}
|
|
1219
|
-
function
|
|
1219
|
+
function Ne(e, t, r, n, o) {
|
|
1220
1220
|
const a = t.get(e.id) ?? [], p = document.createElement("div");
|
|
1221
1221
|
return p.className = "ufp-comment-card", p.dataset.id = e.id, p.innerHTML = `
|
|
1222
1222
|
<div class="ufp-comment-card-header">
|
|
1223
1223
|
<div class="ufp-comment-meta">
|
|
1224
1224
|
<div class="ufp-avatar">${D(e.authorName)}</div>
|
|
1225
1225
|
<div>
|
|
1226
|
-
<div class="ufp-comment-author">${
|
|
1226
|
+
<div class="ufp-comment-author">${T(e.authorName)}</div>
|
|
1227
1227
|
<div class="ufp-comment-time">${U(e.createdAt)}</div>
|
|
1228
1228
|
</div>
|
|
1229
1229
|
</div>
|
|
1230
1230
|
${e.resolved ? '<span class="ufp-resolved-badge">Resolved</span>' : ""}
|
|
1231
1231
|
</div>
|
|
1232
1232
|
<img class="ufp-comment-thumbnail" src="${e.screenshotUrl}" alt="Screenshot" loading="lazy" />
|
|
1233
|
-
<div class="ufp-comment-text">${
|
|
1233
|
+
<div class="ufp-comment-text">${T(e.text)}</div>
|
|
1234
1234
|
<div class="ufp-comment-footer">
|
|
1235
1235
|
<span class="ufp-reply-count">
|
|
1236
1236
|
${a.length > 0 ? `${a.length} ${a.length === 1 ? "reply" : "replies"}` : "No replies yet — click to reply"}
|
|
@@ -1239,7 +1239,7 @@ function He(e, t, r, o, n) {
|
|
|
1239
1239
|
`, p.addEventListener("click", async () => {
|
|
1240
1240
|
let c = t.get(e.id) ?? [];
|
|
1241
1241
|
try {
|
|
1242
|
-
c = await
|
|
1242
|
+
c = await n.getReplies(e.id), t.set(e.id, c);
|
|
1243
1243
|
} catch (i) {
|
|
1244
1244
|
console.error("[ui-feedback-plugin] Failed to fetch replies:", i);
|
|
1245
1245
|
}
|
|
@@ -1247,7 +1247,7 @@ function He(e, t, r, o, n) {
|
|
|
1247
1247
|
r,
|
|
1248
1248
|
e,
|
|
1249
1249
|
c,
|
|
1250
|
-
|
|
1250
|
+
n,
|
|
1251
1251
|
(i) => {
|
|
1252
1252
|
const l = A();
|
|
1253
1253
|
k({ comments: l.comments.map((s) => s.id === i ? { ...s, resolved: !0 } : s) });
|
|
@@ -1270,111 +1270,106 @@ function He(e, t, r, o, n) {
|
|
|
1270
1270
|
);
|
|
1271
1271
|
}), p;
|
|
1272
1272
|
}
|
|
1273
|
-
async function
|
|
1273
|
+
async function He() {
|
|
1274
1274
|
try {
|
|
1275
|
-
const e = await
|
|
1276
|
-
return await
|
|
1275
|
+
const e = await $e();
|
|
1276
|
+
return await Be(e);
|
|
1277
1277
|
} catch (e) {
|
|
1278
|
-
return console.error("[ui-feedback-plugin] capturePageScreenshot failed:", e),
|
|
1278
|
+
return console.error("[ui-feedback-plugin] capturePageScreenshot failed:", e), Re();
|
|
1279
1279
|
}
|
|
1280
1280
|
}
|
|
1281
|
-
async function
|
|
1281
|
+
async function $e() {
|
|
1282
1282
|
return (await import("./html2canvas-pro.esm-QETbiPYt.mjs")).default;
|
|
1283
1283
|
}
|
|
1284
|
-
async function
|
|
1285
|
-
const t =
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
ignoreElements: (n) => n.tagName === "UI-FEEDBACK-PLUGIN"
|
|
1300
|
-
})).toDataURL("image/png");
|
|
1301
|
-
} finally {
|
|
1302
|
-
window.scrollTo(t, r);
|
|
1303
|
-
}
|
|
1284
|
+
async function Be(e) {
|
|
1285
|
+
const t = document.documentElement.clientWidth, r = window.innerHeight;
|
|
1286
|
+
return (await e(document.body, {
|
|
1287
|
+
allowTaint: !1,
|
|
1288
|
+
useCORS: !0,
|
|
1289
|
+
logging: !1,
|
|
1290
|
+
scale: Math.min(window.devicePixelRatio, 2),
|
|
1291
|
+
x: window.scrollX,
|
|
1292
|
+
y: window.scrollY,
|
|
1293
|
+
width: t,
|
|
1294
|
+
height: r,
|
|
1295
|
+
windowWidth: t,
|
|
1296
|
+
windowHeight: r,
|
|
1297
|
+
ignoreElements: (o) => o.tagName === "UI-FEEDBACK-PLUGIN"
|
|
1298
|
+
})).toDataURL("image/png");
|
|
1304
1299
|
}
|
|
1305
|
-
function
|
|
1300
|
+
function Re() {
|
|
1306
1301
|
const e = document.createElement("canvas");
|
|
1307
1302
|
e.width = window.innerWidth, e.height = window.innerHeight;
|
|
1308
1303
|
const t = e.getContext("2d");
|
|
1309
1304
|
return t.fillStyle = "#f3f4f6", t.fillRect(0, 0, e.width, e.height), t.fillStyle = "#9ca3af", t.font = "16px -apple-system, sans-serif", t.textAlign = "center", t.fillText("Screenshot unavailable", e.width / 2, e.height / 2), e.toDataURL("image/png");
|
|
1310
1305
|
}
|
|
1311
|
-
async function
|
|
1306
|
+
async function We(e, t) {
|
|
1312
1307
|
try {
|
|
1313
1308
|
const r = await new Promise((i, l) => {
|
|
1314
1309
|
const s = new Image();
|
|
1315
1310
|
s.onload = () => i(s), s.onerror = () => l(new Error("screenshot failed to load")), s.src = e;
|
|
1316
|
-
}),
|
|
1317
|
-
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1320
|
-
const a =
|
|
1321
|
-
|
|
1311
|
+
}), n = document.createElement("canvas");
|
|
1312
|
+
n.width = r.naturalWidth, n.height = r.naturalHeight;
|
|
1313
|
+
const o = n.getContext("2d");
|
|
1314
|
+
o.drawImage(r, 0, 0);
|
|
1315
|
+
const a = n.width / t.pageWidth, p = n.height / t.pageHeight, c = Math.min(a, p);
|
|
1316
|
+
o.lineCap = "round", o.lineJoin = "round";
|
|
1322
1317
|
for (const i of t.shapes)
|
|
1323
|
-
switch (
|
|
1318
|
+
switch (o.strokeStyle = i.color, o.fillStyle = i.color, o.beginPath(), i.type) {
|
|
1324
1319
|
case "pen": {
|
|
1325
|
-
|
|
1320
|
+
o.lineWidth = i.width * c, i.points.forEach((l, s) => s === 0 ? o.moveTo(l.x * a, l.y * p) : o.lineTo(l.x * a, l.y * p)), o.stroke();
|
|
1326
1321
|
break;
|
|
1327
1322
|
}
|
|
1328
1323
|
case "rect": {
|
|
1329
|
-
|
|
1324
|
+
o.lineWidth = i.strokeWidth * c, o.roundRect(i.x * a, i.y * p, i.width * a, i.height * p, 3 * c), o.stroke();
|
|
1330
1325
|
break;
|
|
1331
1326
|
}
|
|
1332
1327
|
case "circle": {
|
|
1333
|
-
|
|
1328
|
+
o.lineWidth = i.strokeWidth * c, o.ellipse(i.cx * a, i.cy * p, i.rx * a, i.ry * p, 0, 0, Math.PI * 2), o.stroke();
|
|
1334
1329
|
break;
|
|
1335
1330
|
}
|
|
1336
1331
|
case "arrow": {
|
|
1337
|
-
const l = i.width * c, s = i.x1 * a,
|
|
1338
|
-
|
|
1339
|
-
const b = Math.hypot(v - s,
|
|
1340
|
-
|
|
1332
|
+
const l = i.width * c, s = i.x1 * a, h = i.y1 * p, v = i.x2 * a, m = i.y2 * p;
|
|
1333
|
+
o.lineWidth = l, o.lineCap = "butt", o.moveTo(s, h), o.lineTo(v, m), o.stroke(), o.lineCap = "round";
|
|
1334
|
+
const b = Math.hypot(v - s, m - h) || 1, x = (v - s) / b, u = (m - h) / b, w = v + x * l, C = m + u * l, N = w - x * 10 * l, H = C - u * 10 * l;
|
|
1335
|
+
o.beginPath(), o.moveTo(w, C), o.lineTo(N - u * 3.5 * l, H + x * 3.5 * l), o.lineTo(N + u * 3.5 * l, H - x * 3.5 * l), o.closePath(), o.fill();
|
|
1341
1336
|
break;
|
|
1342
1337
|
}
|
|
1343
1338
|
}
|
|
1344
|
-
return
|
|
1339
|
+
return n.toDataURL("image/png");
|
|
1345
1340
|
} catch (r) {
|
|
1346
1341
|
return console.error("[ui-feedback-plugin] drawAnnotationsOnScreenshot failed:", r), e;
|
|
1347
1342
|
}
|
|
1348
1343
|
}
|
|
1349
1344
|
const F = "ui-feedback-plugin";
|
|
1350
|
-
async function
|
|
1345
|
+
async function Oe(e) {
|
|
1351
1346
|
const { backend: t } = e;
|
|
1352
1347
|
if (t.provider === "firebase") {
|
|
1353
|
-
const { FirebaseAdapter: r } = await import("./firebase-BGU5KpRU.mjs"),
|
|
1354
|
-
return { db:
|
|
1348
|
+
const { FirebaseAdapter: r } = await import("./firebase-BGU5KpRU.mjs"), n = new r(t);
|
|
1349
|
+
return { db: n, screenshot: n };
|
|
1355
1350
|
}
|
|
1356
1351
|
if (t.provider === "supabase") {
|
|
1357
|
-
const { SupabaseAdapter: r } = await import("./supabase-BUHP2OkK.mjs"),
|
|
1358
|
-
return { db:
|
|
1352
|
+
const { SupabaseAdapter: r } = await import("./supabase-BUHP2OkK.mjs"), n = new r(t.url, t.anonKey);
|
|
1353
|
+
return { db: n, screenshot: n };
|
|
1359
1354
|
}
|
|
1360
1355
|
if (t.provider === "aws") {
|
|
1361
|
-
const { AWSAdapter: r } = await import("./aws-DyQmIBI9.mjs"),
|
|
1362
|
-
return { db:
|
|
1356
|
+
const { AWSAdapter: r } = await import("./aws-DyQmIBI9.mjs"), n = new r(t);
|
|
1357
|
+
return { db: n, screenshot: n };
|
|
1363
1358
|
}
|
|
1364
1359
|
if (t.provider === "local") {
|
|
1365
|
-
const { LocalAdapter: r } = await import("./local-CqZPr-Eb.mjs"),
|
|
1366
|
-
return { db:
|
|
1360
|
+
const { LocalAdapter: r } = await import("./local-CqZPr-Eb.mjs"), n = new r();
|
|
1361
|
+
return { db: n, screenshot: n };
|
|
1367
1362
|
}
|
|
1368
1363
|
throw new Error("[ui-feedback-plugin] Unknown backend provider");
|
|
1369
1364
|
}
|
|
1370
|
-
function
|
|
1365
|
+
function Pe(e) {
|
|
1371
1366
|
var p;
|
|
1372
1367
|
if (customElements.get(F))
|
|
1373
1368
|
return console.warn("[ui-feedback-plugin] Already initialized."), () => {
|
|
1374
1369
|
};
|
|
1375
|
-
const t = ((p = e.theme) == null ? void 0 : p.primaryColor) ?? "#6366f1", r = e.projectKey ?? "default",
|
|
1370
|
+
const t = ((p = e.theme) == null ? void 0 : p.primaryColor) ?? "#6366f1", r = e.projectKey ?? "default", n = e.position ?? "bottom-right";
|
|
1376
1371
|
k({ config: e });
|
|
1377
|
-
class
|
|
1372
|
+
class o extends HTMLElement {
|
|
1378
1373
|
constructor() {
|
|
1379
1374
|
super();
|
|
1380
1375
|
O(this, "shadow");
|
|
@@ -1385,9 +1380,9 @@ function Fe(e) {
|
|
|
1385
1380
|
}
|
|
1386
1381
|
async connectedCallback() {
|
|
1387
1382
|
const l = document.createElement("style");
|
|
1388
|
-
l.textContent =
|
|
1383
|
+
l.textContent = xe(t), this.shadow.appendChild(l);
|
|
1389
1384
|
try {
|
|
1390
|
-
const s = await
|
|
1385
|
+
const s = await Oe(e);
|
|
1391
1386
|
this.db = s.db, this.screenshot = s.screenshot;
|
|
1392
1387
|
} catch (s) {
|
|
1393
1388
|
console.error("[ui-feedback-plugin] Failed to initialise backend:", s);
|
|
@@ -1400,10 +1395,10 @@ function Fe(e) {
|
|
|
1400
1395
|
(l = this.unsubscribe) == null || l.call(this);
|
|
1401
1396
|
}
|
|
1402
1397
|
mount() {
|
|
1403
|
-
const l =
|
|
1404
|
-
|
|
1398
|
+
const l = Q(window.location.href);
|
|
1399
|
+
Te(this.shadow, this.db, () => this.startAnnotation()), ve(
|
|
1405
1400
|
this.shadow,
|
|
1406
|
-
|
|
1401
|
+
n,
|
|
1407
1402
|
() => this.startAnnotation(),
|
|
1408
1403
|
() => k({ panelOpen: !A().panelOpen })
|
|
1409
1404
|
), this.unsubscribe = this.db.subscribeToComments(l, r, (s) => {
|
|
@@ -1411,11 +1406,11 @@ function Fe(e) {
|
|
|
1411
1406
|
});
|
|
1412
1407
|
}
|
|
1413
1408
|
async startAnnotation() {
|
|
1414
|
-
let l =
|
|
1415
|
-
if (!l && (l = await
|
|
1409
|
+
let l = re();
|
|
1410
|
+
if (!l && (l = await we(this.shadow), !l))
|
|
1416
1411
|
return;
|
|
1417
1412
|
k({ active: !0, panelOpen: !1 });
|
|
1418
|
-
const s = await
|
|
1413
|
+
const s = await Le(this.shadow);
|
|
1419
1414
|
if (!s) {
|
|
1420
1415
|
k({ active: !1 });
|
|
1421
1416
|
return;
|
|
@@ -1423,57 +1418,58 @@ function Fe(e) {
|
|
|
1423
1418
|
k({ active: !1 }), this.showToast("Saving comment…", "info");
|
|
1424
1419
|
try {
|
|
1425
1420
|
await this.saveComment(l, s.text, s.shapes), this.showToast("Comment saved!", "success");
|
|
1426
|
-
} catch (
|
|
1427
|
-
console.error("[ui-feedback-plugin] Failed to save comment:",
|
|
1421
|
+
} catch (h) {
|
|
1422
|
+
console.error("[ui-feedback-plugin] Failed to save comment:", h), this.showToast("Failed to save — check the browser console for details.", "error");
|
|
1428
1423
|
return;
|
|
1429
1424
|
}
|
|
1430
1425
|
k({ panelOpen: !0 });
|
|
1431
1426
|
}
|
|
1432
|
-
async saveComment(l, s,
|
|
1433
|
-
const v =
|
|
1434
|
-
shapes:
|
|
1435
|
-
|
|
1436
|
-
|
|
1427
|
+
async saveComment(l, s, h) {
|
|
1428
|
+
const v = Q(window.location.href), m = {
|
|
1429
|
+
shapes: h,
|
|
1430
|
+
// Shapes are in viewport coordinates; the screenshot covers just the visible viewport.
|
|
1431
|
+
pageWidth: document.documentElement.clientWidth,
|
|
1432
|
+
pageHeight: window.innerHeight
|
|
1437
1433
|
};
|
|
1438
1434
|
this.style.visibility = "hidden";
|
|
1439
1435
|
let b;
|
|
1440
1436
|
try {
|
|
1441
|
-
b = await
|
|
1437
|
+
b = await He();
|
|
1442
1438
|
} finally {
|
|
1443
1439
|
this.style.visibility = "";
|
|
1444
1440
|
}
|
|
1445
|
-
b = await
|
|
1441
|
+
b = await We(b, m);
|
|
1446
1442
|
const x = {
|
|
1447
1443
|
pageUrl: v,
|
|
1448
1444
|
projectKey: r,
|
|
1449
1445
|
authorName: l,
|
|
1450
1446
|
text: s,
|
|
1451
1447
|
screenshotUrl: "",
|
|
1452
|
-
annotation:
|
|
1448
|
+
annotation: m,
|
|
1453
1449
|
resolved: !1,
|
|
1454
1450
|
createdAt: Date.now()
|
|
1455
1451
|
}, u = await this.db.addComment(x), w = await this.screenshot.uploadScreenshot(u, b);
|
|
1456
1452
|
await this.db.updateComment(u, { screenshotUrl: w });
|
|
1457
1453
|
}
|
|
1458
1454
|
showToast(l, s) {
|
|
1459
|
-
const
|
|
1460
|
-
|
|
1461
|
-
const v = { info: "#6366f1", success: "#10b981", error: "#ef4444" },
|
|
1462
|
-
|
|
1455
|
+
const h = this.shadow.querySelector(".ufp-toast");
|
|
1456
|
+
h == null || h.remove();
|
|
1457
|
+
const v = { info: "#6366f1", success: "#10b981", error: "#ef4444" }, m = document.createElement("div");
|
|
1458
|
+
m.className = "ufp-toast", m.style.cssText = `
|
|
1463
1459
|
position:fixed;bottom:80px;left:50%;transform:translateX(-50%);
|
|
1464
1460
|
background:${v[s]};color:white;padding:10px 20px;border-radius:8px;
|
|
1465
1461
|
font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
|
|
1466
1462
|
font-size:13px;font-weight:500;z-index:2147483647;
|
|
1467
1463
|
box-shadow:0 4px 12px rgba(0,0,0,0.2);pointer-events:none;
|
|
1468
1464
|
max-width:360px;text-align:center;
|
|
1469
|
-
`,
|
|
1465
|
+
`, m.textContent = l, this.shadow.appendChild(m), setTimeout(() => m.remove(), s === "error" ? 6e3 : 2500);
|
|
1470
1466
|
}
|
|
1471
1467
|
}
|
|
1472
|
-
customElements.define(F,
|
|
1468
|
+
customElements.define(F, o);
|
|
1473
1469
|
const a = document.createElement(F);
|
|
1474
1470
|
return document.body.appendChild(a), () => a.remove();
|
|
1475
1471
|
}
|
|
1476
1472
|
export {
|
|
1477
|
-
|
|
1473
|
+
Pe as initFeedbackPlugin
|
|
1478
1474
|
};
|
|
1479
1475
|
//# sourceMappingURL=ui-feedback-plugin.es.js.map
|