@sphoro/bugcatch-web-sdk 0.19.0 → 0.21.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.
- package/README.md +54 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-core.es.js +652 -497
- package/dist/bugcatch-core.es.js.map +1 -1
- package/dist/bugcatch-panel.es.js +1307 -964
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +291 -158
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +284 -151
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +8 -8
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/feedback.js +94 -0
- package/src/identity.js +1 -1
- package/src/index.d.ts +65 -6
- package/src/index.js +111 -7
- package/src/panel/call.js +3 -2
- package/src/panel/compose.js +8 -4
- package/src/panel/feedback.js +205 -0
- package/src/panel/icons.js +6 -0
- package/src/panel/index.js +91 -12
- package/src/panel/rate-due.js +155 -0
- package/src/panel/rating.js +87 -0
- package/src/panel/signin.js +1 -1
- package/src/panel/styles.js +75 -0
- package/src/panel/thread.js +3 -72
- package/src/widget.js +14 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { s as
|
|
2
|
-
const Ve = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>', je = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>', fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>', de = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>', ge = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>', Oe = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', Ne = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>', ae = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>', Be = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>', We = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>', me = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>', Ye = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>', Pe = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', Fe = `
|
|
1
|
+
import { s as qe, m as Ee, a as Me, c as pe, b as ze, d as Ce, R as me, h as K, n as Ae, e as He, f as Ie, g as ae, i as P, j as F, r as Re, v as De, k as je, S as Ve, U as Oe, l as Be, o as Ne, p as Fe, M as We, F as Ye } from "./bugcatch-core.es.js";
|
|
2
|
+
const Ke = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>', Pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>', ve = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>', he = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>', ce = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>', Ue = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', _e = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>', oe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>', Ze = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>', Ge = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>', Xe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>', ye = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>', Je = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>', et = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', tt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 5.5h15a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1h-8l-4.3 3.2a.5.5 0 0 1-.8-.4v-2.8H4.5a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1z"/><path d="M12 8.4l.9 1.9 2 .3-1.5 1.4.4 2-1.8-1-1.8 1 .4-2-1.5-1.4 2-.3z"/></svg>', at = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17.5h6M10 21h4"/><path d="M12 3a6 6 0 0 0-3.6 10.8c.6.5 1 1.2 1 2V17h5.2v-1.2c0-.8.4-1.5 1-2A6 6 0 0 0 12 3z"/></svg>', rt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20s-7.5-4.6-7.5-10.2A4.3 4.3 0 0 1 12 7.2a4.3 4.3 0 0 1 7.5 2.6C19.5 15.4 12 20 12 20z"/></svg>', ot = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9.6 9.4a2.5 2.5 0 0 1 4.8.9c0 1.7-2.4 2.2-2.4 3.6M12 17h.01"/></svg>', nt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.8" stroke-linecap="round"><path d="M6.5 12h.01M12 12h.01M17.5 12h.01"/></svg>', it = `
|
|
3
3
|
@keyframes bc-fade-in { from { opacity: 0 } to { opacity: 1 } }
|
|
4
4
|
@keyframes bc-fade-out { to { opacity: 0 } }
|
|
5
5
|
@keyframes bc-panel-in { from { opacity: 0; transform: translateY(14px) scale(.965) } to { opacity: 1; transform: none } }
|
|
@@ -297,6 +297,53 @@ textarea { min-height: 76px; resize: vertical; }
|
|
|
297
297
|
.seg button[aria-pressed=true]::before { opacity: 1; }
|
|
298
298
|
.seg button:focus-visible { outline-offset: -2px; }
|
|
299
299
|
|
|
300
|
+
/* ---------- report a bug, or give feedback ----------
|
|
301
|
+
The same stone track as the severity control, two wide segments, under the
|
|
302
|
+
header so it stays put while the form scrolls. Each form's own parts carry
|
|
303
|
+
bug-only or fb-only; the other screens (history, a conversation, a call)
|
|
304
|
+
carry neither, so a mode left on the panel cannot hide anything of theirs. */
|
|
305
|
+
.modes {
|
|
306
|
+
flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
|
|
307
|
+
margin: 12px var(--bc-pad) 0; padding: 3px; background: var(--bc-stone); border-radius: 999px;
|
|
308
|
+
}
|
|
309
|
+
.modes button {
|
|
310
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-width: 0;
|
|
311
|
+
height: 32px; padding: 0 8px; font: inherit; font-size: var(--bc-fs-sm); font-weight: 520; line-height: 1; white-space: nowrap;
|
|
312
|
+
color: var(--bc-muted); background: none; border: none; border-radius: 999px;
|
|
313
|
+
cursor: pointer; transition: background 180ms var(--bc-ease), color 180ms, box-shadow 180ms;
|
|
314
|
+
}
|
|
315
|
+
.modes button svg { font-size: 15px; flex: none; }
|
|
316
|
+
.modes button:hover { color: var(--bc-fg); }
|
|
317
|
+
.modes button[aria-pressed=true] {
|
|
318
|
+
background: var(--bc-raised); color: var(--bc-fg); font-weight: 600;
|
|
319
|
+
box-shadow: 0 1px 2px rgba(20,18,14,.10), 0 0 0 .5px rgba(20,18,14,.08);
|
|
320
|
+
}
|
|
321
|
+
.modes button:focus-visible { outline-offset: -2px; }
|
|
322
|
+
.panel[data-mode="feedback"] .bug-only,
|
|
323
|
+
.panel:not([data-mode="feedback"]) .fb-only { display: none !important; }
|
|
324
|
+
|
|
325
|
+
/* ---------- feedback ---------- */
|
|
326
|
+
.feedback { animation: bc-fade-in 200ms ease both; }
|
|
327
|
+
.feedback textarea { min-height: 96px; }
|
|
328
|
+
.feedback .kinds { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
329
|
+
.feedback .kinds .tool[aria-pressed=true] { background: var(--bc-accent); border-color: var(--bc-accent); color: var(--bc-on-accent); }
|
|
330
|
+
.feedback .kinds .tool[aria-pressed=true] svg { color: currentColor; }
|
|
331
|
+
.faces { display: flex; gap: 6px; }
|
|
332
|
+
.face {
|
|
333
|
+
flex: 1 1 0; display: grid; place-items: center; height: 42px; padding: 0;
|
|
334
|
+
font: inherit; font-size: 24px; color: var(--bc-muted); background: var(--bc-stone);
|
|
335
|
+
border: 1px solid transparent; border-radius: var(--bc-r-md); cursor: pointer;
|
|
336
|
+
transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
337
|
+
}
|
|
338
|
+
.face:hover { color: var(--bc-fg); background: color-mix(in srgb, var(--bc-fg) 8%, var(--bc-stone)); }
|
|
339
|
+
.face:active { transform: scale(.94); }
|
|
340
|
+
.face[aria-pressed=true] { color: var(--bc-on-accent); background: var(--bc-accent); }
|
|
341
|
+
.face:focus-visible { outline-offset: 2px; }
|
|
342
|
+
.face-word { font-weight: 560; color: var(--bc-muted); }
|
|
343
|
+
.fb-as { margin: 0; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted); }
|
|
344
|
+
.fb-as strong { color: var(--bc-fg); font-weight: 600; word-break: break-all; }
|
|
345
|
+
.fb-who:empty { display: none; }
|
|
346
|
+
|
|
300
347
|
/* ---------- attachments ----------
|
|
301
348
|
Three ring pills in a row: optional, so they take one line, not a band of
|
|
302
349
|
dashed drop zones. */
|
|
@@ -822,6 +869,34 @@ button.quiet:hover { color: var(--bc-fg); text-decoration-color: color-mix(in sr
|
|
|
822
869
|
.history .sub .rated svg { width: 11px; height: 11px; color: #f0a81c; }
|
|
823
870
|
.history .sub .rate-ask { color: var(--bc-fg); font-weight: 600; }
|
|
824
871
|
|
|
872
|
+
/* ---------- a settled report waiting for its rating ----------
|
|
873
|
+
Above the form on the first screen: the same stars as under a report's
|
|
874
|
+
conversation, with the report they are about named on top. */
|
|
875
|
+
.rate-due { margin: 0 0 14px; }
|
|
876
|
+
.rate-due:focus { outline: none; }
|
|
877
|
+
.rate-due:focus-visible { box-shadow: var(--bc-ring); }
|
|
878
|
+
.rate-due .rd-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
|
|
879
|
+
.rate-due .rd-eyebrow {
|
|
880
|
+
font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--bc-faint);
|
|
881
|
+
}
|
|
882
|
+
.rate-due.is-required .rd-eyebrow { color: var(--bc-fg); }
|
|
883
|
+
.rate-due .rd-later { font-size: var(--bc-fs-xs); color: var(--bc-muted); }
|
|
884
|
+
.rate-due .rd-report {
|
|
885
|
+
display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 9px; align-items: center;
|
|
886
|
+
margin: 0 0 10px; padding: 0 0 10px; border-bottom: 1px solid var(--bc-border);
|
|
887
|
+
}
|
|
888
|
+
.rate-due .rd-ico {
|
|
889
|
+
grid-row: span 2; display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 999px;
|
|
890
|
+
background: color-mix(in srgb, var(--bc-ok) 14%, transparent); color: var(--bc-ok);
|
|
891
|
+
}
|
|
892
|
+
.rate-due .rd-ico svg { width: 13px; height: 13px; }
|
|
893
|
+
.rate-due .rd-ttl { font-weight: 620; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
894
|
+
.rate-due .rd-sub { font-size: var(--bc-fs-xs); color: var(--bc-muted); }
|
|
895
|
+
|
|
896
|
+
/* What a required rating is holding: still in sight, plainly not yet. */
|
|
897
|
+
.held { opacity: .42; transition: opacity 200ms ease; }
|
|
898
|
+
@media (prefers-reduced-motion: reduce) { .held { transition: none; } }
|
|
899
|
+
|
|
825
900
|
/* A call in progress, in place of the form.
|
|
826
901
|
---------------------------------------------------------------------------
|
|
827
902
|
Deliberately not styled as a chat. Nothing arrives here to read — the
|
|
@@ -1005,31 +1080,31 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1005
1080
|
.tool:hover:not(:disabled) { transform: none; }
|
|
1006
1081
|
}
|
|
1007
1082
|
`;
|
|
1008
|
-
function
|
|
1083
|
+
function de({ title: e, sub: t, id: o = "", back: d = !1, theme: l = "" }) {
|
|
1009
1084
|
return `
|
|
1010
1085
|
<div class="head">
|
|
1011
|
-
${
|
|
1086
|
+
${d ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${_e}</button>` : ""}
|
|
1012
1087
|
<span class="orb mark" aria-hidden="true"></span>
|
|
1013
1088
|
<div class="titles">
|
|
1014
|
-
<h2${
|
|
1089
|
+
<h2${o ? ` id="${o}"` : ""}>${v(e)}</h2>
|
|
1015
1090
|
<p>${v(t)}</p>
|
|
1016
1091
|
</div>
|
|
1017
|
-
${
|
|
1018
|
-
aria-label="Theme: ${v(
|
|
1019
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
1092
|
+
${l ? `<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${v(l)}"
|
|
1093
|
+
aria-label="Theme: ${v(l)}. Change theme"><span class="m-light">${qe}</span><span class="m-dark">${Ee}</span><span class="m-auto">${Me}</span></button>` : ""}
|
|
1094
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${pe}</button>
|
|
1020
1095
|
</div>`;
|
|
1021
1096
|
}
|
|
1022
|
-
function
|
|
1097
|
+
function ie(e, t) {
|
|
1023
1098
|
return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${v(e)}</div>`;
|
|
1024
1099
|
}
|
|
1025
|
-
function
|
|
1100
|
+
function st(e) {
|
|
1026
1101
|
return Array.from({ length: e }, () => `
|
|
1027
1102
|
<div class="row" aria-hidden="true">
|
|
1028
1103
|
<span class="row-ico"></span>
|
|
1029
1104
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
1030
1105
|
</div>`).join("") + '<span class="sr-only">Loading…</span>';
|
|
1031
1106
|
}
|
|
1032
|
-
function
|
|
1107
|
+
function lt() {
|
|
1033
1108
|
return `
|
|
1034
1109
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
1035
1110
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
@@ -1038,7 +1113,7 @@ function Ue() {
|
|
|
1038
1113
|
</div>
|
|
1039
1114
|
<span class="sr-only">Loading…</span>`;
|
|
1040
1115
|
}
|
|
1041
|
-
function
|
|
1116
|
+
function ct(e) {
|
|
1042
1117
|
const t = String(e).trim().split(/\s+/).filter(Boolean);
|
|
1043
1118
|
return t.length ? (t[0][0] + (t.length > 1 ? t[t.length - 1][0] : "")).toUpperCase() : "?";
|
|
1044
1119
|
}
|
|
@@ -1046,22 +1121,22 @@ function Z(e) {
|
|
|
1046
1121
|
const t = new Date(e);
|
|
1047
1122
|
return Number.isFinite(t.getTime()) ? `${t.getFullYear()}-${t.getMonth()}-${t.getDate()}` : null;
|
|
1048
1123
|
}
|
|
1049
|
-
function
|
|
1050
|
-
const t = new Date(e),
|
|
1051
|
-
if (Z(t) === Z(
|
|
1052
|
-
if (Z(t) === Z(
|
|
1124
|
+
function dt(e) {
|
|
1125
|
+
const t = new Date(e), o = /* @__PURE__ */ new Date(), d = new Date(o.getFullYear(), o.getMonth(), o.getDate() - 1);
|
|
1126
|
+
if (Z(t) === Z(o)) return "Today";
|
|
1127
|
+
if (Z(t) === Z(d)) return "Yesterday";
|
|
1053
1128
|
try {
|
|
1054
1129
|
return t.toLocaleDateString(void 0, {
|
|
1055
1130
|
weekday: "short",
|
|
1056
1131
|
day: "numeric",
|
|
1057
1132
|
month: "short",
|
|
1058
|
-
...t.getFullYear() !==
|
|
1133
|
+
...t.getFullYear() !== o.getFullYear() ? { year: "numeric" } : {}
|
|
1059
1134
|
});
|
|
1060
1135
|
} catch {
|
|
1061
|
-
return
|
|
1136
|
+
return X(e);
|
|
1062
1137
|
}
|
|
1063
1138
|
}
|
|
1064
|
-
function
|
|
1139
|
+
function xe(e) {
|
|
1065
1140
|
const t = new Date(e);
|
|
1066
1141
|
if (!Number.isFinite(t.getTime())) return "";
|
|
1067
1142
|
try {
|
|
@@ -1070,14 +1145,14 @@ function ve(e) {
|
|
|
1070
1145
|
return "";
|
|
1071
1146
|
}
|
|
1072
1147
|
}
|
|
1073
|
-
function
|
|
1148
|
+
function be(e) {
|
|
1074
1149
|
return e.scrollHeight - e.scrollTop - e.clientHeight < 40;
|
|
1075
1150
|
}
|
|
1076
|
-
function
|
|
1077
|
-
const
|
|
1078
|
-
t && !
|
|
1151
|
+
function G(e, { smooth: t = !1 } = {}) {
|
|
1152
|
+
const o = typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1153
|
+
t && !o && e.scrollTo ? e.scrollTo({ top: e.scrollHeight, behavior: "smooth" }) : e.scrollTop = e.scrollHeight;
|
|
1079
1154
|
}
|
|
1080
|
-
function
|
|
1155
|
+
function se(e) {
|
|
1081
1156
|
return {
|
|
1082
1157
|
OPEN: "Open",
|
|
1083
1158
|
IN_PROGRESS: "In progress",
|
|
@@ -1085,54 +1160,54 @@ function ie(e) {
|
|
|
1085
1160
|
CLOSED: "Closed"
|
|
1086
1161
|
}[e] || String(e || "").toLowerCase();
|
|
1087
1162
|
}
|
|
1088
|
-
function
|
|
1163
|
+
function X(e) {
|
|
1089
1164
|
const t = new Date(e).getTime();
|
|
1090
1165
|
if (!Number.isFinite(t)) return "";
|
|
1091
|
-
const
|
|
1092
|
-
if (
|
|
1093
|
-
if (
|
|
1094
|
-
if (
|
|
1095
|
-
const
|
|
1096
|
-
return
|
|
1166
|
+
const o = Math.floor((Date.now() - t) / 864e5);
|
|
1167
|
+
if (o <= 0) return "today";
|
|
1168
|
+
if (o === 1) return "yesterday";
|
|
1169
|
+
if (o < 30) return `${o} days ago`;
|
|
1170
|
+
const d = Math.floor(o / 30);
|
|
1171
|
+
return d === 1 ? "a month ago" : `${d} months ago`;
|
|
1097
1172
|
}
|
|
1098
1173
|
function v(e) {
|
|
1099
1174
|
return String(e).replace(/[&<>"']/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[t]);
|
|
1100
1175
|
}
|
|
1101
|
-
const
|
|
1102
|
-
let
|
|
1103
|
-
function
|
|
1104
|
-
return
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1176
|
+
const pt = 7 * 24 * 60 * 60 * 1e3;
|
|
1177
|
+
let ee;
|
|
1178
|
+
function ut() {
|
|
1179
|
+
return ee || (ee = new Promise((e, t) => {
|
|
1180
|
+
const o = indexedDB.open("bugcatch-drafts", 1);
|
|
1181
|
+
o.onupgradeneeded = () => o.result.createObjectStore("drafts"), o.onsuccess = () => e(o.result), o.onerror = () => t(o.error), o.onblocked = () => t(new Error("Draft storage is blocked."));
|
|
1107
1182
|
}).catch((e) => {
|
|
1108
|
-
throw
|
|
1109
|
-
})),
|
|
1110
|
-
}
|
|
1111
|
-
function
|
|
1112
|
-
var
|
|
1113
|
-
return JSON.stringify([e.apiBase, e.projectId, t || ((
|
|
1114
|
-
}
|
|
1115
|
-
async function
|
|
1116
|
-
const
|
|
1117
|
-
return new Promise((
|
|
1118
|
-
const
|
|
1119
|
-
|
|
1183
|
+
throw ee = null, e;
|
|
1184
|
+
})), ee;
|
|
1185
|
+
}
|
|
1186
|
+
function ht(e, t) {
|
|
1187
|
+
var o, d;
|
|
1188
|
+
return JSON.stringify([e.apiBase, e.projectId, t || ((o = e.user) == null ? void 0 : o.email) || ((d = e.user) == null ? void 0 : d.id) || "anonymous"]);
|
|
1189
|
+
}
|
|
1190
|
+
async function re(e, t) {
|
|
1191
|
+
const o = await ut();
|
|
1192
|
+
return new Promise((d, l) => {
|
|
1193
|
+
const S = o.transaction("drafts", t === void 0 ? "readonly" : "readwrite"), m = S.objectStore("drafts"), f = t === void 0 ? m.get(e) : t === null ? m.delete(e) : m.put({ ...t, savedAt: Date.now() }, e);
|
|
1194
|
+
S.oncomplete = () => d(f.result), S.onerror = () => l(S.error), S.onabort = () => l(S.error || new Error("Draft was not saved."));
|
|
1120
1195
|
});
|
|
1121
1196
|
}
|
|
1122
|
-
async function
|
|
1123
|
-
const t = await
|
|
1124
|
-
return t && Date.now() - t.savedAt >
|
|
1197
|
+
async function bt(e) {
|
|
1198
|
+
const t = await re(e);
|
|
1199
|
+
return t && Date.now() - t.savedAt > pt ? (await re(e, null), null) : t || null;
|
|
1125
1200
|
}
|
|
1126
|
-
const
|
|
1201
|
+
const we = [
|
|
1127
1202
|
{ value: "LOW", label: "Low" },
|
|
1128
1203
|
{ value: "MEDIUM", label: "Medium" },
|
|
1129
1204
|
{ value: "HIGH", label: "High" },
|
|
1130
1205
|
{ value: "CRITICAL", label: "Critical" }
|
|
1131
|
-
],
|
|
1132
|
-
function
|
|
1133
|
-
const t = e.attachments !== !1,
|
|
1206
|
+
], ke = "MEDIUM";
|
|
1207
|
+
function ft(e) {
|
|
1208
|
+
const t = e.attachments !== !1, o = t && ze(), d = t && Ce();
|
|
1134
1209
|
return `
|
|
1135
|
-
<div class="compose">
|
|
1210
|
+
<div class="compose bug-only">
|
|
1136
1211
|
<div class="field">
|
|
1137
1212
|
<label for="bc-title">What went wrong?</label>
|
|
1138
1213
|
<input id="bc-title" type="text" placeholder="e.g. The checkout button does nothing" autocomplete="off"
|
|
@@ -1151,8 +1226,8 @@ function tt(e) {
|
|
|
1151
1226
|
<div class="field">
|
|
1152
1227
|
<label id="bc-prio-l">How much is it getting in your way?</label>
|
|
1153
1228
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
1154
|
-
${
|
|
1155
|
-
<button type="button" data-prio="${
|
|
1229
|
+
${we.map((l) => `
|
|
1230
|
+
<button type="button" data-prio="${l.value}" aria-pressed="${l.value === ke}">${l.label}</button>
|
|
1156
1231
|
`).join("")}
|
|
1157
1232
|
</div>
|
|
1158
1233
|
</div>
|
|
@@ -1163,842 +1238,842 @@ function tt(e) {
|
|
|
1163
1238
|
<span class="count" aria-live="polite"></span>
|
|
1164
1239
|
</div>
|
|
1165
1240
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1166
|
-
${
|
|
1167
|
-
${
|
|
1168
|
-
<button class="tool" type="button" data-act="file">${
|
|
1241
|
+
${o ? `<button class="tool" type="button" data-act="shot">${Ke}Screenshot</button>` : ""}
|
|
1242
|
+
${d ? `<button class="tool" type="button" data-act="rec">${Pe}Record screen</button>` : ""}
|
|
1243
|
+
<button class="tool" type="button" data-act="file">${ve}Upload file</button>
|
|
1169
1244
|
</div>
|
|
1170
1245
|
<div class="thumbs"></div>
|
|
1171
|
-
<input type="file" accept="${
|
|
1246
|
+
<input type="file" accept="${me.join(",")}" multiple hidden />
|
|
1172
1247
|
</div>` : ""}
|
|
1173
1248
|
</div>`;
|
|
1174
1249
|
}
|
|
1175
|
-
function
|
|
1176
|
-
var
|
|
1250
|
+
function gt(e) {
|
|
1251
|
+
var ne, U, _, C;
|
|
1177
1252
|
const {
|
|
1178
1253
|
client: t,
|
|
1179
|
-
cfg:
|
|
1180
|
-
root:
|
|
1181
|
-
host:
|
|
1182
|
-
dock:
|
|
1183
|
-
scrim:
|
|
1184
|
-
$:
|
|
1185
|
-
say:
|
|
1186
|
-
titleInput:
|
|
1187
|
-
descInput:
|
|
1188
|
-
compose:
|
|
1189
|
-
sendBtn:
|
|
1190
|
-
note:
|
|
1191
|
-
} = e,
|
|
1192
|
-
let n =
|
|
1193
|
-
const
|
|
1194
|
-
|
|
1195
|
-
const
|
|
1196
|
-
let
|
|
1197
|
-
function
|
|
1198
|
-
if (clearTimeout(
|
|
1199
|
-
const
|
|
1200
|
-
title:
|
|
1201
|
-
description:
|
|
1254
|
+
cfg: o,
|
|
1255
|
+
root: d,
|
|
1256
|
+
host: l,
|
|
1257
|
+
dock: S,
|
|
1258
|
+
scrim: m,
|
|
1259
|
+
$: f,
|
|
1260
|
+
say: c,
|
|
1261
|
+
titleInput: h,
|
|
1262
|
+
descInput: b,
|
|
1263
|
+
compose: k,
|
|
1264
|
+
sendBtn: s,
|
|
1265
|
+
note: y
|
|
1266
|
+
} = e, x = f(".thumbs"), T = m.querySelector("input[type=file]"), a = [];
|
|
1267
|
+
let n = ke, i = null;
|
|
1268
|
+
const r = document.createElement("div");
|
|
1269
|
+
r.setAttribute("role", "status"), r.className = "note", k.prepend(r);
|
|
1270
|
+
const $ = ht(o, (ne = t.signedInAs()) == null ? void 0 : ne.email);
|
|
1271
|
+
let q = o.drafts === !1, w = !1, p = Promise.resolve(), L;
|
|
1272
|
+
function g() {
|
|
1273
|
+
if (clearTimeout(L), !q || w || o.drafts === !1) return p;
|
|
1274
|
+
const u = h.value || b.value || a.length ? {
|
|
1275
|
+
title: h.value,
|
|
1276
|
+
description: b.value,
|
|
1202
1277
|
priority: n,
|
|
1203
|
-
items:
|
|
1278
|
+
items: a.map(({ blob: E, mime: R, kind: D }) => ({ blob: E, mime: R, kind: D }))
|
|
1204
1279
|
} : null;
|
|
1205
|
-
return
|
|
1206
|
-
}).then(() =>
|
|
1207
|
-
|
|
1280
|
+
return p = p.catch(() => {
|
|
1281
|
+
}).then(() => re($, u)).then(() => {
|
|
1282
|
+
r.textContent = u ? "Draft saved on this device" : "";
|
|
1208
1283
|
}).catch(() => {
|
|
1209
|
-
|
|
1210
|
-
}),
|
|
1284
|
+
r.textContent = "Draft could not be saved. Keep this tab open.";
|
|
1285
|
+
}), p;
|
|
1211
1286
|
}
|
|
1212
|
-
function
|
|
1213
|
-
clearTimeout(
|
|
1287
|
+
function z() {
|
|
1288
|
+
clearTimeout(L), L = setTimeout(g, 250);
|
|
1214
1289
|
}
|
|
1215
|
-
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1290
|
+
k.addEventListener("input", z), k.addEventListener("change", z);
|
|
1291
|
+
const M = () => {
|
|
1292
|
+
g();
|
|
1218
1293
|
};
|
|
1219
|
-
window.addEventListener("pagehide",
|
|
1220
|
-
function
|
|
1221
|
-
|
|
1222
|
-
}
|
|
1223
|
-
window.addEventListener("online",
|
|
1224
|
-
e.closed || !
|
|
1225
|
-
|
|
1226
|
-
for (const
|
|
1227
|
-
|
|
1228
|
-
},
|
|
1229
|
-
|
|
1294
|
+
window.addEventListener("pagehide", M);
|
|
1295
|
+
function A() {
|
|
1296
|
+
a.filter((u) => u.status === "failed").forEach(B);
|
|
1297
|
+
}
|
|
1298
|
+
window.addEventListener("online", A), o.drafts !== !1 && (k.inert = !0, bt($).then((u) => {
|
|
1299
|
+
e.closed || !u || (r.innerHTML = '<span>You have an unfinished report on this device.</span> <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>', r.querySelector("[data-resume]").onclick = () => {
|
|
1300
|
+
h.value = u.title || "", b.value = u.description || "", n = we.some((E) => E.value === u.priority) ? u.priority : "MEDIUM", m.querySelectorAll("[data-prio]").forEach((E) => E.setAttribute("aria-pressed", String(E.dataset.prio === n)));
|
|
1301
|
+
for (const E of (u.items || []).slice(0, o.maxAttachments ?? 5)) W(E);
|
|
1302
|
+
q = !0, g();
|
|
1303
|
+
}, r.querySelector("[data-discard]").onclick = () => {
|
|
1304
|
+
q = !0, g();
|
|
1230
1305
|
});
|
|
1231
1306
|
}).catch(() => {
|
|
1232
|
-
|
|
1307
|
+
r.textContent = "Draft storage is unavailable. Keep this tab open.";
|
|
1233
1308
|
}).finally(() => {
|
|
1234
|
-
|
|
1309
|
+
k.inert = e.mustRate(), r.querySelector("[data-resume]") || (q = !0);
|
|
1235
1310
|
})), e.onDestroy(() => {
|
|
1236
|
-
var
|
|
1237
|
-
|
|
1238
|
-
}),
|
|
1239
|
-
|
|
1240
|
-
n =
|
|
1241
|
-
|
|
1311
|
+
var u;
|
|
1312
|
+
g(), clearTimeout(L), window.removeEventListener("pagehide", M), window.removeEventListener("online", A), i == null || i.cancel(), a.forEach((E) => E.previewUrl && URL.revokeObjectURL(E.previewUrl)), (u = d.querySelector(".recbar")) == null || u.remove();
|
|
1313
|
+
}), m.querySelectorAll("[data-prio]").forEach((u) => {
|
|
1314
|
+
u.addEventListener("click", () => {
|
|
1315
|
+
n = u.dataset.prio, z(), m.querySelectorAll("[data-prio]").forEach((E) => {
|
|
1316
|
+
E.setAttribute("aria-pressed", String(E === u));
|
|
1242
1317
|
});
|
|
1243
1318
|
});
|
|
1244
1319
|
});
|
|
1245
|
-
const
|
|
1246
|
-
function
|
|
1247
|
-
|
|
1320
|
+
const O = f("#bc-title-err");
|
|
1321
|
+
function Q(u) {
|
|
1322
|
+
O.hidden = !u, O.innerHTML = u ? `${P}<span>${v(u)}</span>` : "", h.classList.toggle("invalid", !!u), h.setAttribute("aria-invalid", String(!!u));
|
|
1248
1323
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1324
|
+
h.addEventListener("input", () => {
|
|
1325
|
+
h.value.trim() && Q("");
|
|
1251
1326
|
});
|
|
1252
|
-
function
|
|
1253
|
-
const
|
|
1254
|
-
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
|
|
1327
|
+
function I() {
|
|
1328
|
+
const u = a.some((j) => j.status === "uploading"), E = e.mustRate();
|
|
1329
|
+
s.disabled = e.sending || u || E || a.some((j) => j.status === "failed"), y.textContent = E ? "Rate your last report to send a new one." : u ? "Waiting for the upload to finish…" : a.some((j) => j.status === "failed") ? "Retry or remove failed attachments before sending." : "";
|
|
1330
|
+
const R = o.maxAttachments ?? 5;
|
|
1331
|
+
m.querySelectorAll(".tool").forEach((j) => {
|
|
1332
|
+
j.disabled = e.sending || a.length >= R;
|
|
1258
1333
|
});
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1334
|
+
const D = f(".field-head .count");
|
|
1335
|
+
D && (D.textContent = a.length ? `${a.length} of ${R}` : "");
|
|
1261
1336
|
}
|
|
1262
|
-
e.refreshSendState =
|
|
1263
|
-
function
|
|
1337
|
+
e.refreshSendState = I;
|
|
1338
|
+
function H(u) {
|
|
1264
1339
|
var Y;
|
|
1265
|
-
const
|
|
1266
|
-
let
|
|
1267
|
-
|
|
1268
|
-
${
|
|
1269
|
-
<span class="kind">${
|
|
1270
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${
|
|
1271
|
-
${
|
|
1272
|
-
}
|
|
1273
|
-
function
|
|
1274
|
-
const
|
|
1275
|
-
|
|
1276
|
-
}
|
|
1277
|
-
async function
|
|
1278
|
-
|
|
1340
|
+
const E = u.el, R = u.kind === "VIDEO" ? "Video" : "Shot", D = u.kind === "VIDEO" ? `<video src="${u.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${u.previewUrl}" alt="" />`;
|
|
1341
|
+
let j = "";
|
|
1342
|
+
u.status === "uploading" ? j = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(u.progress * 100)}%"></i></div></div>` : u.status === "failed" && (j = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Ge}</button>Failed</div>`), E.innerHTML = `
|
|
1343
|
+
${D}
|
|
1344
|
+
<span class="kind">${R} · ${K(u.size)}</span>
|
|
1345
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${R.toLowerCase()}">${pe}</button>
|
|
1346
|
+
${j}`, E.querySelector('[data-act="drop"]').addEventListener("click", () => V(u)), (Y = E.querySelector('[data-act="retry"]')) == null || Y.addEventListener("click", () => B(u));
|
|
1347
|
+
}
|
|
1348
|
+
function V(u) {
|
|
1349
|
+
const E = a.indexOf(u);
|
|
1350
|
+
E >= 0 && a.splice(E, 1), u.previewUrl && URL.revokeObjectURL(u.previewUrl), u.el.remove(), g(), I();
|
|
1351
|
+
}
|
|
1352
|
+
async function B(u) {
|
|
1353
|
+
u.status = "uploading", u.progress = 0, H(u), I();
|
|
1279
1354
|
try {
|
|
1280
|
-
const { storageKey:
|
|
1281
|
-
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1355
|
+
const { storageKey: E, mime: R } = await t.uploadAttachment(u.blob, u.mime, (D) => {
|
|
1356
|
+
u.progress = D;
|
|
1357
|
+
const j = u.el.querySelector(".bar i");
|
|
1358
|
+
j && (j.style.width = `${Math.round(D * 100)}%`);
|
|
1284
1359
|
});
|
|
1285
|
-
|
|
1286
|
-
} catch (
|
|
1287
|
-
|
|
1360
|
+
u.storageKey = E, u.mime = R, u.status = "ready";
|
|
1361
|
+
} catch (E) {
|
|
1362
|
+
u.status = "failed", c(E.message.replace("[BugCatch] ", ""));
|
|
1288
1363
|
}
|
|
1289
|
-
|
|
1364
|
+
H(u), I();
|
|
1290
1365
|
}
|
|
1291
|
-
function
|
|
1292
|
-
const
|
|
1293
|
-
if (
|
|
1294
|
-
|
|
1366
|
+
function W({ blob: u, mime: E, kind: R }) {
|
|
1367
|
+
const D = o.maxAttachmentBytes ?? 26214400;
|
|
1368
|
+
if (u.size > D) {
|
|
1369
|
+
c(`That file is ${K(u.size)} — the limit is ${K(D)}.`);
|
|
1295
1370
|
return;
|
|
1296
1371
|
}
|
|
1297
|
-
const
|
|
1298
|
-
if (!
|
|
1299
|
-
|
|
1372
|
+
const j = Ae(E || u.type, me);
|
|
1373
|
+
if (!j) {
|
|
1374
|
+
c("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
|
|
1300
1375
|
return;
|
|
1301
1376
|
}
|
|
1302
1377
|
const Y = {
|
|
1303
|
-
blob:
|
|
1304
|
-
kind:
|
|
1305
|
-
mime:
|
|
1306
|
-
size:
|
|
1307
|
-
previewUrl: URL.createObjectURL(
|
|
1378
|
+
blob: u,
|
|
1379
|
+
kind: R,
|
|
1380
|
+
mime: j,
|
|
1381
|
+
size: u.size,
|
|
1382
|
+
previewUrl: URL.createObjectURL(u),
|
|
1308
1383
|
status: "uploading",
|
|
1309
1384
|
progress: 0,
|
|
1310
1385
|
storageKey: null,
|
|
1311
1386
|
el: document.createElement("div")
|
|
1312
1387
|
};
|
|
1313
|
-
Y.el.className = "thumb",
|
|
1388
|
+
Y.el.className = "thumb", a.push(Y), x.appendChild(Y.el), c(""), g(), B(Y);
|
|
1314
1389
|
}
|
|
1315
|
-
async function
|
|
1316
|
-
|
|
1390
|
+
async function J(u) {
|
|
1391
|
+
l.style.opacity = "0", l.style.pointerEvents = "none", await new Promise((E) => requestAnimationFrame(() => requestAnimationFrame(E)));
|
|
1317
1392
|
try {
|
|
1318
|
-
return await
|
|
1393
|
+
return await u();
|
|
1319
1394
|
} finally {
|
|
1320
|
-
|
|
1395
|
+
l.style.opacity = "", l.style.pointerEvents = "";
|
|
1321
1396
|
}
|
|
1322
1397
|
}
|
|
1323
|
-
(
|
|
1398
|
+
(U = m.querySelector('[data-act="shot"]')) == null || U.addEventListener("click", async () => {
|
|
1324
1399
|
try {
|
|
1325
|
-
const
|
|
1326
|
-
|
|
1327
|
-
} catch (
|
|
1328
|
-
(
|
|
1400
|
+
const u = await J(He);
|
|
1401
|
+
W(u);
|
|
1402
|
+
} catch (u) {
|
|
1403
|
+
(u == null ? void 0 : u.name) !== "NotAllowedError" && c(`Screenshot failed: ${u.message}`);
|
|
1329
1404
|
}
|
|
1330
|
-
}), (
|
|
1331
|
-
const
|
|
1332
|
-
[...
|
|
1333
|
-
|
|
1334
|
-
blob:
|
|
1335
|
-
mime:
|
|
1336
|
-
kind:
|
|
1405
|
+
}), (_ = m.querySelector('[data-act="file"]')) == null || _.addEventListener("click", () => T.click()), T == null || T.addEventListener("change", () => {
|
|
1406
|
+
const u = (o.maxAttachments ?? 5) - a.length;
|
|
1407
|
+
[...T.files].slice(0, Math.max(u, 0)).forEach((E) => {
|
|
1408
|
+
W({
|
|
1409
|
+
blob: E,
|
|
1410
|
+
mime: E.type,
|
|
1411
|
+
kind: E.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
|
|
1337
1412
|
});
|
|
1338
|
-
}),
|
|
1339
|
-
}), (
|
|
1340
|
-
const
|
|
1341
|
-
let
|
|
1413
|
+
}), T.value = "";
|
|
1414
|
+
}), (C = m.querySelector('[data-act="rec"]')) == null || C.addEventListener("click", async () => {
|
|
1415
|
+
const u = o.maxRecordingMs ?? 12e4;
|
|
1416
|
+
let E;
|
|
1342
1417
|
try {
|
|
1343
|
-
|
|
1344
|
-
maxMs:
|
|
1345
|
-
onTick: (
|
|
1346
|
-
|
|
1418
|
+
i = await Ie({
|
|
1419
|
+
maxMs: u,
|
|
1420
|
+
onTick: (R) => {
|
|
1421
|
+
E && (E.querySelector(".time").textContent = ae(R));
|
|
1347
1422
|
},
|
|
1348
1423
|
onAutoStop: () => {
|
|
1349
|
-
|
|
1424
|
+
i && N({ keep: !0 });
|
|
1350
1425
|
}
|
|
1351
1426
|
});
|
|
1352
|
-
} catch (
|
|
1353
|
-
(
|
|
1427
|
+
} catch (R) {
|
|
1428
|
+
(R == null ? void 0 : R.name) !== "NotAllowedError" && c(`Recording failed: ${R.message}`);
|
|
1354
1429
|
return;
|
|
1355
1430
|
}
|
|
1356
|
-
|
|
1431
|
+
m.style.display = "none", S.hidden = !0, E = document.createElement("div"), E.className = "recbar", E.innerHTML = `
|
|
1357
1432
|
<span class="dot"></span>
|
|
1358
1433
|
<span class="time">0:00</span>
|
|
1359
|
-
<span class="hint">Recording — up to ${
|
|
1434
|
+
<span class="hint">Recording — up to ${ae(Math.round(u / 1e3))}</span>
|
|
1360
1435
|
<button class="stop" type="button">Stop</button>
|
|
1361
|
-
<button class="ghost" type="button">Discard</button>`,
|
|
1436
|
+
<button class="ghost" type="button">Discard</button>`, E.querySelector(".stop").addEventListener("click", () => N({ keep: !0 })), E.querySelector(".ghost").addEventListener("click", () => N({ keep: !1 })), d.appendChild(E), E.querySelector(".stop").focus();
|
|
1362
1437
|
});
|
|
1363
|
-
async function
|
|
1364
|
-
var
|
|
1365
|
-
const
|
|
1366
|
-
if (
|
|
1367
|
-
if (
|
|
1368
|
-
|
|
1438
|
+
async function N({ keep: u }) {
|
|
1439
|
+
var R;
|
|
1440
|
+
const E = i;
|
|
1441
|
+
if (E) {
|
|
1442
|
+
if (i = null, (R = d.querySelector(".recbar")) == null || R.remove(), m.style.display = "", S.hidden = !1, !u) {
|
|
1443
|
+
E.cancel(), h.focus();
|
|
1369
1444
|
return;
|
|
1370
1445
|
}
|
|
1371
1446
|
try {
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
} catch (
|
|
1375
|
-
|
|
1447
|
+
const D = await E.stop();
|
|
1448
|
+
D.blob.size ? W(D) : c("That recording came back empty — nothing was captured.");
|
|
1449
|
+
} catch (D) {
|
|
1450
|
+
c(`Recording failed: ${D.message}`);
|
|
1376
1451
|
}
|
|
1377
|
-
|
|
1452
|
+
h.focus();
|
|
1378
1453
|
}
|
|
1379
1454
|
}
|
|
1380
|
-
e.isRecording = () => !!
|
|
1381
|
-
var
|
|
1382
|
-
const
|
|
1383
|
-
if (!
|
|
1384
|
-
|
|
1455
|
+
e.isRecording = () => !!i, e.stopRecording = N, s.addEventListener("click", async () => {
|
|
1456
|
+
var R;
|
|
1457
|
+
const u = h.value;
|
|
1458
|
+
if (!u.trim()) {
|
|
1459
|
+
Q("Add a few words about what went wrong — a short sentence is plenty."), h.focus();
|
|
1385
1460
|
return;
|
|
1386
1461
|
}
|
|
1387
1462
|
if (e.holdForReference()) return;
|
|
1388
|
-
e.sending = !0,
|
|
1389
|
-
const
|
|
1390
|
-
|
|
1463
|
+
e.sending = !0, c(""), I();
|
|
1464
|
+
const E = s.innerHTML;
|
|
1465
|
+
s.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
|
|
1391
1466
|
try {
|
|
1392
|
-
const
|
|
1393
|
-
title:
|
|
1394
|
-
description:
|
|
1467
|
+
const D = await t.report({
|
|
1468
|
+
title: u,
|
|
1469
|
+
description: b.value,
|
|
1395
1470
|
priority: n,
|
|
1396
1471
|
references: e.answeredReference(),
|
|
1397
|
-
issue: ((
|
|
1398
|
-
attachments:
|
|
1472
|
+
issue: ((R = e.pickedIssue()) == null ? void 0 : R.key) || null,
|
|
1473
|
+
attachments: a.filter((j) => j.status === "ready").map((j) => ({ type: j.kind, storageKey: j.storageKey, mime: j.mime }))
|
|
1399
1474
|
});
|
|
1400
|
-
if (
|
|
1401
|
-
e.sending = !1,
|
|
1475
|
+
if (D != null && D.cancelled) {
|
|
1476
|
+
e.sending = !1, s.innerHTML = E, I();
|
|
1402
1477
|
return;
|
|
1403
1478
|
}
|
|
1404
|
-
|
|
1405
|
-
}), e.succeed(
|
|
1406
|
-
} catch (
|
|
1407
|
-
e.sending = !1,
|
|
1479
|
+
w = !0, clearTimeout(L), await p, o.drafts !== !1 && await re($, null).catch(() => {
|
|
1480
|
+
}), e.succeed(D);
|
|
1481
|
+
} catch (D) {
|
|
1482
|
+
e.sending = !1, s.innerHTML = E, c(D.message.replace("[BugCatch] ", "")), I(), e.recheckSignIn();
|
|
1408
1483
|
}
|
|
1409
1484
|
});
|
|
1410
1485
|
}
|
|
1411
|
-
function
|
|
1486
|
+
function mt(e) {
|
|
1412
1487
|
const {
|
|
1413
1488
|
client: t,
|
|
1414
|
-
say:
|
|
1415
|
-
titleInput:
|
|
1416
|
-
descInput:
|
|
1417
|
-
sendBtn:
|
|
1418
|
-
refsBox:
|
|
1489
|
+
say: o,
|
|
1490
|
+
titleInput: d,
|
|
1491
|
+
descInput: l,
|
|
1492
|
+
sendBtn: S,
|
|
1493
|
+
refsBox: m
|
|
1419
1494
|
} = e;
|
|
1420
|
-
let
|
|
1421
|
-
t.referenceFields().then((
|
|
1422
|
-
|
|
1495
|
+
let f = { policy: "off", fields: [] }, c = !1, h = null, b = "", k = "", s = [], y = "ask", x = !1, T = !1;
|
|
1496
|
+
t.referenceFields().then((Q) => {
|
|
1497
|
+
f = Q, q();
|
|
1423
1498
|
}).catch(() => {
|
|
1424
1499
|
});
|
|
1425
|
-
function
|
|
1426
|
-
return
|
|
1427
|
-
}
|
|
1428
|
-
function n(
|
|
1429
|
-
return
|
|
1430
|
-
}
|
|
1431
|
-
function
|
|
1432
|
-
return !
|
|
1433
|
-
}
|
|
1434
|
-
const
|
|
1435
|
-
|
|
1436
|
-
let
|
|
1437
|
-
function
|
|
1438
|
-
const
|
|
1439
|
-
if (n(
|
|
1440
|
-
const
|
|
1441
|
-
|
|
1500
|
+
function a() {
|
|
1501
|
+
return f.policy === "off" || !f.fields.length ? { found: [], conflicts: [], loose: [] } : Re(f.fields, [d.value, l.value]);
|
|
1502
|
+
}
|
|
1503
|
+
function n(Q = a()) {
|
|
1504
|
+
return Q.found.length > 0 && Q.conflicts.length === 0;
|
|
1505
|
+
}
|
|
1506
|
+
function i() {
|
|
1507
|
+
return !h || !b.trim() ? [] : [{ key: h, value: b.trim().slice(0, 120) }];
|
|
1508
|
+
}
|
|
1509
|
+
const r = document.createElement("p");
|
|
1510
|
+
r.className = "ref-found", r.setAttribute("aria-live", "polite"), r.hidden = !0, l.closest(".field").after(r);
|
|
1511
|
+
let $;
|
|
1512
|
+
function q() {
|
|
1513
|
+
const Q = a();
|
|
1514
|
+
if (n(Q)) {
|
|
1515
|
+
const I = Q.found.slice(0, 2).map((H) => `${v(H.label)} <b>${v(p(H.value))}</b>`).join(", ");
|
|
1516
|
+
r.innerHTML = `${F}<span>Found your ${I} — no need to add it again.</span>`, r.hidden = !1, c && !i().length && (c = !1, z());
|
|
1442
1517
|
} else
|
|
1443
|
-
|
|
1518
|
+
r.hidden = !0, r.innerHTML = "";
|
|
1444
1519
|
}
|
|
1445
|
-
const
|
|
1446
|
-
clearTimeout(
|
|
1520
|
+
const w = () => {
|
|
1521
|
+
clearTimeout($), $ = setTimeout(q, 250);
|
|
1447
1522
|
};
|
|
1448
|
-
|
|
1449
|
-
function
|
|
1450
|
-
return
|
|
1523
|
+
d.addEventListener("input", w), l.addEventListener("input", w);
|
|
1524
|
+
function p(Q) {
|
|
1525
|
+
return Q.length > 20 ? `${Q.slice(0, 8)}…${Q.slice(-4)}` : Q;
|
|
1451
1526
|
}
|
|
1452
|
-
function
|
|
1453
|
-
const
|
|
1454
|
-
return
|
|
1527
|
+
function L(Q) {
|
|
1528
|
+
const I = Q.trim().toLowerCase();
|
|
1529
|
+
return s.find((H) => H.value.toLowerCase() === I) || null;
|
|
1455
1530
|
}
|
|
1456
|
-
function
|
|
1457
|
-
|
|
1531
|
+
function g(Q) {
|
|
1532
|
+
b = Q.value, Q.kinds.length === 1 ? h = Q.kinds[0].key : Q.kinds.some((I) => I.key === h) || (h = null), k = "", T = !1;
|
|
1458
1533
|
}
|
|
1459
|
-
function
|
|
1460
|
-
var
|
|
1461
|
-
if (!
|
|
1462
|
-
|
|
1534
|
+
function z() {
|
|
1535
|
+
var U, _;
|
|
1536
|
+
if (!c) {
|
|
1537
|
+
m.hidden = !0, m.innerHTML = "";
|
|
1463
1538
|
return;
|
|
1464
1539
|
}
|
|
1465
|
-
const
|
|
1466
|
-
confirm:
|
|
1540
|
+
const Q = f.fields.find((C) => C.key === h) || null, I = f.policy !== "required", H = L(b), V = H && H.kinds.length > 1 ? f.fields.filter((C) => H.kinds.some((u) => u.key === C.key)) : f.fields, B = s.length > 1 && s.every((C) => C.kinds.length === 1 && C.kinds[0].key === s[0].kinds[0].key), W = {
|
|
1541
|
+
confirm: s.length > 1 ? ["Which one is this about?", "We found more than one ID in your message. Pick the one this problem is about."] : ["Is this the right ID?", "This could be more than one kind of ID. Tell us which it is."],
|
|
1467
1542
|
suggest: ["Is this your ID?", "We spotted this in your message. Tell us what it is so we can find your record."],
|
|
1468
|
-
ask:
|
|
1469
|
-
}[
|
|
1470
|
-
|
|
1471
|
-
const
|
|
1472
|
-
|
|
1543
|
+
ask: I ? ["One more thing", "So we can find your record — this helps us answer faster."] : ["We need one detail", "We need one of these to look this up."]
|
|
1544
|
+
}[y];
|
|
1545
|
+
m.hidden = !1;
|
|
1546
|
+
const J = V.length > 6;
|
|
1547
|
+
m.innerHTML = `
|
|
1473
1548
|
<div class="ask-head">
|
|
1474
1549
|
<span class="avatar orb" aria-hidden="true"></span>
|
|
1475
1550
|
<div>
|
|
1476
|
-
<strong>${v(
|
|
1477
|
-
<p class="why">${v(
|
|
1551
|
+
<strong>${v(W[0])}</strong>
|
|
1552
|
+
<p class="why">${v(W[1])}</p>
|
|
1478
1553
|
</div>
|
|
1479
1554
|
</div>
|
|
1480
|
-
${
|
|
1555
|
+
${s.length > 1 ? `
|
|
1481
1556
|
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1482
|
-
${
|
|
1483
|
-
<button type="button" data-ref-cand="${
|
|
1484
|
-
aria-pressed="${!!
|
|
1557
|
+
${s.map((C, u) => `
|
|
1558
|
+
<button type="button" data-ref-cand="${u}" title="${v(C.value)}"
|
|
1559
|
+
aria-pressed="${!!H && H === C}">${v(p(C.value))}</button>
|
|
1485
1560
|
`).join("")}
|
|
1486
1561
|
</div>` : ""}
|
|
1487
|
-
${
|
|
1562
|
+
${V.length > 1 && !J && !B ? `
|
|
1488
1563
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1489
|
-
${
|
|
1490
|
-
<button type="button" data-ref-kind="${v(
|
|
1564
|
+
${V.map((C) => `
|
|
1565
|
+
<button type="button" data-ref-kind="${v(C.key)}" aria-pressed="${!!Q && C.key === Q.key}">${v(C.label)}</button>
|
|
1491
1566
|
`).join("")}
|
|
1492
1567
|
</div>` : ""}
|
|
1493
1568
|
<div class="row">
|
|
1494
|
-
${
|
|
1569
|
+
${J ? `
|
|
1495
1570
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1496
|
-
${
|
|
1497
|
-
${
|
|
1498
|
-
<option value="${v(
|
|
1571
|
+
${Q ? "" : '<option value="" selected disabled>What is it?</option>'}
|
|
1572
|
+
${V.map((C) => `
|
|
1573
|
+
<option value="${v(C.key)}" ${Q && C.key === Q.key ? "selected" : ""}>${v(C.label)}</option>
|
|
1499
1574
|
`).join("")}
|
|
1500
1575
|
</select>` : ""}
|
|
1501
|
-
<input class="ref-value${
|
|
1502
|
-
inputmode="${v((
|
|
1503
|
-
value="${v(
|
|
1504
|
-
placeholder="${v(
|
|
1505
|
-
aria-label="${v(
|
|
1576
|
+
<input class="ref-value${k ? " invalid" : ""}" type="${(Q == null ? void 0 : Q.inputMode) === "email" ? "email" : "text"}"
|
|
1577
|
+
inputmode="${v((Q == null ? void 0 : Q.inputMode) === "numeric" || (Q == null ? void 0 : Q.inputMode) === "tel" ? "numeric" : "text")}"
|
|
1578
|
+
value="${v(b)}"
|
|
1579
|
+
placeholder="${v(Q ? Q.placeholder || Q.label : "Your ID")}"
|
|
1580
|
+
aria-label="${v(Q ? Q.label : "Your ID")}" ${k ? 'aria-invalid="true"' : ""} />
|
|
1506
1581
|
</div>
|
|
1507
|
-
${
|
|
1508
|
-
${
|
|
1509
|
-
${
|
|
1510
|
-
|
|
1511
|
-
|
|
1582
|
+
${Q != null && Q.hint ? `<p class="hint">${v(Q.hint)}</p>` : ""}
|
|
1583
|
+
${k ? `<p class="field-err" role="alert">${P}<span>${v(k)}</span></p>` : ""}
|
|
1584
|
+
${I ? `<button type="button" class="link" data-act="ref-skip">${y === "ask" ? "I don't have this — send without it" : "Not sure — send as it is"}</button>` : ""}`, m.querySelectorAll("[data-ref-cand]").forEach((C) => {
|
|
1585
|
+
C.addEventListener("click", () => {
|
|
1586
|
+
g(s[Number(C.dataset.refCand)]), z();
|
|
1512
1587
|
});
|
|
1513
|
-
}),
|
|
1514
|
-
|
|
1515
|
-
|
|
1588
|
+
}), m.querySelectorAll("[data-ref-kind]").forEach((C) => {
|
|
1589
|
+
C.addEventListener("click", () => {
|
|
1590
|
+
h = C.dataset.refKind, k = "", T = !1, z();
|
|
1516
1591
|
});
|
|
1517
1592
|
});
|
|
1518
|
-
const
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
}),
|
|
1522
|
-
|
|
1523
|
-
}), (
|
|
1524
|
-
var
|
|
1525
|
-
|
|
1526
|
-
}), (
|
|
1527
|
-
|
|
1528
|
-
}), ((!
|
|
1529
|
-
}
|
|
1530
|
-
function
|
|
1531
|
-
if (
|
|
1532
|
-
if (
|
|
1593
|
+
const N = m.querySelector(".ref-value");
|
|
1594
|
+
N.addEventListener("input", () => {
|
|
1595
|
+
b = N.value, k = "", T = !1;
|
|
1596
|
+
}), N.addEventListener("keydown", (C) => {
|
|
1597
|
+
C.key === "Enter" && (C.preventDefault(), S.click());
|
|
1598
|
+
}), (U = m.querySelector(".ref-kind")) == null || U.addEventListener("change", (C) => {
|
|
1599
|
+
var u;
|
|
1600
|
+
h = C.target.value, k = "", z(), (u = m.querySelector(".ref-value")) == null || u.focus();
|
|
1601
|
+
}), (_ = m.querySelector('[data-act="ref-skip"]')) == null || _.addEventListener("click", () => {
|
|
1602
|
+
x = !0, c = !1, h = null, b = "", k = "", T = !1, z(), o("");
|
|
1603
|
+
}), ((!Q && b ? m.querySelector("[data-ref-kind], .ref-kind") : null) || N).focus();
|
|
1604
|
+
}
|
|
1605
|
+
function M(Q) {
|
|
1606
|
+
if (s = Q.conflicts.length ? Q.conflicts : Q.loose.slice(0, 4), y = Q.conflicts.length ? "confirm" : Q.loose.length ? "suggest" : "ask", c = !0, s.length)
|
|
1607
|
+
if (s.length === 1) g(s[0]);
|
|
1533
1608
|
else {
|
|
1534
|
-
|
|
1535
|
-
const [
|
|
1536
|
-
|
|
1609
|
+
b = "";
|
|
1610
|
+
const [I] = s;
|
|
1611
|
+
h = s.every((V) => V.kinds.length === 1 && V.kinds[0].key === I.kinds[0].key) ? I.kinds[0].key : null;
|
|
1537
1612
|
}
|
|
1538
1613
|
else
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
}
|
|
1542
|
-
function
|
|
1543
|
-
if (
|
|
1544
|
-
const
|
|
1545
|
-
return n(
|
|
1546
|
-
}
|
|
1547
|
-
function
|
|
1548
|
-
if (
|
|
1549
|
-
return
|
|
1550
|
-
const
|
|
1551
|
-
if (
|
|
1552
|
-
return
|
|
1553
|
-
if (
|
|
1554
|
-
const
|
|
1555
|
-
if (!
|
|
1556
|
-
return
|
|
1614
|
+
h = h || f.fields[0].key;
|
|
1615
|
+
z();
|
|
1616
|
+
}
|
|
1617
|
+
function A() {
|
|
1618
|
+
if (f.policy === "off" || !f.fields.length || i().length) return !1;
|
|
1619
|
+
const Q = a();
|
|
1620
|
+
return n(Q) || x && f.policy !== "required" ? !1 : Q;
|
|
1621
|
+
}
|
|
1622
|
+
function O() {
|
|
1623
|
+
if (c && b.trim() && !h)
|
|
1624
|
+
return k = "Pick what this ID is.", z(), !0;
|
|
1625
|
+
const Q = A();
|
|
1626
|
+
if (Q)
|
|
1627
|
+
return c ? z() : M(Q), o(""), !0;
|
|
1628
|
+
if (h && b.trim()) {
|
|
1629
|
+
const I = f.fields.find((H) => H.key === h);
|
|
1630
|
+
if (!T && I && !De(I, b))
|
|
1631
|
+
return k = `That does not look like a ${I.label.toLowerCase()}. Press Send again to use it anyway.`, T = !0, z(), !0;
|
|
1557
1632
|
}
|
|
1558
1633
|
return !1;
|
|
1559
1634
|
}
|
|
1560
|
-
e.holdForReference =
|
|
1561
|
-
}
|
|
1562
|
-
const
|
|
1563
|
-
function
|
|
1564
|
-
const { client: t, cfg:
|
|
1565
|
-
let
|
|
1566
|
-
function
|
|
1567
|
-
const
|
|
1568
|
-
|
|
1635
|
+
e.holdForReference = O, e.answeredReference = i;
|
|
1636
|
+
}
|
|
1637
|
+
const vt = 3;
|
|
1638
|
+
function yt(e) {
|
|
1639
|
+
const { client: t, cfg: o, notices: d } = e;
|
|
1640
|
+
let l = [];
|
|
1641
|
+
function S() {
|
|
1642
|
+
const f = l.slice(0, vt);
|
|
1643
|
+
d.replaceChildren(...f.map((c) => je(c, { where: "panel", onDismiss: m }))), d.hidden = f.length === 0;
|
|
1569
1644
|
}
|
|
1570
|
-
function
|
|
1571
|
-
t.dismissAnnouncement(
|
|
1645
|
+
function m(f) {
|
|
1646
|
+
t.dismissAnnouncement(f), l = l.filter((c) => c !== f), S(), e.titleInput.focus();
|
|
1572
1647
|
}
|
|
1573
|
-
|
|
1574
|
-
e.closed || (
|
|
1648
|
+
o.announcements !== !1 && typeof t.announcements == "function" && t.announcements().then((f) => {
|
|
1649
|
+
e.closed || (l = f, S());
|
|
1575
1650
|
}).catch(() => {
|
|
1576
1651
|
});
|
|
1577
1652
|
}
|
|
1578
|
-
function
|
|
1653
|
+
function xt(e) {
|
|
1579
1654
|
const {
|
|
1580
1655
|
client: t,
|
|
1581
|
-
cfg:
|
|
1582
|
-
titleInput:
|
|
1583
|
-
known:
|
|
1656
|
+
cfg: o,
|
|
1657
|
+
titleInput: d,
|
|
1658
|
+
known: l
|
|
1584
1659
|
} = e;
|
|
1585
|
-
let
|
|
1586
|
-
function
|
|
1587
|
-
|
|
1588
|
-
|
|
1660
|
+
let S = [], m = "", f = null, c = null;
|
|
1661
|
+
function h() {
|
|
1662
|
+
o.knownIssues !== !1 && t.knownIssues().then((x) => {
|
|
1663
|
+
S = x, s();
|
|
1589
1664
|
}).catch(() => {
|
|
1590
1665
|
});
|
|
1591
1666
|
}
|
|
1592
|
-
let
|
|
1593
|
-
function
|
|
1594
|
-
if (
|
|
1595
|
-
clearTimeout(
|
|
1596
|
-
const
|
|
1597
|
-
if (
|
|
1598
|
-
|
|
1667
|
+
let b = null;
|
|
1668
|
+
function k(x) {
|
|
1669
|
+
if (o.knownIssues === !1) return;
|
|
1670
|
+
clearTimeout(b), c == null || c.abort();
|
|
1671
|
+
const T = (x || "").trim();
|
|
1672
|
+
if (T.length < 3) {
|
|
1673
|
+
h();
|
|
1599
1674
|
return;
|
|
1600
1675
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1676
|
+
b = setTimeout(() => {
|
|
1677
|
+
c = new AbortController(), t.matchKnownIssues(T, { signal: c.signal }).then((a) => {
|
|
1678
|
+
a.length && (S = a, s());
|
|
1604
1679
|
}).catch(() => {
|
|
1605
1680
|
});
|
|
1606
1681
|
}, 250);
|
|
1607
1682
|
}
|
|
1608
|
-
function
|
|
1609
|
-
if (!
|
|
1610
|
-
|
|
1683
|
+
function s() {
|
|
1684
|
+
if (!S.length) {
|
|
1685
|
+
l.hidden = !0, l.innerHTML = "";
|
|
1611
1686
|
return;
|
|
1612
1687
|
}
|
|
1613
|
-
|
|
1688
|
+
l.hidden = !1, l.innerHTML = `
|
|
1614
1689
|
<p class="known-h">Already reported</p>
|
|
1615
|
-
${
|
|
1616
|
-
<div class="issue ${
|
|
1690
|
+
${S.map((x) => `
|
|
1691
|
+
<div class="issue ${x.joined ? "is-joined" : ""}">
|
|
1617
1692
|
<span class="who">
|
|
1618
|
-
<span class="t">${v(
|
|
1619
|
-
<span class="meta">${v(
|
|
1693
|
+
<span class="t">${v(x.title)}</span>
|
|
1694
|
+
<span class="meta">${v(y(x))}</span>
|
|
1620
1695
|
</span>
|
|
1621
|
-
<button class="join" type="button" data-join="${v(
|
|
1622
|
-
${
|
|
1696
|
+
<button class="join" type="button" data-join="${v(x.id)}"
|
|
1697
|
+
${x.joined ? "disabled" : ""}>${x.joined ? "Following" : "Me too"}</button>
|
|
1623
1698
|
</div>
|
|
1624
|
-
${
|
|
1699
|
+
${f === x.id ? `
|
|
1625
1700
|
<div class="ask">
|
|
1626
1701
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1627
1702
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1628
|
-
<button class="ghost" type="button" data-join-confirm="${v(
|
|
1703
|
+
<button class="ghost" type="button" data-join-confirm="${v(x.id)}">Follow</button>
|
|
1629
1704
|
</div>` : ""}
|
|
1630
1705
|
`).join("")}
|
|
1631
|
-
${
|
|
1632
|
-
}
|
|
1633
|
-
function
|
|
1634
|
-
const
|
|
1635
|
-
return `${
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
var
|
|
1639
|
-
const
|
|
1640
|
-
if (!
|
|
1641
|
-
const n = (
|
|
1642
|
-
|
|
1643
|
-
const
|
|
1644
|
-
if (!
|
|
1645
|
-
|
|
1706
|
+
${m ? `<p class="err">${v(m)}</p>` : ""}`;
|
|
1707
|
+
}
|
|
1708
|
+
function y(x) {
|
|
1709
|
+
const T = x.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", a = x.affectedCount === 0 ? "" : ` · ${x.affectedCount} ${x.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
|
|
1710
|
+
return `${T} · reported ${X(x.since)}${a}`;
|
|
1711
|
+
}
|
|
1712
|
+
l.addEventListener("click", async (x) => {
|
|
1713
|
+
var r, $, q, w, p;
|
|
1714
|
+
const T = x.target.closest("[data-join]"), a = x.target.closest("[data-join-confirm]");
|
|
1715
|
+
if (!T && !a) return;
|
|
1716
|
+
const n = (a || T).getAttribute(a ? "data-join-confirm" : "data-join");
|
|
1717
|
+
m = "";
|
|
1718
|
+
const i = (($ = (r = l.querySelector(".join-email")) == null ? void 0 : r.value) == null ? void 0 : $.trim()) || ((q = t.signedInAs()) == null ? void 0 : q.email) || ((w = t.config.user) == null ? void 0 : w.email);
|
|
1719
|
+
if (!i) {
|
|
1720
|
+
f = n, s(), (p = l.querySelector(".join-email")) == null || p.focus();
|
|
1646
1721
|
return;
|
|
1647
1722
|
}
|
|
1648
1723
|
try {
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1651
|
-
} catch (
|
|
1652
|
-
|
|
1724
|
+
const L = await t.meToo(n, { email: i });
|
|
1725
|
+
f = null, S = S.map((g) => g.id === n ? { ...g, joined: !0, affectedCount: L.affectedCount ?? g.affectedCount } : g), s();
|
|
1726
|
+
} catch (L) {
|
|
1727
|
+
m = L.message.replace("[BugCatch] ", ""), s();
|
|
1653
1728
|
}
|
|
1654
|
-
}),
|
|
1729
|
+
}), h(), d.addEventListener("input", () => k(d.value));
|
|
1655
1730
|
}
|
|
1656
|
-
function
|
|
1731
|
+
function wt(e) {
|
|
1657
1732
|
const {
|
|
1658
1733
|
client: t,
|
|
1659
|
-
cfg:
|
|
1660
|
-
titleInput:
|
|
1661
|
-
descInput:
|
|
1662
|
-
picks:
|
|
1734
|
+
cfg: o,
|
|
1735
|
+
titleInput: d,
|
|
1736
|
+
descInput: l,
|
|
1737
|
+
picks: S
|
|
1663
1738
|
} = e;
|
|
1664
|
-
let
|
|
1665
|
-
function
|
|
1666
|
-
if (!
|
|
1667
|
-
|
|
1739
|
+
let m = [], f = null;
|
|
1740
|
+
function c() {
|
|
1741
|
+
if (!m.length) {
|
|
1742
|
+
S.hidden = !0, S.innerHTML = "";
|
|
1668
1743
|
return;
|
|
1669
1744
|
}
|
|
1670
|
-
|
|
1745
|
+
S.hidden = !1, S.innerHTML = `
|
|
1671
1746
|
<p class="picks-h">Get an answer right away</p>
|
|
1672
1747
|
<div class="picks-grid" role="group" aria-label="Common questions">
|
|
1673
|
-
${
|
|
1674
|
-
<button type="button" class="pick" data-pick="${v(
|
|
1675
|
-
${
|
|
1676
|
-
aria-pressed="${(
|
|
1677
|
-
<span class="t">${v(
|
|
1678
|
-
${
|
|
1748
|
+
${m.map((h, b) => `
|
|
1749
|
+
<button type="button" class="pick" data-pick="${v(h.key)}"
|
|
1750
|
+
${h.hint ? `title="${v(h.hint)}" aria-describedby="bc-pick-h${b}"` : ""}
|
|
1751
|
+
aria-pressed="${(f == null ? void 0 : f.key) === h.key}">
|
|
1752
|
+
<span class="t">${v(h.title)}</span>
|
|
1753
|
+
${h.hint ? `<span class="h sr-only" id="bc-pick-h${b}">${v(h.hint)}</span>` : ""}
|
|
1679
1754
|
</button>`).join("")}
|
|
1680
1755
|
</div>
|
|
1681
|
-
${
|
|
1756
|
+
${f ? `<p class="picks-note">${F}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>` : ""}`;
|
|
1682
1757
|
}
|
|
1683
|
-
|
|
1684
|
-
const
|
|
1685
|
-
if (!
|
|
1686
|
-
const
|
|
1687
|
-
if (!
|
|
1688
|
-
const
|
|
1689
|
-
(
|
|
1690
|
-
}),
|
|
1691
|
-
|
|
1758
|
+
S.addEventListener("click", (h) => {
|
|
1759
|
+
const b = h.target.closest("[data-pick]");
|
|
1760
|
+
if (!b) return;
|
|
1761
|
+
const k = m.find((y) => y.key === b.dataset.pick);
|
|
1762
|
+
if (!k) return;
|
|
1763
|
+
const s = f && d.value.trim() === f.title;
|
|
1764
|
+
(f == null ? void 0 : f.key) === k.key ? (f = null, s && (d.value = "")) : (f = k, (!d.value.trim() || s) && (d.value = k.title)), d.dispatchEvent(new Event("input", { bubbles: !0 })), c(), f && l.focus();
|
|
1765
|
+
}), o.agentIssues !== !1 && typeof t.agentIssues == "function" && t.agentIssues().then((h) => {
|
|
1766
|
+
m = h, c();
|
|
1692
1767
|
}).catch(() => {
|
|
1693
|
-
}), e.pickedIssue = () =>
|
|
1768
|
+
}), e.pickedIssue = () => f;
|
|
1694
1769
|
}
|
|
1695
|
-
function
|
|
1770
|
+
function kt(e) {
|
|
1696
1771
|
const {
|
|
1697
1772
|
client: t,
|
|
1698
|
-
scrim:
|
|
1699
|
-
say:
|
|
1700
|
-
callBtn:
|
|
1701
|
-
close:
|
|
1773
|
+
scrim: o,
|
|
1774
|
+
say: d,
|
|
1775
|
+
callBtn: l,
|
|
1776
|
+
close: S
|
|
1702
1777
|
} = e;
|
|
1703
|
-
let
|
|
1704
|
-
function
|
|
1705
|
-
t.callKind().then((
|
|
1706
|
-
|
|
1778
|
+
let m = !1;
|
|
1779
|
+
function f() {
|
|
1780
|
+
t.callKind().then((b) => {
|
|
1781
|
+
b && (m = !0, e.preloadCall(), l.hidden = e.mustSignIn() || e.mustRate());
|
|
1707
1782
|
}).catch(() => {
|
|
1708
1783
|
});
|
|
1709
1784
|
}
|
|
1710
|
-
|
|
1711
|
-
e.sending = !0,
|
|
1785
|
+
f(), l.addEventListener("click", async () => {
|
|
1786
|
+
e.sending = !0, d(""), e.refreshSendState(), l.disabled = !0, l.innerHTML = '<span class="spinner"></span>Ringing…';
|
|
1712
1787
|
try {
|
|
1713
|
-
const
|
|
1714
|
-
|
|
1715
|
-
} catch (
|
|
1716
|
-
e.sending = !1,
|
|
1788
|
+
const b = await t.startCall();
|
|
1789
|
+
c(b);
|
|
1790
|
+
} catch (b) {
|
|
1791
|
+
e.sending = !1, l.disabled = !1, l.innerHTML = `${oe}Talk to the team`, e.refreshSendState(), b.filed ? e.succeed(b.filed, { callFailed: b.reason || "The call could not be started." }) : (d(b.message.replace("[BugCatch] ", "")), e.recheckSignIn());
|
|
1717
1792
|
}
|
|
1718
1793
|
});
|
|
1719
|
-
function
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1794
|
+
function c(b) {
|
|
1795
|
+
const k = o.querySelector(".panel"), s = b != null && b.bugId ? String(b.bugId).slice(0, 8) : null;
|
|
1796
|
+
k.innerHTML = `
|
|
1722
1797
|
<div class="call">
|
|
1723
1798
|
<div class="call-head">
|
|
1724
1799
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1725
1800
|
<strong class="call-state">Ringing…</strong>
|
|
1726
1801
|
</div>
|
|
1727
1802
|
<p class="call-note">
|
|
1728
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1803
|
+
We're ringing the team now. Someone will pick up if they're free — your report${s ? ` <code>${v(s)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
|
|
1729
1804
|
</p>
|
|
1730
1805
|
<div class="foot">
|
|
1731
1806
|
<span class="spacer"></span>
|
|
1732
1807
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1733
1808
|
</div>
|
|
1734
1809
|
</div>`;
|
|
1735
|
-
const
|
|
1810
|
+
const y = k.querySelector(".call-state"), x = k.querySelector(".call-dot"), T = {
|
|
1736
1811
|
ringing: "Ringing the team…",
|
|
1737
1812
|
connecting: "Someone answered — connecting…",
|
|
1738
1813
|
connected: "Connected",
|
|
1739
1814
|
missed: "Nobody was free",
|
|
1740
1815
|
ended: "Call ended",
|
|
1741
1816
|
failed: "The call dropped"
|
|
1742
|
-
},
|
|
1743
|
-
if (
|
|
1744
|
-
const
|
|
1745
|
-
|
|
1817
|
+
}, a = ["ended", "failed", "missed"], n = t.on("call", ({ state: i }) => {
|
|
1818
|
+
if (y.textContent = T[i] || i, x.classList.toggle("off", a.includes(i)), a.includes(i) && (k.querySelector('[data-act="hangup"]').textContent = "Close", i === "missed")) {
|
|
1819
|
+
const r = k.querySelector(".call-note");
|
|
1820
|
+
r && (r.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
|
|
1746
1821
|
}
|
|
1747
1822
|
});
|
|
1748
|
-
|
|
1749
|
-
n(), t.endCall(),
|
|
1823
|
+
k.querySelector('[data-act="hangup"]').addEventListener("click", () => {
|
|
1824
|
+
n(), t.endCall(), S();
|
|
1750
1825
|
});
|
|
1751
1826
|
}
|
|
1752
|
-
function
|
|
1753
|
-
const
|
|
1754
|
-
|
|
1827
|
+
function h(b, k, s) {
|
|
1828
|
+
const y = document.createElement("div");
|
|
1829
|
+
y.className = "livecall", y.innerHTML = `
|
|
1755
1830
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1756
1831
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1757
1832
|
<span class="secs" hidden></span>
|
|
1758
|
-
${
|
|
1833
|
+
${s != null && s.recorded ? '<span class="call-kept">This call is recorded.</span>' : ""}
|
|
1759
1834
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
1760
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1761
|
-
const
|
|
1762
|
-
let
|
|
1763
|
-
const
|
|
1764
|
-
|
|
1765
|
-
},
|
|
1766
|
-
|
|
1767
|
-
},
|
|
1768
|
-
if (
|
|
1769
|
-
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
}, 1e3),
|
|
1835
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`, b.insertBefore(y, k);
|
|
1836
|
+
const x = y.querySelector(".who"), T = y.querySelector(".secs"), a = y.querySelector(".call-dot"), n = y.querySelector('[data-act="mute"]'), i = y.querySelector('[data-act="hangup"]');
|
|
1837
|
+
let r = null;
|
|
1838
|
+
const $ = () => {
|
|
1839
|
+
r && (clearInterval(r), r = null);
|
|
1840
|
+
}, q = (p) => {
|
|
1841
|
+
$(), a.classList.add("off"), y.classList.add("over"), x.textContent = p, T.hidden = !0, n.hidden = !0, i.textContent = "Dismiss", i.classList.remove("danger");
|
|
1842
|
+
}, w = t.on("call", ({ state: p }) => {
|
|
1843
|
+
if (p === "ringing" && (x.textContent = "Calling the team…"), p === "connecting" && (x.textContent = "Someone answered — connecting…"), p === "connected") {
|
|
1844
|
+
x.textContent = "You're on a call with the team", n.hidden = !1, T.hidden = !1;
|
|
1845
|
+
const L = Date.now();
|
|
1846
|
+
$(), r = setInterval(() => {
|
|
1847
|
+
T.textContent = ae(Math.floor((Date.now() - L) / 1e3));
|
|
1848
|
+
}, 1e3), T.textContent = "0s";
|
|
1774
1849
|
}
|
|
1775
|
-
|
|
1850
|
+
p === "missed" && q("Nobody was free. Send a message instead and the team will pick it up."), p === "ended" && q("Call ended."), p === "failed" && q("The call dropped.");
|
|
1776
1851
|
});
|
|
1777
1852
|
n.addEventListener("click", () => {
|
|
1778
|
-
const
|
|
1779
|
-
n.textContent =
|
|
1780
|
-
}),
|
|
1781
|
-
|
|
1853
|
+
const p = s.setMuted(!s.isMuted());
|
|
1854
|
+
n.textContent = p ? "Unmute" : "Mute", x.textContent = p ? "You're muted" : "You're on a call with the team";
|
|
1855
|
+
}), i.addEventListener("click", () => {
|
|
1856
|
+
w(), $(), t.endCall(), y.remove(), e.refreshThread(e.openReportId());
|
|
1782
1857
|
});
|
|
1783
1858
|
}
|
|
1784
|
-
e.offerCall =
|
|
1859
|
+
e.offerCall = f, e.callOffered = () => m, e.showLiveCall = h;
|
|
1785
1860
|
}
|
|
1786
|
-
function
|
|
1787
|
-
var
|
|
1861
|
+
function $t(e) {
|
|
1862
|
+
var w;
|
|
1788
1863
|
const {
|
|
1789
1864
|
client: t,
|
|
1790
|
-
say:
|
|
1791
|
-
compose:
|
|
1792
|
-
sendBtn:
|
|
1793
|
-
historyBtn:
|
|
1794
|
-
callBtn:
|
|
1795
|
-
whoami:
|
|
1865
|
+
say: o,
|
|
1866
|
+
compose: d,
|
|
1867
|
+
sendBtn: l,
|
|
1868
|
+
historyBtn: S,
|
|
1869
|
+
callBtn: m,
|
|
1870
|
+
whoami: f
|
|
1796
1871
|
} = e;
|
|
1797
|
-
let
|
|
1798
|
-
const
|
|
1799
|
-
function
|
|
1800
|
-
const
|
|
1801
|
-
|
|
1872
|
+
let c = { mode: t.lastLoginMode || "off", signedIn: null }, h = "idle", b = ((w = t.config.user) == null ? void 0 : w.email) || "", k = "", s = !1, y = "";
|
|
1873
|
+
const x = () => c.mode === "required" && !c.signedIn;
|
|
1874
|
+
function T() {
|
|
1875
|
+
const p = x();
|
|
1876
|
+
d.hidden = p, l.hidden = p, S && (S.hidden = p), p ? m.hidden = !0 : e.callOffered() && !e.mustRate() && (m.hidden = !1);
|
|
1802
1877
|
}
|
|
1803
|
-
function
|
|
1804
|
-
var
|
|
1805
|
-
if (
|
|
1806
|
-
|
|
1878
|
+
function a() {
|
|
1879
|
+
var L;
|
|
1880
|
+
if (c.mode === "off") {
|
|
1881
|
+
f.hidden = !0, f.innerHTML = "";
|
|
1807
1882
|
return;
|
|
1808
1883
|
}
|
|
1809
|
-
|
|
1810
|
-
const
|
|
1811
|
-
if (
|
|
1812
|
-
if (
|
|
1813
|
-
|
|
1884
|
+
f.hidden = !1, f.classList.toggle("asking", h !== "idle");
|
|
1885
|
+
const p = y ? `<div class="after err">${v(y)}</div>` : "";
|
|
1886
|
+
if (h === "idle") {
|
|
1887
|
+
if (c.signedIn) {
|
|
1888
|
+
f.innerHTML = `<span class="who">Signed in as <strong>${v(c.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
|
|
1814
1889
|
return;
|
|
1815
1890
|
}
|
|
1816
|
-
const
|
|
1817
|
-
|
|
1891
|
+
const g = (L = t.config.user) == null ? void 0 : L.email;
|
|
1892
|
+
f.innerHTML = `<span class="who">${c.mode === "required" ? "Sign in to report a bug here." : g ? `Reporting as <strong>${v(g)}</strong>.` : "Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;
|
|
1818
1893
|
return;
|
|
1819
1894
|
}
|
|
1820
|
-
if (
|
|
1821
|
-
|
|
1895
|
+
if (h === "email") {
|
|
1896
|
+
f.innerHTML = `
|
|
1822
1897
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
1823
|
-
It's how you hear back about this report${
|
|
1898
|
+
It's how you hear back about this report${c.mode === "required" ? ", and this project asks for it" : ""}.</p>
|
|
1824
1899
|
<div class="row">
|
|
1825
|
-
<input type="email" data-fld="email" value="${v(
|
|
1900
|
+
<input type="email" data-fld="email" value="${v(b)}"
|
|
1826
1901
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1827
|
-
aria-label="Your email address" ${
|
|
1828
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1829
|
-
${
|
|
1902
|
+
aria-label="Your email address" ${s ? "disabled" : ""} />
|
|
1903
|
+
<button type="button" class="primary" data-act="code" ${s ? "disabled" : ""}>
|
|
1904
|
+
${s ? "Sending…" : "Send code"}
|
|
1830
1905
|
</button>
|
|
1831
1906
|
</div>
|
|
1832
|
-
${
|
|
1833
|
-
${
|
|
1907
|
+
${p}
|
|
1908
|
+
${c.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
|
|
1834
1909
|
return;
|
|
1835
1910
|
}
|
|
1836
|
-
|
|
1837
|
-
<p class="why">We sent a code to <strong>${v(
|
|
1911
|
+
f.innerHTML = `
|
|
1912
|
+
<p class="why">We sent a code to <strong>${v(b)}</strong>. It expires in ten minutes.</p>
|
|
1838
1913
|
<div class="row">
|
|
1839
|
-
<input type="text" class="code" data-fld="code" value="${v(
|
|
1914
|
+
<input type="text" class="code" data-fld="code" value="${v(k)}"
|
|
1840
1915
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
1841
|
-
maxlength="8" aria-label="The code we emailed you" ${
|
|
1842
|
-
<button type="button" class="primary" data-act="confirm" ${
|
|
1843
|
-
${
|
|
1916
|
+
maxlength="8" aria-label="The code we emailed you" ${s ? "disabled" : ""} />
|
|
1917
|
+
<button type="button" class="primary" data-act="confirm" ${s ? "disabled" : ""}>
|
|
1918
|
+
${s ? "Checking…" : "Sign in"}
|
|
1844
1919
|
</button>
|
|
1845
1920
|
</div>
|
|
1846
|
-
${
|
|
1921
|
+
${p}
|
|
1847
1922
|
<div class="after">
|
|
1848
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1849
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1923
|
+
<button type="button" class="link" data-act="resend" ${s ? "disabled" : ""}>Send it again</button>
|
|
1924
|
+
<button type="button" class="link" data-act="signin-back" ${s ? "disabled" : ""}>Use another address</button>
|
|
1850
1925
|
</div>`;
|
|
1851
1926
|
}
|
|
1852
|
-
function n({ focus:
|
|
1853
|
-
var
|
|
1854
|
-
if (
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
}),
|
|
1862
|
-
|
|
1927
|
+
function n({ focus: p = !1 } = {}) {
|
|
1928
|
+
var g;
|
|
1929
|
+
if (a(), T(), !p || s) return;
|
|
1930
|
+
const L = f.querySelector("[data-fld]");
|
|
1931
|
+
L && (L.focus(), (g = L.setSelectionRange) == null || g.call(L, L.value.length, L.value.length));
|
|
1932
|
+
}
|
|
1933
|
+
f.addEventListener("input", (p) => {
|
|
1934
|
+
const L = p.target.closest("[data-fld]");
|
|
1935
|
+
L && (L.dataset.fld === "email" ? b = L.value : k = L.value);
|
|
1936
|
+
}), f.addEventListener("keydown", (p) => {
|
|
1937
|
+
p.key !== "Enter" || !p.target.closest("[data-fld]") || (p.preventDefault(), h === "email" ? i() : r());
|
|
1863
1938
|
});
|
|
1864
|
-
async function
|
|
1865
|
-
const
|
|
1866
|
-
if (!
|
|
1867
|
-
|
|
1939
|
+
async function i({ resent: p = !1 } = {}) {
|
|
1940
|
+
const L = b.trim();
|
|
1941
|
+
if (!L) {
|
|
1942
|
+
y = "Enter the address to send the code to.", n({ focus: !0 });
|
|
1868
1943
|
return;
|
|
1869
1944
|
}
|
|
1870
|
-
|
|
1945
|
+
s = !0, y = "", n();
|
|
1871
1946
|
try {
|
|
1872
|
-
await t.signIn(
|
|
1873
|
-
} catch (
|
|
1874
|
-
|
|
1947
|
+
await t.signIn(L), b = L, p || (k = ""), h = "code";
|
|
1948
|
+
} catch (g) {
|
|
1949
|
+
y = g.message;
|
|
1875
1950
|
} finally {
|
|
1876
|
-
|
|
1951
|
+
s = !1, n({ focus: !0 });
|
|
1877
1952
|
}
|
|
1878
1953
|
}
|
|
1879
|
-
async function
|
|
1880
|
-
const
|
|
1881
|
-
if (!
|
|
1882
|
-
|
|
1954
|
+
async function r() {
|
|
1955
|
+
const p = k.trim();
|
|
1956
|
+
if (!p) {
|
|
1957
|
+
y = "Enter the code we emailed you.", n({ focus: !0 });
|
|
1883
1958
|
return;
|
|
1884
1959
|
}
|
|
1885
|
-
|
|
1960
|
+
s = !0, y = "", n();
|
|
1886
1961
|
try {
|
|
1887
|
-
const
|
|
1888
|
-
|
|
1889
|
-
} catch (
|
|
1890
|
-
|
|
1962
|
+
const L = await t.confirmSignIn(b.trim(), p);
|
|
1963
|
+
c.signedIn = L, h = "idle", k = "", o(""), e.offerCall();
|
|
1964
|
+
} catch (L) {
|
|
1965
|
+
y = L.message;
|
|
1891
1966
|
} finally {
|
|
1892
|
-
|
|
1967
|
+
s = !1, n({ focus: h !== "idle" });
|
|
1893
1968
|
}
|
|
1894
1969
|
}
|
|
1895
|
-
|
|
1896
|
-
const
|
|
1897
|
-
if (!
|
|
1898
|
-
const
|
|
1899
|
-
if (
|
|
1900
|
-
|
|
1970
|
+
f.addEventListener("click", async (p) => {
|
|
1971
|
+
const L = p.target.closest("button[data-act]");
|
|
1972
|
+
if (!L) return;
|
|
1973
|
+
const g = L.dataset.act;
|
|
1974
|
+
if (g === "signin") {
|
|
1975
|
+
h = "email", y = "", n({ focus: !0 });
|
|
1901
1976
|
return;
|
|
1902
1977
|
}
|
|
1903
|
-
if (
|
|
1904
|
-
|
|
1978
|
+
if (g === "skip") {
|
|
1979
|
+
h = "idle", y = "", n();
|
|
1905
1980
|
return;
|
|
1906
1981
|
}
|
|
1907
|
-
if (
|
|
1908
|
-
|
|
1982
|
+
if (g === "signin-back") {
|
|
1983
|
+
h = "email", y = "", k = "", n({ focus: !0 });
|
|
1909
1984
|
return;
|
|
1910
1985
|
}
|
|
1911
|
-
if (
|
|
1912
|
-
|
|
1986
|
+
if (g === "code") {
|
|
1987
|
+
i();
|
|
1913
1988
|
return;
|
|
1914
1989
|
}
|
|
1915
|
-
if (
|
|
1916
|
-
|
|
1990
|
+
if (g === "resend") {
|
|
1991
|
+
i({ resent: !0 });
|
|
1917
1992
|
return;
|
|
1918
1993
|
}
|
|
1919
|
-
if (
|
|
1920
|
-
|
|
1994
|
+
if (g === "confirm") {
|
|
1995
|
+
r();
|
|
1921
1996
|
return;
|
|
1922
1997
|
}
|
|
1923
|
-
if (
|
|
1924
|
-
|
|
1998
|
+
if (g === "signout") {
|
|
1999
|
+
s = !0, n();
|
|
1925
2000
|
try {
|
|
1926
2001
|
await t.signOut();
|
|
1927
2002
|
} finally {
|
|
1928
|
-
|
|
2003
|
+
c.signedIn = null, s = !1, h = c.mode === "required" ? "email" : "idle", n({ focus: h !== "idle" });
|
|
1929
2004
|
}
|
|
1930
2005
|
}
|
|
1931
2006
|
});
|
|
1932
|
-
async function
|
|
1933
|
-
const
|
|
1934
|
-
|
|
2007
|
+
async function $({ announce: p = !1 } = {}) {
|
|
2008
|
+
const L = await t.loginState();
|
|
2009
|
+
c = { mode: L.mode, signedIn: L.signedIn }, t.lastLoginMode = L.mode, x() && h === "idle" && (h = "email"), c.signedIn && (h = "idle"), p && L.signedOutReason && o(L.signedOutReason, "info"), n();
|
|
1935
2010
|
}
|
|
1936
|
-
|
|
2011
|
+
$({ announce: !0 }).catch(() => {
|
|
1937
2012
|
});
|
|
1938
|
-
function
|
|
1939
|
-
|
|
2013
|
+
function q() {
|
|
2014
|
+
c.mode !== "off" && $().catch(() => {
|
|
1940
2015
|
});
|
|
1941
2016
|
}
|
|
1942
|
-
e.mustSignIn =
|
|
2017
|
+
e.mustSignIn = x, e.recheckSignIn = q;
|
|
1943
2018
|
}
|
|
1944
|
-
function
|
|
2019
|
+
function fe(e) {
|
|
1945
2020
|
const t = e || [];
|
|
1946
2021
|
if (!t.length) return "";
|
|
1947
|
-
let
|
|
1948
|
-
return t.map((
|
|
1949
|
-
var
|
|
1950
|
-
const
|
|
1951
|
-
if (
|
|
1952
|
-
return
|
|
1953
|
-
const
|
|
1954
|
-
from:
|
|
1955
|
-
author: (
|
|
1956
|
-
automated: (
|
|
1957
|
-
body: (
|
|
1958
|
-
at:
|
|
1959
|
-
attachments: (
|
|
1960
|
-
},
|
|
1961
|
-
return
|
|
2022
|
+
let o = null, d = null;
|
|
2023
|
+
return t.map((l) => {
|
|
2024
|
+
var b, k, s, y;
|
|
2025
|
+
const S = Z(l.at), m = S && S !== o ? `<div class="day-sep" role="separator">${v(dt(l.at))}</div>` : "";
|
|
2026
|
+
if (m && (o = S, d = null), !l.from)
|
|
2027
|
+
return d = null, m + Lt(l);
|
|
2028
|
+
const f = {
|
|
2029
|
+
from: l.from,
|
|
2030
|
+
author: (b = l.reply) == null ? void 0 : b.author,
|
|
2031
|
+
automated: (k = l.reply) == null ? void 0 : k.automated,
|
|
2032
|
+
body: (s = l.reply) == null ? void 0 : s.body,
|
|
2033
|
+
at: l.at,
|
|
2034
|
+
attachments: (y = l.reply) == null ? void 0 : y.attachments
|
|
2035
|
+
}, c = St(f), h = d && d.who === c && Math.abs(new Date(l.at).getTime() - new Date(d.at).getTime()) < 5 * 6e4;
|
|
2036
|
+
return d = { who: c, at: l.at }, m + $e(f, h ? "cont" : "");
|
|
1962
2037
|
}).join("");
|
|
1963
2038
|
}
|
|
1964
|
-
function
|
|
2039
|
+
function St(e) {
|
|
1965
2040
|
return e.from === "reporter" ? "me" : e.automated ? "assistant" : `team:${e.author || ""}`;
|
|
1966
2041
|
}
|
|
1967
|
-
function
|
|
1968
|
-
const t =
|
|
2042
|
+
function Lt(e) {
|
|
2043
|
+
const t = xe(e.at);
|
|
1969
2044
|
return `
|
|
1970
2045
|
<div class="sys k-${v(e.kind)}">
|
|
1971
2046
|
<span class="dot" aria-hidden="true"></span>${v(e.summary || "")}${t ? `
|
|
1972
2047
|
<span class="t">· ${v(t)}</span>` : ""}
|
|
1973
2048
|
</div>`;
|
|
1974
2049
|
}
|
|
1975
|
-
function
|
|
1976
|
-
const
|
|
1977
|
-
let
|
|
1978
|
-
if (
|
|
1979
|
-
|
|
1980
|
-
else if (!
|
|
1981
|
-
const
|
|
1982
|
-
|
|
1983
|
-
}
|
|
1984
|
-
t.includes("cont") && (
|
|
1985
|
-
const
|
|
2050
|
+
function $e(e, t = "") {
|
|
2051
|
+
const o = e.from === "reporter", d = e.body || "", l = e.attachments || [], S = !o && !!e.automated, m = d ? `<span class="msg-text">${v(d)}</span>` : "", f = l.length ? `<div class="att">${l.map(Tt).join("")}</div>` : "";
|
|
2052
|
+
let c = "", h = "";
|
|
2053
|
+
if (S)
|
|
2054
|
+
c = '<span class="msg-who auto">Assistant <span class="tag">AI</span></span>', h = '<span class="av bot orb" aria-hidden="true"></span>';
|
|
2055
|
+
else if (!o) {
|
|
2056
|
+
const k = e.author || "Support team";
|
|
2057
|
+
c = `<span class="msg-who">${v(k)}</span>`, h = `<span class="av" aria-hidden="true">${v(ct(k))}</span>`;
|
|
2058
|
+
}
|
|
2059
|
+
t.includes("cont") && (c = "");
|
|
2060
|
+
const b = S && /it goes to the same person/i.test(d) ? `<div class="quick" role="group" aria-label="Answer">
|
|
1986
2061
|
<button type="button" data-quick="Yes, this is the problem">${F}That's right</button>
|
|
1987
2062
|
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
1988
|
-
</div>` :
|
|
2063
|
+
</div>` : S && Ve.test(d) ? `<div class="quick" role="group" aria-label="Did this answer your question?">
|
|
1989
2064
|
<button type="button" data-quick="Yes, that answers it">${F}Yes, that answers it</button>
|
|
1990
2065
|
<button type="button" data-quick="No, I still need help">No, I still need help</button>
|
|
1991
2066
|
</div>` : "";
|
|
1992
2067
|
return `
|
|
1993
|
-
<div class="msg-row ${
|
|
1994
|
-
${
|
|
1995
|
-
${
|
|
1996
|
-
<div class="bubble ${
|
|
1997
|
-
${
|
|
1998
|
-
<span class="msg-when">${v(
|
|
2068
|
+
<div class="msg-row ${o ? "mine" : "theirs"} ${S ? "auto" : ""} ${t}">
|
|
2069
|
+
${h}
|
|
2070
|
+
${c}
|
|
2071
|
+
<div class="bubble ${d ? "" : "silent"}">${m}${f}</div>
|
|
2072
|
+
${b}
|
|
2073
|
+
<span class="msg-when">${v(xe(e.at) || X(e.at))}</span>
|
|
1999
2074
|
</div>`;
|
|
2000
2075
|
}
|
|
2001
|
-
function
|
|
2076
|
+
function Qt() {
|
|
2002
2077
|
return `
|
|
2003
2078
|
<div class="typing-row">
|
|
2004
2079
|
<span class="av bot orb" aria-hidden="true"></span>
|
|
@@ -2006,450 +2081,700 @@ function ut() {
|
|
|
2006
2081
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
2007
2082
|
</div>`;
|
|
2008
2083
|
}
|
|
2009
|
-
function
|
|
2084
|
+
function Tt(e) {
|
|
2010
2085
|
const t = v(e.name || "attachment");
|
|
2011
2086
|
if (!e.url) return `<span class="file"><span class="nm">${t}</span></span>`;
|
|
2012
|
-
const
|
|
2013
|
-
return e.type === "SCREENSHOT" ? `<a href="${
|
|
2014
|
-
<a class="file" href="${
|
|
2087
|
+
const o = v(e.url);
|
|
2088
|
+
return e.type === "SCREENSHOT" ? `<a href="${o}" target="_blank" rel="noopener noreferrer"><img src="${o}" alt="${t}" loading="lazy"></a>` : e.type === "AUDIO" ? `<audio controls preload="metadata" src="${o}"></audio>` : e.type === "VIDEO" ? `<video controls preload="metadata" src="${o}"></video>` : `
|
|
2089
|
+
<a class="file" href="${o}" target="_blank" rel="noopener noreferrer" download>
|
|
2015
2090
|
<span class="nm">${t}</span>
|
|
2016
|
-
${e.size ? `<span class="sz">${v(
|
|
2091
|
+
${e.size ? `<span class="sz">${v(K(e.size))}</span>` : ""}
|
|
2017
2092
|
</a>`;
|
|
2018
2093
|
}
|
|
2019
|
-
function
|
|
2020
|
-
var
|
|
2021
|
-
const { client:
|
|
2022
|
-
|
|
2094
|
+
function qt(e, t, o, d) {
|
|
2095
|
+
var q;
|
|
2096
|
+
const { client: l, cfg: S } = e, m = document.createElement("div");
|
|
2097
|
+
m.className = "composer", m.innerHTML = `
|
|
2023
2098
|
<div class="staged" hidden></div>
|
|
2024
2099
|
<div class="row">
|
|
2025
2100
|
<div class="tools">
|
|
2026
|
-
${
|
|
2027
|
-
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${
|
|
2028
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
2029
|
-
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${
|
|
2101
|
+
${S.attachments === !1 ? "" : `
|
|
2102
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${ve}</button>
|
|
2103
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${he}</button>`}
|
|
2104
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${oe}</button>
|
|
2030
2105
|
</div>
|
|
2031
2106
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
2032
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
2107
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${ce}</button>
|
|
2033
2108
|
</div>
|
|
2034
2109
|
<div class="note" hidden></div>
|
|
2035
|
-
<input type="file" hidden multiple accept="${
|
|
2036
|
-
const
|
|
2037
|
-
let
|
|
2038
|
-
function n(
|
|
2039
|
-
|
|
2040
|
-
}
|
|
2041
|
-
function
|
|
2042
|
-
const
|
|
2043
|
-
|
|
2044
|
-
<span class="chip ${
|
|
2045
|
-
<span class="nm">${v(
|
|
2046
|
-
<span class="sz">${
|
|
2047
|
-
<button type="button" data-drop="${
|
|
2110
|
+
<input type="file" hidden multiple accept="${Oe.join(",")}">`, t.appendChild(m);
|
|
2111
|
+
const f = m.querySelector(".staged"), c = m.querySelector("textarea"), h = m.querySelector('[data-act="send"]'), b = m.querySelector('[data-act="voice"]'), k = m.querySelector('[data-act="livecall"]'), s = m.querySelector("input[type=file]"), y = m.querySelector(".note"), x = [];
|
|
2112
|
+
let T = null, a = !1;
|
|
2113
|
+
function n(w, p = "") {
|
|
2114
|
+
y.hidden = !w, y.className = `note ${p}`, y.textContent = w || "";
|
|
2115
|
+
}
|
|
2116
|
+
function i() {
|
|
2117
|
+
const w = x.filter((p) => p.storageKey);
|
|
2118
|
+
h.disabled = a || !c.value.trim() && !w.length, f.hidden = !x.length, f.innerHTML = x.map((p, L) => `
|
|
2119
|
+
<span class="chip ${p.storageKey ? "" : "uploading"}">
|
|
2120
|
+
<span class="nm">${v(p.name)}</span>
|
|
2121
|
+
<span class="sz">${p.storageKey ? K(p.size) : "sending…"}</span>
|
|
2122
|
+
<button type="button" data-drop="${L}" aria-label="Remove ${v(p.name)}">${pe}</button>
|
|
2048
2123
|
</span>`).join("");
|
|
2049
|
-
for (const
|
|
2050
|
-
|
|
2051
|
-
|
|
2124
|
+
for (const p of f.querySelectorAll("[data-drop]"))
|
|
2125
|
+
p.addEventListener("click", () => {
|
|
2126
|
+
x.splice(Number(p.dataset.drop), 1), i();
|
|
2052
2127
|
});
|
|
2053
2128
|
}
|
|
2054
|
-
async function
|
|
2055
|
-
const
|
|
2056
|
-
|
|
2129
|
+
async function r(w, p, L) {
|
|
2130
|
+
const g = { name: L, size: w.size, storageKey: null };
|
|
2131
|
+
x.push(g), i();
|
|
2057
2132
|
try {
|
|
2058
|
-
const { storageKey:
|
|
2059
|
-
|
|
2060
|
-
} catch (
|
|
2061
|
-
|
|
2133
|
+
const { storageKey: z, mime: M } = await l.uploadAttachment(w, p);
|
|
2134
|
+
g.storageKey = z, g.mime = M;
|
|
2135
|
+
} catch (z) {
|
|
2136
|
+
x.splice(x.indexOf(g), 1), n(z.message || "That file could not be sent.", "err");
|
|
2062
2137
|
}
|
|
2063
|
-
|
|
2138
|
+
i();
|
|
2064
2139
|
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
}),
|
|
2068
|
-
|
|
2069
|
-
}), (
|
|
2140
|
+
c.addEventListener("input", () => {
|
|
2141
|
+
c.style.height = "auto", c.style.height = `${Math.min(c.scrollHeight, 120)}px`, i();
|
|
2142
|
+
}), c.addEventListener("keydown", (w) => {
|
|
2143
|
+
w.key === "Enter" && !w.shiftKey && !w.isComposing && (w.preventDefault(), $());
|
|
2144
|
+
}), (q = m.querySelector('[data-act="attach"]')) == null || q.addEventListener("click", () => s.click()), s.addEventListener("change", () => {
|
|
2070
2145
|
n("");
|
|
2071
|
-
for (const
|
|
2072
|
-
if (
|
|
2073
|
-
n(`${
|
|
2146
|
+
for (const w of s.files) {
|
|
2147
|
+
if (w.size > l.config.maxAttachmentBytes) {
|
|
2148
|
+
n(`${w.name} is larger than ${K(l.config.maxAttachmentBytes)}.`, "err");
|
|
2074
2149
|
continue;
|
|
2075
2150
|
}
|
|
2076
|
-
|
|
2151
|
+
r(w, w.type, w.name);
|
|
2077
2152
|
}
|
|
2078
|
-
|
|
2079
|
-
}),
|
|
2080
|
-
if (
|
|
2081
|
-
const
|
|
2082
|
-
|
|
2083
|
-
const { blob:
|
|
2084
|
-
|
|
2153
|
+
s.value = "";
|
|
2154
|
+
}), b && !Be() && (b.disabled = !0, b.title = "This browser cannot record audio"), b == null || b.addEventListener("click", async () => {
|
|
2155
|
+
if (T) {
|
|
2156
|
+
const w = T;
|
|
2157
|
+
T = null, b.classList.remove("recording"), b.innerHTML = he, n("");
|
|
2158
|
+
const { blob: p, mime: L } = await w.stop();
|
|
2159
|
+
p.size && r(p, L, "Voice note");
|
|
2085
2160
|
return;
|
|
2086
2161
|
}
|
|
2087
2162
|
try {
|
|
2088
|
-
n(""),
|
|
2089
|
-
maxMs:
|
|
2090
|
-
onTick: (
|
|
2091
|
-
onAutoStop: () =>
|
|
2092
|
-
}),
|
|
2163
|
+
n(""), T = await Ne({
|
|
2164
|
+
maxMs: l.config.maxRecordingMs,
|
|
2165
|
+
onTick: (w) => n(`Recording — ${ae(w)}. Tap the mic to stop.`),
|
|
2166
|
+
onAutoStop: () => b.click()
|
|
2167
|
+
}), b.classList.add("recording"), b.innerHTML = Ue;
|
|
2093
2168
|
} catch {
|
|
2094
|
-
|
|
2169
|
+
T = null, n("The microphone is not available — check the browser permission.", "err");
|
|
2095
2170
|
}
|
|
2096
|
-
}),
|
|
2097
|
-
|
|
2171
|
+
}), l.canCallTeam(d).then((w) => {
|
|
2172
|
+
w && (k.hidden = !1, e.preloadCall());
|
|
2098
2173
|
}).catch(() => {
|
|
2099
|
-
}),
|
|
2100
|
-
|
|
2174
|
+
}), k.addEventListener("click", async () => {
|
|
2175
|
+
k.disabled = !0, n("");
|
|
2101
2176
|
try {
|
|
2102
|
-
const
|
|
2103
|
-
e.showLiveCall(t,
|
|
2104
|
-
} catch (
|
|
2105
|
-
n(
|
|
2177
|
+
const w = await l.startLiveCall(d);
|
|
2178
|
+
e.showLiveCall(t, o, w);
|
|
2179
|
+
} catch (w) {
|
|
2180
|
+
n(w.message.replace("[BugCatch] ", ""), "err");
|
|
2106
2181
|
} finally {
|
|
2107
|
-
|
|
2182
|
+
k.disabled = !1;
|
|
2108
2183
|
}
|
|
2109
|
-
}),
|
|
2110
|
-
var
|
|
2111
|
-
const
|
|
2112
|
-
!
|
|
2184
|
+
}), h.addEventListener("click", $), o.addEventListener("click", (w) => {
|
|
2185
|
+
var L, g;
|
|
2186
|
+
const p = (g = (L = w.target).closest) == null ? void 0 : g.call(L, "[data-quick]");
|
|
2187
|
+
!p || a || (c.value = p.dataset.quick, $());
|
|
2113
2188
|
});
|
|
2114
|
-
async function
|
|
2115
|
-
var
|
|
2116
|
-
const
|
|
2117
|
-
if (!(
|
|
2118
|
-
|
|
2189
|
+
async function $() {
|
|
2190
|
+
var L;
|
|
2191
|
+
const w = c.value.trim(), p = x.filter((g) => g.storageKey);
|
|
2192
|
+
if (!(a || !w && !p.length)) {
|
|
2193
|
+
a = !0, i(), n(""), o.insertAdjacentHTML("beforeend", $e({
|
|
2119
2194
|
from: "reporter",
|
|
2120
|
-
body:
|
|
2195
|
+
body: w,
|
|
2121
2196
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2122
|
-
attachments:
|
|
2123
|
-
}, "pending")),
|
|
2197
|
+
attachments: p.map((g) => ({ type: "FILE", name: g.name, size: g.size }))
|
|
2198
|
+
}, "pending")), G(o, { smooth: !0 });
|
|
2124
2199
|
try {
|
|
2125
|
-
await
|
|
2126
|
-
body:
|
|
2127
|
-
attachments:
|
|
2128
|
-
storageKey:
|
|
2129
|
-
mime:
|
|
2130
|
-
name:
|
|
2131
|
-
size:
|
|
2200
|
+
await l.replyToReport(d, {
|
|
2201
|
+
body: w,
|
|
2202
|
+
attachments: p.map((g) => ({
|
|
2203
|
+
storageKey: g.storageKey,
|
|
2204
|
+
mime: g.mime,
|
|
2205
|
+
name: g.name,
|
|
2206
|
+
size: g.size
|
|
2132
2207
|
}))
|
|
2133
|
-
}),
|
|
2134
|
-
} catch (
|
|
2135
|
-
(
|
|
2208
|
+
}), c.value = "", c.style.height = "auto", x.length = 0, await e.refreshThread(d);
|
|
2209
|
+
} catch (g) {
|
|
2210
|
+
(L = o.querySelector(".msg-row.pending")) == null || L.classList.replace("pending", "failed"), n(g.message || "That could not be sent — try again.", "err");
|
|
2136
2211
|
} finally {
|
|
2137
|
-
|
|
2212
|
+
a = !1, i();
|
|
2138
2213
|
}
|
|
2139
2214
|
}
|
|
2140
2215
|
}
|
|
2141
|
-
|
|
2216
|
+
i();
|
|
2142
2217
|
}
|
|
2143
|
-
|
|
2144
|
-
function he(e) {
|
|
2218
|
+
function Se(e) {
|
|
2145
2219
|
return JSON.stringify(e ? [e.score, e.current, e.comment || null] : null);
|
|
2146
2220
|
}
|
|
2147
|
-
function
|
|
2148
|
-
|
|
2221
|
+
function ue(e, {
|
|
2222
|
+
client: t,
|
|
2223
|
+
report: o,
|
|
2224
|
+
rating: d,
|
|
2225
|
+
justRated: l = !1,
|
|
2226
|
+
question: S = null,
|
|
2227
|
+
onRated: m = null,
|
|
2228
|
+
onError: f = null
|
|
2229
|
+
}) {
|
|
2230
|
+
var a;
|
|
2231
|
+
e.dataset.key = Se(d);
|
|
2232
|
+
const c = d != null && d.current ? d.score : 0, h = d ? d.current ? l ? "Thanks — the team will see that." : `You rated this ${d.score} out of 5.` : `You rated an earlier fix ${d.score} out of 5. How did this one go?` : S || "How did we do?", b = l && (d == null ? void 0 : d.current) && !d.comment;
|
|
2233
|
+
e.innerHTML = `
|
|
2234
|
+
<p class="fr-q">${v(h)}</p>
|
|
2235
|
+
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1, 2, 3, 4, 5].map((n) => `
|
|
2236
|
+
<button type="button" data-score="${n}" aria-pressed="${n === c}" aria-label="${n} out of 5${n === 1 ? ", poor" : n === 5 ? ", great" : ""}" class="${n <= c ? "on" : ""}">${ye}</button>`).join("")}
|
|
2237
|
+
</div>
|
|
2238
|
+
${d != null && d.current && d.comment ? `<p class="fr-said">“${v(d.comment)}”</p>` : ""}
|
|
2239
|
+
${b ? `
|
|
2240
|
+
<div class="fr-note">
|
|
2241
|
+
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${d.score <= 2 ? "What went wrong? (optional)" : "Anything to add? (optional)"}"></textarea>
|
|
2242
|
+
<button type="button" data-act="rating-note">Add note</button>
|
|
2243
|
+
</div>` : ""}
|
|
2244
|
+
${d ? "" : '<p class="fr-hint">1 is poor, 5 is great.</p>'}
|
|
2245
|
+
<p class="feedback-status" role="status"></p>`;
|
|
2246
|
+
const k = [...e.querySelectorAll("[data-score]")], s = (n) => k.forEach((i) => i.classList.toggle("on", Number(i.dataset.score) <= n)), y = (n) => e.querySelectorAll("button, textarea").forEach((i) => {
|
|
2247
|
+
i.disabled = n;
|
|
2248
|
+
}), x = e.querySelector(".feedback-status");
|
|
2249
|
+
async function T(n, i) {
|
|
2250
|
+
var r;
|
|
2251
|
+
y(!0), x.textContent = "";
|
|
2252
|
+
try {
|
|
2253
|
+
const $ = await t.rate(o.id, { score: n, comment: i });
|
|
2254
|
+
ue(e, {
|
|
2255
|
+
client: t,
|
|
2256
|
+
report: o,
|
|
2257
|
+
rating: $,
|
|
2258
|
+
justRated: !0,
|
|
2259
|
+
question: S,
|
|
2260
|
+
onRated: m,
|
|
2261
|
+
onError: f
|
|
2262
|
+
}), (r = e.querySelector(".fr-note textarea")) == null || r.focus(), m == null || m($);
|
|
2263
|
+
} catch ($) {
|
|
2264
|
+
x.textContent = $.message, y(!1), s(c), f == null || f($);
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
for (const n of k) {
|
|
2268
|
+
const i = Number(n.dataset.score);
|
|
2269
|
+
n.addEventListener("mouseenter", () => s(i)), n.addEventListener("focus", () => s(i)), n.addEventListener("blur", () => s(c)), n.addEventListener("click", () => T(i));
|
|
2270
|
+
}
|
|
2271
|
+
e.querySelector(".stars").addEventListener("mouseleave", () => s(c)), (a = e.querySelector('[data-act="rating-note"]')) == null || a.addEventListener("click", () => {
|
|
2272
|
+
var i;
|
|
2273
|
+
const n = e.querySelector(".fr-note textarea").value.trim();
|
|
2274
|
+
if (!n) {
|
|
2275
|
+
(i = e.querySelector(".fr-note")) == null || i.remove();
|
|
2276
|
+
return;
|
|
2277
|
+
}
|
|
2278
|
+
T(d.score, n);
|
|
2279
|
+
});
|
|
2149
2280
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2281
|
+
const le = /* @__PURE__ */ new WeakMap();
|
|
2282
|
+
function Et(e) {
|
|
2283
|
+
return e.rating ? ` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${ye}${Number(e.rating)}</span>` : e.ratingAsked ? ' · <span class="rate-ask">Rate it</span>' : "";
|
|
2284
|
+
}
|
|
2285
|
+
function Mt(e) {
|
|
2286
|
+
var T;
|
|
2152
2287
|
const {
|
|
2153
2288
|
client: t,
|
|
2154
|
-
scrim:
|
|
2155
|
-
close:
|
|
2289
|
+
scrim: o,
|
|
2290
|
+
close: d
|
|
2156
2291
|
} = e;
|
|
2157
|
-
let
|
|
2158
|
-
function
|
|
2159
|
-
if (
|
|
2160
|
-
|
|
2161
|
-
|
|
2292
|
+
let l = null;
|
|
2293
|
+
function S(a, { callFailed: n = null } = {}) {
|
|
2294
|
+
if (a != null && a.id && !n) {
|
|
2295
|
+
c(a.id, { fresh: !0 }).then((i) => {
|
|
2296
|
+
i || m(a, { callFailed: n });
|
|
2162
2297
|
});
|
|
2163
2298
|
return;
|
|
2164
2299
|
}
|
|
2165
|
-
|
|
2300
|
+
m(a, { callFailed: n });
|
|
2166
2301
|
}
|
|
2167
|
-
function
|
|
2168
|
-
var
|
|
2169
|
-
const
|
|
2170
|
-
|
|
2302
|
+
function m(a, { callFailed: n = null } = {}) {
|
|
2303
|
+
var q;
|
|
2304
|
+
const i = a != null && a.id ? String(a.id).slice(0, 8) : null, r = (q = a == null ? void 0 : a.estimate) != null && q.label ? String(a.estimate.label) : null, $ = n ? `<p class="eta">${v(n)} Your report is filed, and the team will reply in the chat.</p>` : "";
|
|
2305
|
+
o.querySelector(".panel").innerHTML = `
|
|
2171
2306
|
<div class="done">
|
|
2172
2307
|
<div class="tick">${F}</div>
|
|
2173
2308
|
<h3>Thanks — that's on its way.</h3>
|
|
2174
|
-
<p>${
|
|
2175
|
-
${
|
|
2176
|
-
${
|
|
2177
|
-
</div>`, setTimeout(
|
|
2178
|
-
}
|
|
2179
|
-
async function
|
|
2180
|
-
const
|
|
2181
|
-
clearTimeout(
|
|
2182
|
-
${
|
|
2183
|
-
<div class="history" aria-busy="true">${
|
|
2184
|
-
let
|
|
2309
|
+
<p>${i ? `Filed as <code>${v(i)}</code>.` : "The team has what they need to reproduce it."}</p>
|
|
2310
|
+
${$}
|
|
2311
|
+
${r ? `<p class="eta">Reports like this usually take <strong>${v(r)}</strong>. We'll let you know when it moves.</p>` : ""}
|
|
2312
|
+
</div>`, setTimeout(d, $ ? 6e3 : r ? 4e3 : 2e3);
|
|
2313
|
+
}
|
|
2314
|
+
async function f() {
|
|
2315
|
+
const a = o.querySelector(".panel");
|
|
2316
|
+
clearTimeout(h), l = null, a.classList.remove("is-chat"), a.innerHTML = `
|
|
2317
|
+
${de({ title: "Your reports", sub: "Where each one has got to.", theme: e.themeLabel() })}
|
|
2318
|
+
<div class="history" aria-busy="true">${st(3)}</div>`, a.querySelector('[data-act="close"]').addEventListener("click", d);
|
|
2319
|
+
let n = [];
|
|
2185
2320
|
try {
|
|
2186
|
-
({ reports:
|
|
2321
|
+
({ reports: n } = await t.myReports());
|
|
2187
2322
|
} catch {
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2323
|
+
const r = a.querySelector(".history");
|
|
2324
|
+
r && (r.innerHTML = ie("Couldn't load your reports just now.", P));
|
|
2190
2325
|
return;
|
|
2191
2326
|
}
|
|
2192
|
-
const
|
|
2193
|
-
if (
|
|
2194
|
-
|
|
2195
|
-
<button class="row" type="button" data-report="${v(
|
|
2196
|
-
<span class="row-ico" aria-hidden="true">${
|
|
2327
|
+
const i = a.querySelector(".history");
|
|
2328
|
+
if (i) {
|
|
2329
|
+
i.removeAttribute("aria-busy"), i.innerHTML = n.length ? n.map((r, $) => `
|
|
2330
|
+
<button class="row" type="button" data-report="${v(r.id)}" style="animation-delay:${Math.min($, 8) * 30}ms">
|
|
2331
|
+
<span class="row-ico" aria-hidden="true">${Fe}</span>
|
|
2197
2332
|
<span class="who">
|
|
2198
|
-
<span class="ttl">${v(
|
|
2199
|
-
<span class="sub">${v(
|
|
2333
|
+
<span class="ttl">${v(r.title)}</span>
|
|
2334
|
+
<span class="sub">${v(r.reference)} · ${v(X(r.createdAt))}${Et(r)}</span>
|
|
2200
2335
|
</span>
|
|
2201
|
-
<span class="pill ${v(String(
|
|
2202
|
-
<span class="chev" aria-hidden="true">${
|
|
2203
|
-
</button>`).join("") :
|
|
2204
|
-
for (const
|
|
2205
|
-
|
|
2336
|
+
<span class="pill ${v(String(r.status).toLowerCase())}">${v(se(r.status))}</span>
|
|
2337
|
+
<span class="chev" aria-hidden="true">${Xe}</span>
|
|
2338
|
+
</button>`).join("") : ie("You haven't reported anything yet.", Je);
|
|
2339
|
+
for (const r of i.querySelectorAll("[data-report]"))
|
|
2340
|
+
r.addEventListener("click", () => c(r.dataset.report));
|
|
2206
2341
|
}
|
|
2207
2342
|
}
|
|
2208
|
-
async function
|
|
2209
|
-
var
|
|
2210
|
-
const
|
|
2211
|
-
clearTimeout(
|
|
2212
|
-
${
|
|
2343
|
+
async function c(a, { fresh: n = !1 } = {}) {
|
|
2344
|
+
var p;
|
|
2345
|
+
const i = o.querySelector(".panel");
|
|
2346
|
+
clearTimeout(h), i.classList.add("is-chat"), i.innerHTML = `
|
|
2347
|
+
${de({
|
|
2213
2348
|
back: !0,
|
|
2214
|
-
title:
|
|
2215
|
-
sub:
|
|
2349
|
+
title: n ? "Looking into it" : "Your report",
|
|
2350
|
+
sub: n ? "It may ask you a question here." : "Updates, and a way to reply.",
|
|
2216
2351
|
theme: e.themeLabel()
|
|
2217
2352
|
})}
|
|
2218
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
2219
|
-
let
|
|
2353
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${lt()}</div></div>`, i.querySelector('[data-act="close"]').addEventListener("click", d), i.querySelector('[data-act="back"]').addEventListener("click", f);
|
|
2354
|
+
let r = null;
|
|
2220
2355
|
try {
|
|
2221
|
-
|
|
2356
|
+
r = await t.myReport(a);
|
|
2222
2357
|
} catch {
|
|
2223
|
-
|
|
2358
|
+
r = null;
|
|
2224
2359
|
}
|
|
2225
|
-
const
|
|
2226
|
-
if (
|
|
2227
|
-
if (!
|
|
2228
|
-
return
|
|
2229
|
-
|
|
2230
|
-
const
|
|
2231
|
-
|
|
2360
|
+
const $ = i.querySelector(".history");
|
|
2361
|
+
if (!$ || !i.querySelector('[data-act="back"]')) return !1;
|
|
2362
|
+
if (!r)
|
|
2363
|
+
return n ? (i.classList.remove("is-chat"), !1) : ($.removeAttribute("aria-busy"), $.innerHTML = ie("Couldn't load that report just now.", P), !1);
|
|
2364
|
+
l = a, t.markReportRead(a);
|
|
2365
|
+
const q = fe(r.timeline);
|
|
2366
|
+
$.classList.add("chatting"), $.removeAttribute("aria-busy"), $.innerHTML = `
|
|
2232
2367
|
<div class="report-head">
|
|
2233
|
-
<span class="ttl">${v(
|
|
2234
|
-
<span class="sub">${v(
|
|
2235
|
-
<span class="pill ${v(String(
|
|
2236
|
-
${(
|
|
2368
|
+
<span class="ttl">${v(r.title)}</span>
|
|
2369
|
+
<span class="sub">${v(r.reference)} · ${v(r.project || "")}</span>
|
|
2370
|
+
<span class="pill ${v(String(r.status).toLowerCase())}">${v(se(r.status))}</span>
|
|
2371
|
+
${(p = r.estimate) != null && p.label ? `<span class="eta-line">Usually takes ${v(String(r.estimate.label))}</span>` : ""}
|
|
2237
2372
|
</div>
|
|
2238
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
2239
|
-
const
|
|
2240
|
-
return
|
|
2373
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${q}</div>`;
|
|
2374
|
+
const w = $.querySelector(".thread");
|
|
2375
|
+
return le.set(w, q), G(w), k($, r), s($, r), r.canReply && qt(e, $, w, a), b($, r, a), G(w), !0;
|
|
2241
2376
|
}
|
|
2242
|
-
let
|
|
2243
|
-
function
|
|
2244
|
-
var
|
|
2245
|
-
clearTimeout(
|
|
2246
|
-
const
|
|
2247
|
-
let
|
|
2248
|
-
if (!
|
|
2249
|
-
|
|
2377
|
+
let h = null;
|
|
2378
|
+
function b(a, n, i) {
|
|
2379
|
+
var O, Q, I;
|
|
2380
|
+
clearTimeout(h);
|
|
2381
|
+
const r = n.assistant, $ = a.querySelector(".thread");
|
|
2382
|
+
let q = a.querySelector(".assistant");
|
|
2383
|
+
if (!r) {
|
|
2384
|
+
q == null || q.remove(), (O = $ == null ? void 0 : $.querySelector(".typing-row")) == null || O.remove();
|
|
2250
2385
|
return;
|
|
2251
2386
|
}
|
|
2252
|
-
const
|
|
2253
|
-
|
|
2254
|
-
const
|
|
2255
|
-
<div class="as-body${
|
|
2387
|
+
const w = (q == null ? void 0 : q.dataset.phase) || null;
|
|
2388
|
+
q || (q = document.createElement("div"), q.setAttribute("role", "status"), q.setAttribute("aria-live", "polite"), (Q = a.querySelector(".report-head")) == null || Q.after(q)), q.className = `assistant ${v(r.phase)}`, q.dataset.phase = r.phase;
|
|
2389
|
+
const p = r.steps || [], L = p.filter((H) => H.state === "done").length, g = p.some((H) => H.state === "active") ? 0.5 : 0, z = p.length ? Math.round((L + g) / p.length * 100) : 0, M = `
|
|
2390
|
+
<div class="as-body${w && w !== r.phase ? " entering" : ""}">
|
|
2256
2391
|
<div class="as-top">
|
|
2257
|
-
<span class="as-orb${
|
|
2392
|
+
<span class="as-orb${r.phase === "calling" || r.phase === "resolved" ? "" : " orb"}" aria-hidden="true">${r.phase === "calling" ? oe : r.phase === "resolved" ? F : ""}</span>
|
|
2258
2393
|
<div class="as-text">
|
|
2259
|
-
<div class="as-title">${v(
|
|
2260
|
-
<div class="as-detail">${v(
|
|
2394
|
+
<div class="as-title">${v(r.title)}</div>
|
|
2395
|
+
<div class="as-detail">${v(r.detail)}</div>
|
|
2261
2396
|
</div>
|
|
2262
2397
|
</div>
|
|
2263
2398
|
</div>
|
|
2264
|
-
${
|
|
2265
|
-
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${
|
|
2266
|
-
<ol class="as-steps">${
|
|
2267
|
-
if (
|
|
2268
|
-
const H =
|
|
2269
|
-
|
|
2270
|
-
const
|
|
2271
|
-
|
|
2272
|
-
|
|
2399
|
+
${p.length ? `
|
|
2400
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${z}"><i style="width:${z}%"></i></div>
|
|
2401
|
+
<ol class="as-steps">${p.map((H) => `<li class="${v(H.state)}"${H.state === "active" ? ' aria-current="step"' : ""}><span class="dot"></span><span class="lbl">${v(H.label)}</span></li>`).join("")}</ol>` : ""}`, A = JSON.stringify([r.phase, r.title, r.detail, p]);
|
|
2402
|
+
if (q.dataset.key !== A) {
|
|
2403
|
+
const H = q.querySelector(".as-progress i"), V = H == null ? void 0 : H.style.width;
|
|
2404
|
+
q.innerHTML = M, q.dataset.key = A;
|
|
2405
|
+
const B = q.querySelector(".as-progress i");
|
|
2406
|
+
B && V && (B.style.width = V, requestAnimationFrame(() => {
|
|
2407
|
+
B.style.width = `${z}%`;
|
|
2273
2408
|
}));
|
|
2274
2409
|
}
|
|
2275
|
-
if (
|
|
2276
|
-
const H =
|
|
2277
|
-
|
|
2410
|
+
if ($) {
|
|
2411
|
+
const H = be($), V = $.querySelector(".typing-row");
|
|
2412
|
+
r.phase !== "analyzing" ? V == null || V.remove() : (!V || V !== $.lastElementChild) && (V == null || V.remove(), $.insertAdjacentHTML("beforeend", Qt()), H && G($));
|
|
2278
2413
|
}
|
|
2279
|
-
|
|
2280
|
-
}
|
|
2281
|
-
function
|
|
2282
|
-
var
|
|
2283
|
-
if ((
|
|
2284
|
-
const
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2414
|
+
r.phase === "analyzing" ? h = setTimeout(() => y(i), 3e3) : r.phase === "calling" ? h = setTimeout(() => y(i), 1e4) : r.phase === "needs_info" && w !== "needs_info" && ((I = a.querySelector(".composer textarea")) == null || I.focus());
|
|
2415
|
+
}
|
|
2416
|
+
function k(a, n) {
|
|
2417
|
+
var r, $;
|
|
2418
|
+
if ((r = a.querySelector(".fix-verification")) == null || r.remove(), !n.resolvedAt || !["RESOLVED", "CLOSED"].includes(n.status)) return;
|
|
2419
|
+
const i = document.createElement("div");
|
|
2420
|
+
i.className = "fix-verification", n.verification ? i.textContent = n.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (i.innerHTML = '<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>', i.querySelectorAll("[data-result]").forEach((q) => {
|
|
2421
|
+
q.onclick = async () => {
|
|
2422
|
+
i.querySelectorAll("button").forEach((w) => {
|
|
2423
|
+
w.disabled = !0;
|
|
2289
2424
|
});
|
|
2290
2425
|
try {
|
|
2291
|
-
await t.verifyFix(
|
|
2292
|
-
} catch (
|
|
2293
|
-
|
|
2294
|
-
|
|
2426
|
+
await t.verifyFix(n.id, { result: q.dataset.result, resolvedAt: n.resolvedAt, note: i.querySelector("textarea").value }), await c(n.id);
|
|
2427
|
+
} catch (w) {
|
|
2428
|
+
i.querySelector(".feedback-status").textContent = w.message, i.querySelectorAll("button").forEach((p) => {
|
|
2429
|
+
p.disabled = !1;
|
|
2295
2430
|
});
|
|
2296
2431
|
}
|
|
2297
2432
|
};
|
|
2298
|
-
})), (
|
|
2433
|
+
})), ($ = a.querySelector(".report-head")) == null || $.after(i);
|
|
2299
2434
|
}
|
|
2300
|
-
function
|
|
2301
|
-
var
|
|
2302
|
-
let
|
|
2303
|
-
if (!["RESOLVED", "CLOSED"].includes(
|
|
2304
|
-
|
|
2435
|
+
function s(a, n) {
|
|
2436
|
+
var $;
|
|
2437
|
+
let i = a.querySelector(".fix-rating");
|
|
2438
|
+
if (!["RESOLVED", "CLOSED"].includes(n.status) || !n.ratingAsked) {
|
|
2439
|
+
i == null || i.remove();
|
|
2305
2440
|
return;
|
|
2306
2441
|
}
|
|
2307
|
-
|
|
2308
|
-
}
|
|
2309
|
-
function
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2442
|
+
i && i.dataset.key === Se(n.rating) || (i || (i = document.createElement("div"), i.className = "fix-rating", ($ = a.querySelector(".fix-verification") || a.querySelector(".report-head")) == null || $.after(i)), ue(i, { client: t, report: n, rating: n.rating || null }));
|
|
2443
|
+
}
|
|
2444
|
+
async function y(a) {
|
|
2445
|
+
const n = o.querySelector(".history.chatting"), i = n == null ? void 0 : n.querySelector(".thread");
|
|
2446
|
+
if (!i || l !== a) return;
|
|
2447
|
+
let r = null;
|
|
2448
|
+
try {
|
|
2449
|
+
r = await t.myReport(a);
|
|
2450
|
+
} catch {
|
|
2451
|
+
}
|
|
2452
|
+
if (e.closed || !r || l !== a) return;
|
|
2453
|
+
k(n, r), s(n, r);
|
|
2454
|
+
const $ = be(i), q = fe(r.timeline);
|
|
2455
|
+
le.get(i) !== q && (i.innerHTML = q, le.set(i, q)), b(n, r, a), $ && G(i);
|
|
2456
|
+
const w = n.querySelector(".report-head .pill");
|
|
2457
|
+
w && (w.className = `pill ${String(r.status).toLowerCase()}`, w.textContent = se(r.status));
|
|
2458
|
+
}
|
|
2459
|
+
const x = t.on("update", (a) => {
|
|
2460
|
+
!l || (a == null ? void 0 : a.bugId) !== l || (t.markReportRead(l), y(l));
|
|
2461
|
+
});
|
|
2462
|
+
e.onDestroy(() => {
|
|
2463
|
+
x(), clearTimeout(h);
|
|
2464
|
+
}), (T = o.querySelector('[data-act="history"]')) == null || T.addEventListener("click", f), e.succeed = S, e.refreshThread = y, e.openReportId = () => l;
|
|
2465
|
+
}
|
|
2466
|
+
const Le = "bugcatch.rateLater", zt = 50;
|
|
2467
|
+
function Qe() {
|
|
2468
|
+
try {
|
|
2469
|
+
const e = JSON.parse(window.localStorage.getItem(Le) || "[]");
|
|
2470
|
+
return Array.isArray(e) ? e : [];
|
|
2471
|
+
} catch {
|
|
2472
|
+
return [];
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
function Ct(e) {
|
|
2476
|
+
try {
|
|
2477
|
+
const t = Qe().filter((o) => o !== e);
|
|
2478
|
+
t.push(e), window.localStorage.setItem(Le, JSON.stringify(t.slice(-zt)));
|
|
2479
|
+
} catch {
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
function At(e, t = Qe()) {
|
|
2483
|
+
const o = new Set(t), d = (e || []).filter((S) => S.ratingDue === "require" || S.ratingDue === "ask" && !o.has(S.id));
|
|
2484
|
+
if (!d.length) return null;
|
|
2485
|
+
const l = (S) => new Date(S.resolvedAt || S.updatedAt || 0).getTime() || 0;
|
|
2486
|
+
return d.reduce((S, m) => l(m) > l(S) ? m : S);
|
|
2487
|
+
}
|
|
2488
|
+
function Ht(e) {
|
|
2489
|
+
const {
|
|
2490
|
+
client: t,
|
|
2491
|
+
rateDue: o,
|
|
2492
|
+
compose: d,
|
|
2493
|
+
picks: l,
|
|
2494
|
+
known: S,
|
|
2495
|
+
callBtn: m,
|
|
2496
|
+
titleInput: f,
|
|
2497
|
+
scrim: c
|
|
2498
|
+
} = e;
|
|
2499
|
+
let h = !1;
|
|
2500
|
+
e.mustRate = () => h;
|
|
2501
|
+
function b(x) {
|
|
2502
|
+
h = x;
|
|
2503
|
+
for (const T of [d, l, S])
|
|
2504
|
+
T.classList.toggle("held", x), T.inert = x;
|
|
2505
|
+
x ? m.hidden = !0 : e.callOffered() && !e.mustSignIn() && (m.hidden = !1), e.refreshSendState();
|
|
2506
|
+
}
|
|
2507
|
+
function k() {
|
|
2508
|
+
h && b(!1);
|
|
2509
|
+
}
|
|
2510
|
+
function s() {
|
|
2511
|
+
o.hidden = !0, o.replaceChildren(), k(), f.focus();
|
|
2512
|
+
}
|
|
2513
|
+
function y(x) {
|
|
2514
|
+
var i;
|
|
2515
|
+
const T = x.ratingDue === "require", a = x.resolvedAt ? X(x.resolvedAt) : "", n = x.status === "CLOSED" ? "closed" : "fixed";
|
|
2516
|
+
if (o.hidden = !1, o.classList.toggle("is-required", T), o.innerHTML = `
|
|
2517
|
+
<div class="rd-head">
|
|
2518
|
+
<span class="rd-eyebrow">${T ? "Before you report something new" : `Your report was ${n}`}</span>
|
|
2519
|
+
${T ? "" : '<button type="button" class="link rd-later" data-act="rate-later">Not now</button>'}
|
|
2317
2520
|
</div>
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
<
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2521
|
+
<p class="rd-report">
|
|
2522
|
+
<span class="rd-ico" aria-hidden="true">${F}</span>
|
|
2523
|
+
<span class="rd-ttl">${v(x.title)}</span>
|
|
2524
|
+
<span class="rd-sub">${v(x.reference)}${a ? ` · ${n} ${v(a)}` : ""}</span>
|
|
2525
|
+
</p>
|
|
2526
|
+
<div class="rd-stars"></div>`, (i = o.querySelector('[data-act="rate-later"]')) == null || i.addEventListener("click", () => {
|
|
2527
|
+
Ct(x.id), s();
|
|
2528
|
+
}), ue(o.querySelector(".rd-stars"), {
|
|
2529
|
+
client: t,
|
|
2530
|
+
report: x,
|
|
2531
|
+
rating: null,
|
|
2532
|
+
question: T ? "How did we handle it? Rate it to send a new one." : "How did we do?",
|
|
2533
|
+
onRated: () => {
|
|
2534
|
+
var r;
|
|
2535
|
+
o.querySelector(".rd-eyebrow").textContent = `Your report was ${n}`, (r = o.querySelector('[data-act="skip"]')) == null || r.remove(), o.classList.remove("is-required"), k();
|
|
2536
|
+
},
|
|
2537
|
+
// The rating could not be sent. A held form must not turn into a locked
|
|
2538
|
+
// door because of our outage: offer the way past.
|
|
2539
|
+
onError: () => {
|
|
2540
|
+
if (!h || o.querySelector('[data-act="skip"]')) return;
|
|
2541
|
+
const r = document.createElement("button");
|
|
2542
|
+
r.type = "button", r.className = "link rd-later", r.dataset.act = "skip", r.textContent = "Skip for now", r.addEventListener("click", s), o.querySelector(".rd-head").append(r);
|
|
2337
2543
|
}
|
|
2544
|
+
}), T) {
|
|
2545
|
+
b(!0);
|
|
2546
|
+
const r = c.getRootNode().activeElement;
|
|
2547
|
+
(!r || !o.contains(r)) && o.focus();
|
|
2338
2548
|
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2549
|
+
}
|
|
2550
|
+
t.hasReports() && t.myReports().then(({ reports: x }) => {
|
|
2551
|
+
if (e.closed) return;
|
|
2552
|
+
const T = At(x);
|
|
2553
|
+
T && y(T);
|
|
2554
|
+
}).catch(() => {
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2557
|
+
const ge = {
|
|
2558
|
+
idea: { label: "Idea", icon: at },
|
|
2559
|
+
praise: { label: "Praise", icon: rt },
|
|
2560
|
+
confusing: { label: "Confusing", icon: ot },
|
|
2561
|
+
other: { label: "Other", icon: nt }
|
|
2562
|
+
}, Te = [
|
|
2563
|
+
{ score: 1, word: "Terrible", mouth: "M7.8 17.2c1.1-2 2.5-2.9 4.2-2.9s3.1.9 4.2 2.9M8 8l2.4 1.2M16 8l-2.4 1.2" },
|
|
2564
|
+
{ score: 2, word: "Not great", mouth: "M8.6 16c1-.8 2.1-1.2 3.4-1.2s2.4.4 3.4 1.2" },
|
|
2565
|
+
{ score: 3, word: "Okay", mouth: "M8.8 15.2h6.4" },
|
|
2566
|
+
{ score: 4, word: "Good", mouth: "M8.6 14.4c1 .9 2.1 1.4 3.4 1.4s2.4-.5 3.4-1.4" },
|
|
2567
|
+
{ score: 5, word: "Great", mouth: "M7.8 13.2h8.4a4.2 4.2 0 0 1-8.4 0z" }
|
|
2568
|
+
];
|
|
2569
|
+
function It(e) {
|
|
2570
|
+
return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9.2"/><path d="M9 9.9h.01M15 9.9h.01" stroke-width="2.6"/><path d="${e}"/></svg>`;
|
|
2571
|
+
}
|
|
2572
|
+
function Rt() {
|
|
2573
|
+
return `
|
|
2574
|
+
<div class="feedback fb-only">
|
|
2575
|
+
<div class="field">
|
|
2576
|
+
<label for="bc-fb-msg">What's on your mind?</label>
|
|
2577
|
+
<textarea id="bc-fb-msg" maxlength="${We}" aria-describedby="bc-fb-err"
|
|
2578
|
+
placeholder="An idea, something you like, or something that confused you."></textarea>
|
|
2579
|
+
<p class="field-err" id="bc-fb-err" hidden></p>
|
|
2580
|
+
</div>
|
|
2581
|
+
<div class="field">
|
|
2582
|
+
<label id="bc-fb-kind-l">What kind is it? <span class="opt">(optional)</span></label>
|
|
2583
|
+
<div class="kinds" role="group" aria-labelledby="bc-fb-kind-l">
|
|
2584
|
+
${Ye.map((e) => `
|
|
2585
|
+
<button class="tool" type="button" data-kind="${e}" aria-pressed="false">${ge[e].icon}${ge[e].label}</button>
|
|
2586
|
+
`).join("")}
|
|
2587
|
+
</div>
|
|
2588
|
+
</div>
|
|
2589
|
+
<div class="field">
|
|
2590
|
+
<div class="field-head">
|
|
2591
|
+
<label id="bc-fb-score-l">How's your experience so far? <span class="opt">(optional)</span></label>
|
|
2592
|
+
<span class="count face-word" aria-hidden="true"></span>
|
|
2593
|
+
</div>
|
|
2594
|
+
<div class="faces" role="group" aria-labelledby="bc-fb-score-l">
|
|
2595
|
+
${Te.map((e) => `
|
|
2596
|
+
<button class="face" type="button" data-score="${e.score}" aria-pressed="false"
|
|
2597
|
+
aria-label="${e.word}" title="${e.word}">${It(e.mouth)}</button>
|
|
2598
|
+
`).join("")}
|
|
2599
|
+
</div>
|
|
2600
|
+
</div>
|
|
2601
|
+
<!-- Who it is from: an address to write back to when the page knows
|
|
2602
|
+
none, and a line saying which one when it does. -->
|
|
2603
|
+
<div class="field fb-who"></div>
|
|
2604
|
+
</div>`;
|
|
2605
|
+
}
|
|
2606
|
+
function Dt(e) {
|
|
2607
|
+
var g, z;
|
|
2608
|
+
const { client: t, cfg: o, scrim: d, $: l, say: S, close: m } = e, f = l(".feedback"), c = l("#bc-fb-msg"), h = l("#bc-fb-err"), b = l('[data-act="send-feedback"]'), k = l(".face-word");
|
|
2609
|
+
let s = null, y = null, x = !1, T = !1;
|
|
2610
|
+
const a = l(".fb-who"), n = ((g = t.signedInAs()) == null ? void 0 : g.email) || ((z = o.user) == null ? void 0 : z.email) || null;
|
|
2611
|
+
n ? a.innerHTML = `<p class="fb-as">Sent as <strong>${v(n)}</strong></p>` : a.innerHTML = `
|
|
2612
|
+
<label for="bc-fb-email">Your email <span class="opt">(optional — only if you'd like a reply)</span></label>
|
|
2613
|
+
<input id="bc-fb-email" type="email" autocomplete="email" placeholder="you@example.com" />`;
|
|
2614
|
+
const i = l("#bc-fb-email"), r = `bugcatch.feedbackDraft:${o.projectId || ""}`, $ = o.drafts !== !1;
|
|
2615
|
+
if ($)
|
|
2616
|
+
try {
|
|
2617
|
+
c.value = localStorage.getItem(r) || "";
|
|
2618
|
+
} catch {
|
|
2342
2619
|
}
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
(
|
|
2348
|
-
|
|
2620
|
+
let q;
|
|
2621
|
+
function w() {
|
|
2622
|
+
if (clearTimeout(q), !!$)
|
|
2623
|
+
try {
|
|
2624
|
+
c.value.trim() ? localStorage.setItem(r, c.value) : localStorage.removeItem(r);
|
|
2625
|
+
} catch {
|
|
2349
2626
|
}
|
|
2350
|
-
|
|
2627
|
+
}
|
|
2628
|
+
c.addEventListener("input", () => {
|
|
2629
|
+
c.value.trim() && p(""), clearTimeout(q), q = setTimeout(w, 250);
|
|
2630
|
+
}), e.onDestroy(() => {
|
|
2631
|
+
T || w();
|
|
2632
|
+
}), f.querySelectorAll("[data-kind]").forEach((M) => {
|
|
2633
|
+
M.addEventListener("click", () => {
|
|
2634
|
+
s = s === M.dataset.kind ? null : M.dataset.kind, f.querySelectorAll("[data-kind]").forEach((A) => A.setAttribute("aria-pressed", String(A.dataset.kind === s)));
|
|
2635
|
+
});
|
|
2636
|
+
}), f.querySelectorAll("[data-score]").forEach((M) => {
|
|
2637
|
+
M.addEventListener("click", () => {
|
|
2638
|
+
const A = Number(M.dataset.score);
|
|
2639
|
+
y = y === A ? null : A, f.querySelectorAll("[data-score]").forEach((O) => O.setAttribute("aria-pressed", String(Number(O.dataset.score) === y))), k.textContent = y ? Te[y - 1].word : "";
|
|
2351
2640
|
});
|
|
2641
|
+
});
|
|
2642
|
+
function p(M) {
|
|
2643
|
+
h.hidden = !M, h.innerHTML = M ? `${P}<span>${v(M)}</span>` : "", c.classList.toggle("invalid", !!M), c.setAttribute("aria-invalid", String(!!M));
|
|
2352
2644
|
}
|
|
2353
|
-
async
|
|
2354
|
-
|
|
2355
|
-
if (!
|
|
2356
|
-
|
|
2645
|
+
b.addEventListener("click", async () => {
|
|
2646
|
+
if (x) return;
|
|
2647
|
+
if (!c.value.trim()) {
|
|
2648
|
+
p("Write a few words — a sentence is plenty."), c.focus();
|
|
2649
|
+
return;
|
|
2650
|
+
}
|
|
2651
|
+
x = !0, e.sending = !0, S("");
|
|
2652
|
+
const M = b.innerHTML;
|
|
2653
|
+
b.disabled = !0, b.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
|
|
2357
2654
|
try {
|
|
2358
|
-
|
|
2359
|
-
|
|
2655
|
+
const A = await t.feedback({
|
|
2656
|
+
message: c.value,
|
|
2657
|
+
kind: s,
|
|
2658
|
+
score: y,
|
|
2659
|
+
...i && i.value.trim() ? { email: i.value.trim() } : {}
|
|
2660
|
+
});
|
|
2661
|
+
if (A != null && A.cancelled) throw Object.assign(new Error(""), { quiet: !0 });
|
|
2662
|
+
if (T = !0, clearTimeout(q), $)
|
|
2663
|
+
try {
|
|
2664
|
+
localStorage.removeItem(r);
|
|
2665
|
+
} catch {
|
|
2666
|
+
}
|
|
2667
|
+
L();
|
|
2668
|
+
} catch (A) {
|
|
2669
|
+
x = !1, e.sending = !1, b.disabled = !1, b.innerHTML = M, A.quiet || S(String(A.message || "That did not send. Please try again.").replace("[BugCatch] ", ""));
|
|
2360
2670
|
}
|
|
2361
|
-
if (e.closed || !s || b !== n) return;
|
|
2362
|
-
L(p, s), y(p, s);
|
|
2363
|
-
const u = pe(a), r = ue(s.timeline);
|
|
2364
|
-
se.get(a) !== r && (a.innerHTML = r, se.set(a, r)), d(p, s, n), u && _(a);
|
|
2365
|
-
const o = p.querySelector(".report-head .pill");
|
|
2366
|
-
o && (o.className = `pill ${String(s.status).toLowerCase()}`, o.textContent = ie(s.status));
|
|
2367
|
-
}
|
|
2368
|
-
const q = t.on("update", (n) => {
|
|
2369
|
-
!b || (n == null ? void 0 : n.bugId) !== b || (t.markReportRead(b), S(b));
|
|
2370
2671
|
});
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2672
|
+
function L() {
|
|
2673
|
+
e.sending = !1, d.querySelector(".panel").innerHTML = `
|
|
2674
|
+
<div class="done">
|
|
2675
|
+
<div class="tick">${F}</div>
|
|
2676
|
+
<h3>Thanks — that's with the team.</h3>
|
|
2677
|
+
<p>Everything sent here is read by the people who build this.</p>
|
|
2678
|
+
</div>`, setTimeout(m, 2600);
|
|
2679
|
+
}
|
|
2680
|
+
e.focusFeedback = () => c.focus();
|
|
2374
2681
|
}
|
|
2375
|
-
|
|
2682
|
+
const te = {
|
|
2683
|
+
report: { title: "Report a bug", sub: "We attach the page details for you." },
|
|
2684
|
+
feedback: { title: "Give feedback", sub: "The team reads every note." }
|
|
2685
|
+
};
|
|
2686
|
+
function Ot({
|
|
2376
2687
|
root: e,
|
|
2377
2688
|
host: t,
|
|
2378
|
-
dock:
|
|
2379
|
-
client:
|
|
2380
|
-
onClose:
|
|
2381
|
-
preloadCall:
|
|
2689
|
+
dock: o,
|
|
2690
|
+
client: d,
|
|
2691
|
+
onClose: l,
|
|
2692
|
+
preloadCall: S = () => {
|
|
2382
2693
|
},
|
|
2383
|
-
themeControls:
|
|
2694
|
+
themeControls: m = null,
|
|
2695
|
+
mode: f = "report"
|
|
2384
2696
|
}) {
|
|
2385
|
-
|
|
2386
|
-
const
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2697
|
+
jt(e);
|
|
2698
|
+
const c = d.config, h = () => (m == null ? void 0 : m.label()) || "", b = c.feedback !== !1;
|
|
2699
|
+
let k = b && f === "feedback" ? "feedback" : "report";
|
|
2700
|
+
const s = document.createElement("div");
|
|
2701
|
+
s.className = `scrim ${o.classList.contains("at-left") ? "at-left" : "at-right"} ${o.classList.contains("at-top") ? "at-top" : "at-bottom"}`, s.style.setProperty("--bc-dock-h", `${Math.round(o.getBoundingClientRect().height)}px`), s.innerHTML = `
|
|
2702
|
+
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h" data-mode="${k}">
|
|
2703
|
+
${de({
|
|
2390
2704
|
id: "bc-h",
|
|
2391
2705
|
// Not "Tell us what went wrong": that is the first field's own label,
|
|
2392
2706
|
// a few pixels below. The header names the errand the launcher named.
|
|
2393
|
-
title:
|
|
2394
|
-
sub:
|
|
2395
|
-
theme:
|
|
2707
|
+
title: te[k].title,
|
|
2708
|
+
sub: te[k].sub,
|
|
2709
|
+
theme: h()
|
|
2396
2710
|
})}
|
|
2711
|
+
${b ? `
|
|
2712
|
+
<div class="modes" role="group" aria-label="What would you like to do?">
|
|
2713
|
+
<button type="button" data-mode="report" aria-pressed="${k === "report"}">${Ze}Report a bug</button>
|
|
2714
|
+
<button type="button" data-mode="feedback" aria-pressed="${k === "feedback"}">${tt}Give feedback</button>
|
|
2715
|
+
</div>` : ""}
|
|
2397
2716
|
<div class="body">
|
|
2398
2717
|
<div class="slot" role="alert"></div>
|
|
2718
|
+
<!-- A settled report still waiting for its rating. Drawn only when the
|
|
2719
|
+
project asks for one here; see rate-due.js. -->
|
|
2720
|
+
<div class="rate-due fix-rating bug-only" tabindex="-1" hidden></div>
|
|
2399
2721
|
<!-- What the project's team is telling visitors. Drawn only when it
|
|
2400
2722
|
has published something. -->
|
|
2401
2723
|
<div class="notices" hidden></div>
|
|
2402
|
-
<div class="whoami" hidden></div>
|
|
2724
|
+
<div class="whoami bug-only" hidden></div>
|
|
2403
2725
|
<!-- The questions the assistant can answer from their account and
|
|
2404
2726
|
close by itself. Drawn only when the project offers any. -->
|
|
2405
|
-
<div class="picks" hidden></div>
|
|
2406
|
-
<div class="known" hidden></div>
|
|
2407
|
-
${
|
|
2727
|
+
<div class="picks bug-only" hidden></div>
|
|
2728
|
+
<div class="known bug-only" hidden></div>
|
|
2729
|
+
${ft(c)}
|
|
2730
|
+
${b ? Rt() : ""}
|
|
2408
2731
|
</div>
|
|
2409
2732
|
<div class="foot">
|
|
2410
|
-
<span class="note" aria-live="polite"></span>
|
|
2411
|
-
${
|
|
2733
|
+
<span class="note bug-only" aria-live="polite"></span>
|
|
2734
|
+
${d.hasReports() ? '<button class="quiet" type="button" data-act="history">Your reports</button>' : ""}
|
|
2412
2735
|
<span class="spacer"></span>
|
|
2413
2736
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
2414
2737
|
most cannot. Drawn here rather than as a second launcher because it
|
|
2415
2738
|
is the same errand as Send report — the difference is only whether
|
|
2416
2739
|
the reporter would rather say it than type it. -->
|
|
2417
|
-
<button class="ghost" type="button" data-act="call" hidden>${
|
|
2418
|
-
<button class="primary" type="button" data-act="send">Send report ${
|
|
2740
|
+
<button class="ghost bug-only" type="button" data-act="call" hidden>${oe}Talk to the team</button>
|
|
2741
|
+
<button class="primary bug-only" type="button" data-act="send">Send report ${ce}</button>
|
|
2742
|
+
${b ? `<button class="primary fb-only" type="button" data-act="send-feedback">Send feedback ${ce}</button>` : ""}
|
|
2419
2743
|
</div>
|
|
2420
2744
|
<div class="powered">Powered by
|
|
2421
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
2745
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${et}</a>
|
|
2422
2746
|
</div>
|
|
2423
2747
|
</div>`;
|
|
2424
|
-
const
|
|
2425
|
-
client:
|
|
2426
|
-
cfg:
|
|
2748
|
+
const y = (g) => s.querySelector(g), x = y(".slot"), T = [], a = {
|
|
2749
|
+
client: d,
|
|
2750
|
+
cfg: c,
|
|
2427
2751
|
root: e,
|
|
2428
2752
|
host: t,
|
|
2429
|
-
dock:
|
|
2430
|
-
scrim:
|
|
2431
|
-
$:
|
|
2432
|
-
titleInput:
|
|
2433
|
-
descInput:
|
|
2434
|
-
compose:
|
|
2435
|
-
sendBtn:
|
|
2436
|
-
callBtn:
|
|
2437
|
-
historyBtn:
|
|
2438
|
-
note:
|
|
2439
|
-
whoami:
|
|
2440
|
-
refsBox:
|
|
2441
|
-
notices:
|
|
2442
|
-
known:
|
|
2443
|
-
picks:
|
|
2753
|
+
dock: o,
|
|
2754
|
+
scrim: s,
|
|
2755
|
+
$: y,
|
|
2756
|
+
titleInput: y("#bc-title"),
|
|
2757
|
+
descInput: y("#bc-desc"),
|
|
2758
|
+
compose: y(".compose"),
|
|
2759
|
+
sendBtn: y('[data-act="send"]'),
|
|
2760
|
+
callBtn: y('[data-act="call"]'),
|
|
2761
|
+
historyBtn: y('[data-act="history"]'),
|
|
2762
|
+
note: y(".foot .note"),
|
|
2763
|
+
whoami: y(".whoami"),
|
|
2764
|
+
refsBox: y(".refs"),
|
|
2765
|
+
notices: y(".notices"),
|
|
2766
|
+
known: y(".known"),
|
|
2767
|
+
picks: y(".picks"),
|
|
2768
|
+
rateDue: y(".rate-due"),
|
|
2444
2769
|
// A report or a call is on its way. Escape and a click outside wait for it.
|
|
2445
2770
|
sending: !1,
|
|
2446
2771
|
closed: !1,
|
|
2447
|
-
say:
|
|
2448
|
-
close:
|
|
2449
|
-
preloadCall:
|
|
2450
|
-
themeLabel:
|
|
2451
|
-
onDestroy: (
|
|
2452
|
-
|
|
2772
|
+
say: L,
|
|
2773
|
+
close: w,
|
|
2774
|
+
preloadCall: S,
|
|
2775
|
+
themeLabel: h,
|
|
2776
|
+
onDestroy: (g) => {
|
|
2777
|
+
T.push(g);
|
|
2453
2778
|
},
|
|
2454
2779
|
// compose.js
|
|
2455
2780
|
refreshSendState: null,
|
|
@@ -2467,65 +2792,83 @@ function xt({
|
|
|
2467
2792
|
// signin.js
|
|
2468
2793
|
mustSignIn: null,
|
|
2469
2794
|
recheckSignIn: null,
|
|
2795
|
+
// rate-due.js
|
|
2796
|
+
mustRate: () => !1,
|
|
2797
|
+
// feedback.js
|
|
2798
|
+
focusFeedback: () => {
|
|
2799
|
+
},
|
|
2470
2800
|
// thread.js
|
|
2471
2801
|
succeed: null,
|
|
2472
2802
|
refreshThread: null,
|
|
2473
2803
|
openReportId: null
|
|
2474
2804
|
};
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2805
|
+
gt(a), mt(a), yt(a), xt(a), wt(a), kt(a), $t(a), Mt(a), Ht(a), b && Dt(a);
|
|
2806
|
+
function n(g, { focus: z = !0 } = {}) {
|
|
2807
|
+
const M = g === "feedback" && y(".modes") ? "feedback" : "report", A = s.querySelector(".panel");
|
|
2808
|
+
a.closed || a.sending || !A || !s.querySelector(".modes") || M === "feedback" && a.isRecording() || (k = M, A.dataset.mode = M, A.querySelector("#bc-h").textContent = te[M].title, A.querySelector(".head .titles p").textContent = te[M].sub, s.querySelectorAll(".modes [data-mode]").forEach((O) => {
|
|
2809
|
+
O.setAttribute("aria-pressed", String(O.dataset.mode === M));
|
|
2810
|
+
}), L(""), z && (M === "feedback" ? a.focusFeedback() : a.titleInput.focus()));
|
|
2480
2811
|
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2812
|
+
s.querySelectorAll(".modes [data-mode]").forEach((g) => {
|
|
2813
|
+
g.addEventListener("click", () => n(g.dataset.mode));
|
|
2814
|
+
}), b && d.feedbackEnabled().then((g) => {
|
|
2815
|
+
var M, A, O;
|
|
2816
|
+
if (g || a.closed || a.sending) return;
|
|
2817
|
+
n("report", { focus: k === "feedback" }), (M = s.querySelector(".modes")) == null || M.remove(), (A = s.querySelector(".feedback")) == null || A.remove(), (O = s.querySelector('[data-act="send-feedback"]')) == null || O.remove();
|
|
2818
|
+
});
|
|
2819
|
+
const i = document.activeElement, r = document.documentElement.style, $ = r.overflow;
|
|
2820
|
+
r.overflow = "hidden";
|
|
2821
|
+
function q() {
|
|
2822
|
+
a.closed || (T.forEach((g) => g()), a.closed = !0, r.overflow = $, document.removeEventListener("keydown", p, !0), s.remove(), o.hidden = !1, t.style.opacity = "", l == null || l());
|
|
2823
|
+
}
|
|
2824
|
+
function w() {
|
|
2825
|
+
var g;
|
|
2826
|
+
if (!a.closed) {
|
|
2827
|
+
s.classList.add("closing"), setTimeout(q, 160);
|
|
2485
2828
|
try {
|
|
2486
|
-
(
|
|
2829
|
+
(g = i == null ? void 0 : i.focus) == null || g.call(i);
|
|
2487
2830
|
} catch {
|
|
2488
2831
|
}
|
|
2489
2832
|
}
|
|
2490
2833
|
}
|
|
2491
|
-
function
|
|
2492
|
-
if (
|
|
2493
|
-
if (
|
|
2494
|
-
|
|
2834
|
+
function p(g) {
|
|
2835
|
+
if (g.key === "Escape") {
|
|
2836
|
+
if (g.stopPropagation(), a.isRecording()) {
|
|
2837
|
+
a.stopRecording({ keep: !1 });
|
|
2495
2838
|
return;
|
|
2496
2839
|
}
|
|
2497
|
-
|
|
2840
|
+
a.sending || w();
|
|
2498
2841
|
return;
|
|
2499
2842
|
}
|
|
2500
|
-
if (
|
|
2501
|
-
const
|
|
2843
|
+
if (g.key !== "Tab" || a.isRecording()) return;
|
|
2844
|
+
const z = [...s.querySelectorAll(
|
|
2502
2845
|
"button:not(:disabled), input:not([hidden]), textarea, select, [href]"
|
|
2503
|
-
)].filter((
|
|
2504
|
-
if (!
|
|
2505
|
-
const
|
|
2506
|
-
|
|
2507
|
-
}
|
|
2508
|
-
document.addEventListener("keydown",
|
|
2509
|
-
|
|
2510
|
-
}),
|
|
2511
|
-
const
|
|
2512
|
-
if (!
|
|
2513
|
-
const
|
|
2514
|
-
|
|
2846
|
+
)].filter((Q) => Q.offsetParent !== null || Q === document.activeElement);
|
|
2847
|
+
if (!z.length) return;
|
|
2848
|
+
const M = z[0], A = z[z.length - 1], O = s.getRootNode().activeElement;
|
|
2849
|
+
g.shiftKey && O === M ? (g.preventDefault(), A.focus()) : !g.shiftKey && O === A && (g.preventDefault(), M.focus());
|
|
2850
|
+
}
|
|
2851
|
+
document.addEventListener("keydown", p, !0), s.addEventListener("click", (g) => {
|
|
2852
|
+
g.target === s && !a.sending && w();
|
|
2853
|
+
}), y('[data-act="close"]').addEventListener("click", w), s.addEventListener("click", (g) => {
|
|
2854
|
+
const z = g.target.closest('[data-act="theme"]');
|
|
2855
|
+
if (!z || !m) return;
|
|
2856
|
+
const M = m.cycle();
|
|
2857
|
+
z.title = `Theme: ${M.label}`, z.setAttribute("aria-label", `Theme: ${M.label}. Change theme`);
|
|
2515
2858
|
});
|
|
2516
|
-
function
|
|
2517
|
-
|
|
2859
|
+
function L(g, z = "err") {
|
|
2860
|
+
x.innerHTML = g ? `<div class="msg ${z}">${z === "err" ? P : ""}<span>${v(g)}</span></div>` : "";
|
|
2518
2861
|
}
|
|
2519
|
-
return e.appendChild(
|
|
2862
|
+
return e.appendChild(s), a.refreshSendState(), k === "feedback" ? a.focusFeedback() : a.titleInput.focus(), { destroy: q, close: w, setMode: n };
|
|
2520
2863
|
}
|
|
2521
|
-
function
|
|
2864
|
+
function jt(e) {
|
|
2522
2865
|
if (e.querySelector("style[data-panel]")) return;
|
|
2523
2866
|
const t = document.createElement("style");
|
|
2524
|
-
t.setAttribute("data-panel", ""), t.textContent =
|
|
2525
|
-
const
|
|
2526
|
-
|
|
2867
|
+
t.setAttribute("data-panel", ""), t.textContent = it;
|
|
2868
|
+
const o = e.querySelector("style");
|
|
2869
|
+
o ? o.after(t) : e.prepend(t);
|
|
2527
2870
|
}
|
|
2528
2871
|
export {
|
|
2529
|
-
|
|
2872
|
+
Ot as openPanel
|
|
2530
2873
|
};
|
|
2531
2874
|
//# sourceMappingURL=bugcatch-panel.es.js.map
|