@sphoro/bugcatch-web-sdk 0.19.0 → 0.20.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 +16 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-core.es.js +1 -1
- package/dist/bugcatch-panel.es.js +1057 -916
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +192 -151
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +178 -137
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +2 -2
- package/package.json +1 -1
- package/src/index.d.ts +9 -0
- package/src/panel/call.js +3 -2
- package/src/panel/compose.js +7 -3
- package/src/panel/index.js +9 -0
- 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 +28 -0
- package/src/panel/thread.js +3 -72
|
@@ -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 Le, m as Qe, a as Te, c as ce, b as qe, d as Ee, R as be, h as F, n as ze, e as Me, f as Ce, g as te, i as G, j as P, r as He, v as Ae, k as Re, S as Ie, U as De, l as Ve, o as je, p as Oe } from "./bugcatch-core.es.js";
|
|
2
|
+
const Ne = '<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>', Be = '<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>', pe = '<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>', Ye = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', We = '<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>', re = '<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>', Pe = '<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>', Fe = '<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>', Ke = '<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>', Ue = '<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>', Ze = `
|
|
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 } }
|
|
@@ -822,6 +822,34 @@ button.quiet:hover { color: var(--bc-fg); text-decoration-color: color-mix(in sr
|
|
|
822
822
|
.history .sub .rated svg { width: 11px; height: 11px; color: #f0a81c; }
|
|
823
823
|
.history .sub .rate-ask { color: var(--bc-fg); font-weight: 600; }
|
|
824
824
|
|
|
825
|
+
/* ---------- a settled report waiting for its rating ----------
|
|
826
|
+
Above the form on the first screen: the same stars as under a report's
|
|
827
|
+
conversation, with the report they are about named on top. */
|
|
828
|
+
.rate-due { margin: 0 0 14px; }
|
|
829
|
+
.rate-due:focus { outline: none; }
|
|
830
|
+
.rate-due:focus-visible { box-shadow: var(--bc-ring); }
|
|
831
|
+
.rate-due .rd-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
|
|
832
|
+
.rate-due .rd-eyebrow {
|
|
833
|
+
font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--bc-faint);
|
|
834
|
+
}
|
|
835
|
+
.rate-due.is-required .rd-eyebrow { color: var(--bc-fg); }
|
|
836
|
+
.rate-due .rd-later { font-size: var(--bc-fs-xs); color: var(--bc-muted); }
|
|
837
|
+
.rate-due .rd-report {
|
|
838
|
+
display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 9px; align-items: center;
|
|
839
|
+
margin: 0 0 10px; padding: 0 0 10px; border-bottom: 1px solid var(--bc-border);
|
|
840
|
+
}
|
|
841
|
+
.rate-due .rd-ico {
|
|
842
|
+
grid-row: span 2; display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 999px;
|
|
843
|
+
background: color-mix(in srgb, var(--bc-ok) 14%, transparent); color: var(--bc-ok);
|
|
844
|
+
}
|
|
845
|
+
.rate-due .rd-ico svg { width: 13px; height: 13px; }
|
|
846
|
+
.rate-due .rd-ttl { font-weight: 620; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
847
|
+
.rate-due .rd-sub { font-size: var(--bc-fs-xs); color: var(--bc-muted); }
|
|
848
|
+
|
|
849
|
+
/* What a required rating is holding: still in sight, plainly not yet. */
|
|
850
|
+
.held { opacity: .42; transition: opacity 200ms ease; }
|
|
851
|
+
@media (prefers-reduced-motion: reduce) { .held { transition: none; } }
|
|
852
|
+
|
|
825
853
|
/* A call in progress, in place of the form.
|
|
826
854
|
---------------------------------------------------------------------------
|
|
827
855
|
Deliberately not styled as a chat. Nothing arrives here to read — the
|
|
@@ -1005,31 +1033,31 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1005
1033
|
.tool:hover:not(:disabled) { transform: none; }
|
|
1006
1034
|
}
|
|
1007
1035
|
`;
|
|
1008
|
-
function le({ title: e, sub: t, id:
|
|
1036
|
+
function le({ title: e, sub: t, id: r = "", back: d = !1, theme: u = "" }) {
|
|
1009
1037
|
return `
|
|
1010
1038
|
<div class="head">
|
|
1011
|
-
${
|
|
1039
|
+
${d ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${We}</button>` : ""}
|
|
1012
1040
|
<span class="orb mark" aria-hidden="true"></span>
|
|
1013
1041
|
<div class="titles">
|
|
1014
|
-
<h2${
|
|
1042
|
+
<h2${r ? ` id="${r}"` : ""}>${v(e)}</h2>
|
|
1015
1043
|
<p>${v(t)}</p>
|
|
1016
1044
|
</div>
|
|
1017
|
-
${
|
|
1018
|
-
aria-label="Theme: ${v(
|
|
1045
|
+
${u ? `<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${v(u)}"
|
|
1046
|
+
aria-label="Theme: ${v(u)}. Change theme"><span class="m-light">${Le}</span><span class="m-dark">${Qe}</span><span class="m-auto">${Te}</span></button>` : ""}
|
|
1019
1047
|
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${ce}</button>
|
|
1020
1048
|
</div>`;
|
|
1021
1049
|
}
|
|
1022
|
-
function
|
|
1050
|
+
function oe(e, t) {
|
|
1023
1051
|
return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${v(e)}</div>`;
|
|
1024
1052
|
}
|
|
1025
|
-
function
|
|
1053
|
+
function _e(e) {
|
|
1026
1054
|
return Array.from({ length: e }, () => `
|
|
1027
1055
|
<div class="row" aria-hidden="true">
|
|
1028
1056
|
<span class="row-ico"></span>
|
|
1029
1057
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
1030
1058
|
</div>`).join("") + '<span class="sr-only">Loading…</span>';
|
|
1031
1059
|
}
|
|
1032
|
-
function
|
|
1060
|
+
function Ge() {
|
|
1033
1061
|
return `
|
|
1034
1062
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
1035
1063
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
@@ -1038,7 +1066,7 @@ function Ue() {
|
|
|
1038
1066
|
</div>
|
|
1039
1067
|
<span class="sr-only">Loading…</span>`;
|
|
1040
1068
|
}
|
|
1041
|
-
function
|
|
1069
|
+
function Je(e) {
|
|
1042
1070
|
const t = String(e).trim().split(/\s+/).filter(Boolean);
|
|
1043
1071
|
return t.length ? (t[0][0] + (t.length > 1 ? t[t.length - 1][0] : "")).toUpperCase() : "?";
|
|
1044
1072
|
}
|
|
@@ -1046,19 +1074,19 @@ function Z(e) {
|
|
|
1046
1074
|
const t = new Date(e);
|
|
1047
1075
|
return Number.isFinite(t.getTime()) ? `${t.getFullYear()}-${t.getMonth()}-${t.getDate()}` : null;
|
|
1048
1076
|
}
|
|
1049
|
-
function
|
|
1050
|
-
const t = new Date(e),
|
|
1051
|
-
if (Z(t) === Z(
|
|
1052
|
-
if (Z(t) === Z(
|
|
1077
|
+
function Xe(e) {
|
|
1078
|
+
const t = new Date(e), r = /* @__PURE__ */ new Date(), d = new Date(r.getFullYear(), r.getMonth(), r.getDate() - 1);
|
|
1079
|
+
if (Z(t) === Z(r)) return "Today";
|
|
1080
|
+
if (Z(t) === Z(d)) return "Yesterday";
|
|
1053
1081
|
try {
|
|
1054
1082
|
return t.toLocaleDateString(void 0, {
|
|
1055
1083
|
weekday: "short",
|
|
1056
1084
|
day: "numeric",
|
|
1057
1085
|
month: "short",
|
|
1058
|
-
...t.getFullYear() !==
|
|
1086
|
+
...t.getFullYear() !== r.getFullYear() ? { year: "numeric" } : {}
|
|
1059
1087
|
});
|
|
1060
1088
|
} catch {
|
|
1061
|
-
return
|
|
1089
|
+
return J(e);
|
|
1062
1090
|
}
|
|
1063
1091
|
}
|
|
1064
1092
|
function ve(e) {
|
|
@@ -1070,12 +1098,12 @@ function ve(e) {
|
|
|
1070
1098
|
return "";
|
|
1071
1099
|
}
|
|
1072
1100
|
}
|
|
1073
|
-
function
|
|
1101
|
+
function ue(e) {
|
|
1074
1102
|
return e.scrollHeight - e.scrollTop - e.clientHeight < 40;
|
|
1075
1103
|
}
|
|
1076
1104
|
function _(e, { smooth: t = !1 } = {}) {
|
|
1077
|
-
const
|
|
1078
|
-
t && !
|
|
1105
|
+
const r = typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1106
|
+
t && !r && e.scrollTo ? e.scrollTo({ top: e.scrollHeight, behavior: "smooth" }) : e.scrollTop = e.scrollHeight;
|
|
1079
1107
|
}
|
|
1080
1108
|
function ie(e) {
|
|
1081
1109
|
return {
|
|
@@ -1085,43 +1113,43 @@ function ie(e) {
|
|
|
1085
1113
|
CLOSED: "Closed"
|
|
1086
1114
|
}[e] || String(e || "").toLowerCase();
|
|
1087
1115
|
}
|
|
1088
|
-
function
|
|
1116
|
+
function J(e) {
|
|
1089
1117
|
const t = new Date(e).getTime();
|
|
1090
1118
|
if (!Number.isFinite(t)) return "";
|
|
1091
|
-
const
|
|
1092
|
-
if (
|
|
1093
|
-
if (
|
|
1094
|
-
if (
|
|
1095
|
-
const
|
|
1096
|
-
return
|
|
1119
|
+
const r = Math.floor((Date.now() - t) / 864e5);
|
|
1120
|
+
if (r <= 0) return "today";
|
|
1121
|
+
if (r === 1) return "yesterday";
|
|
1122
|
+
if (r < 30) return `${r} days ago`;
|
|
1123
|
+
const d = Math.floor(r / 30);
|
|
1124
|
+
return d === 1 ? "a month ago" : `${d} months ago`;
|
|
1097
1125
|
}
|
|
1098
1126
|
function v(e) {
|
|
1099
1127
|
return String(e).replace(/[&<>"']/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[t]);
|
|
1100
1128
|
}
|
|
1101
|
-
const
|
|
1102
|
-
let
|
|
1103
|
-
function
|
|
1104
|
-
return
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1129
|
+
const et = 7 * 24 * 60 * 60 * 1e3;
|
|
1130
|
+
let ee;
|
|
1131
|
+
function tt() {
|
|
1132
|
+
return ee || (ee = new Promise((e, t) => {
|
|
1133
|
+
const r = indexedDB.open("bugcatch-drafts", 1);
|
|
1134
|
+
r.onupgradeneeded = () => r.result.createObjectStore("drafts"), r.onsuccess = () => e(r.result), r.onerror = () => t(r.error), r.onblocked = () => t(new Error("Draft storage is blocked."));
|
|
1107
1135
|
}).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
|
-
|
|
1136
|
+
throw ee = null, e;
|
|
1137
|
+
})), ee;
|
|
1138
|
+
}
|
|
1139
|
+
function at(e, t) {
|
|
1140
|
+
var r, d;
|
|
1141
|
+
return JSON.stringify([e.apiBase, e.projectId, t || ((r = e.user) == null ? void 0 : r.email) || ((d = e.user) == null ? void 0 : d.id) || "anonymous"]);
|
|
1142
|
+
}
|
|
1143
|
+
async function ae(e, t) {
|
|
1144
|
+
const r = await tt();
|
|
1145
|
+
return new Promise((d, u) => {
|
|
1146
|
+
const S = r.transaction("drafts", t === void 0 ? "readonly" : "readwrite"), b = S.objectStore("drafts"), h = t === void 0 ? b.get(e) : t === null ? b.delete(e) : b.put({ ...t, savedAt: Date.now() }, e);
|
|
1147
|
+
S.oncomplete = () => d(h.result), S.onerror = () => u(S.error), S.onabort = () => u(S.error || new Error("Draft was not saved."));
|
|
1120
1148
|
});
|
|
1121
1149
|
}
|
|
1122
|
-
async function
|
|
1123
|
-
const t = await
|
|
1124
|
-
return t && Date.now() - t.savedAt >
|
|
1150
|
+
async function rt(e) {
|
|
1151
|
+
const t = await ae(e);
|
|
1152
|
+
return t && Date.now() - t.savedAt > et ? (await ae(e, null), null) : t || null;
|
|
1125
1153
|
}
|
|
1126
1154
|
const xe = [
|
|
1127
1155
|
{ value: "LOW", label: "Low" },
|
|
@@ -1129,8 +1157,8 @@ const xe = [
|
|
|
1129
1157
|
{ value: "HIGH", label: "High" },
|
|
1130
1158
|
{ value: "CRITICAL", label: "Critical" }
|
|
1131
1159
|
], ye = "MEDIUM";
|
|
1132
|
-
function
|
|
1133
|
-
const t = e.attachments !== !1,
|
|
1160
|
+
function nt(e) {
|
|
1161
|
+
const t = e.attachments !== !1, r = t && qe(), d = t && Ee();
|
|
1134
1162
|
return `
|
|
1135
1163
|
<div class="compose">
|
|
1136
1164
|
<div class="field">
|
|
@@ -1151,8 +1179,8 @@ function tt(e) {
|
|
|
1151
1179
|
<div class="field">
|
|
1152
1180
|
<label id="bc-prio-l">How much is it getting in your way?</label>
|
|
1153
1181
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
1154
|
-
${xe.map((
|
|
1155
|
-
<button type="button" data-prio="${
|
|
1182
|
+
${xe.map((u) => `
|
|
1183
|
+
<button type="button" data-prio="${u.value}" aria-pressed="${u.value === ye}">${u.label}</button>
|
|
1156
1184
|
`).join("")}
|
|
1157
1185
|
</div>
|
|
1158
1186
|
</div>
|
|
@@ -1163,8 +1191,8 @@ function tt(e) {
|
|
|
1163
1191
|
<span class="count" aria-live="polite"></span>
|
|
1164
1192
|
</div>
|
|
1165
1193
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1166
|
-
${
|
|
1167
|
-
${
|
|
1194
|
+
${r ? `<button class="tool" type="button" data-act="shot">${Ne}Screenshot</button>` : ""}
|
|
1195
|
+
${d ? `<button class="tool" type="button" data-act="rec">${Be}Record screen</button>` : ""}
|
|
1168
1196
|
<button class="tool" type="button" data-act="file">${fe}Upload file</button>
|
|
1169
1197
|
</div>
|
|
1170
1198
|
<div class="thumbs"></div>
|
|
@@ -1172,552 +1200,552 @@ function tt(e) {
|
|
|
1172
1200
|
</div>` : ""}
|
|
1173
1201
|
</div>`;
|
|
1174
1202
|
}
|
|
1175
|
-
function
|
|
1176
|
-
var
|
|
1203
|
+
function ot(e) {
|
|
1204
|
+
var ne, K, U, z;
|
|
1177
1205
|
const {
|
|
1178
1206
|
client: t,
|
|
1179
|
-
cfg:
|
|
1180
|
-
root:
|
|
1181
|
-
host:
|
|
1182
|
-
dock:
|
|
1183
|
-
scrim:
|
|
1184
|
-
$:
|
|
1185
|
-
say:
|
|
1186
|
-
titleInput:
|
|
1187
|
-
descInput:
|
|
1207
|
+
cfg: r,
|
|
1208
|
+
root: d,
|
|
1209
|
+
host: u,
|
|
1210
|
+
dock: S,
|
|
1211
|
+
scrim: b,
|
|
1212
|
+
$: h,
|
|
1213
|
+
say: f,
|
|
1214
|
+
titleInput: s,
|
|
1215
|
+
descInput: c,
|
|
1188
1216
|
compose: L,
|
|
1189
|
-
sendBtn:
|
|
1190
|
-
note:
|
|
1191
|
-
} = e,
|
|
1192
|
-
let n = ye,
|
|
1217
|
+
sendBtn: g,
|
|
1218
|
+
note: w
|
|
1219
|
+
} = e, x = h(".thumbs"), T = b.querySelector("input[type=file]"), i = [];
|
|
1220
|
+
let n = ye, o = null;
|
|
1193
1221
|
const a = document.createElement("div");
|
|
1194
1222
|
a.setAttribute("role", "status"), a.className = "note", L.prepend(a);
|
|
1195
|
-
const
|
|
1196
|
-
let
|
|
1197
|
-
function
|
|
1198
|
-
if (clearTimeout(
|
|
1199
|
-
const
|
|
1200
|
-
title:
|
|
1201
|
-
description:
|
|
1223
|
+
const k = at(r, (ne = t.signedInAs()) == null ? void 0 : ne.email);
|
|
1224
|
+
let y = r.drafts === !1, m = !1, l = Promise.resolve(), $;
|
|
1225
|
+
function q() {
|
|
1226
|
+
if (clearTimeout($), !y || m || r.drafts === !1) return l;
|
|
1227
|
+
const p = s.value || c.value || i.length ? {
|
|
1228
|
+
title: s.value,
|
|
1229
|
+
description: c.value,
|
|
1202
1230
|
priority: n,
|
|
1203
|
-
items:
|
|
1231
|
+
items: i.map(({ blob: E, mime: A, kind: R }) => ({ blob: E, mime: A, kind: R }))
|
|
1204
1232
|
} : null;
|
|
1205
|
-
return
|
|
1206
|
-
}).then(() =>
|
|
1207
|
-
a.textContent =
|
|
1233
|
+
return l = l.catch(() => {
|
|
1234
|
+
}).then(() => ae(k, p)).then(() => {
|
|
1235
|
+
a.textContent = p ? "Draft saved on this device" : "";
|
|
1208
1236
|
}).catch(() => {
|
|
1209
1237
|
a.textContent = "Draft could not be saved. Keep this tab open.";
|
|
1210
|
-
}),
|
|
1238
|
+
}), l;
|
|
1211
1239
|
}
|
|
1212
|
-
function
|
|
1213
|
-
clearTimeout(
|
|
1240
|
+
function H() {
|
|
1241
|
+
clearTimeout($), $ = setTimeout(q, 250);
|
|
1214
1242
|
}
|
|
1215
|
-
L.addEventListener("input",
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1243
|
+
L.addEventListener("input", H), L.addEventListener("change", H);
|
|
1244
|
+
const O = () => {
|
|
1245
|
+
q();
|
|
1218
1246
|
};
|
|
1219
|
-
window.addEventListener("pagehide",
|
|
1220
|
-
function
|
|
1221
|
-
|
|
1247
|
+
window.addEventListener("pagehide", O);
|
|
1248
|
+
function N() {
|
|
1249
|
+
i.filter((p) => p.status === "failed").forEach(V);
|
|
1222
1250
|
}
|
|
1223
|
-
window.addEventListener("online",
|
|
1224
|
-
e.closed || !
|
|
1225
|
-
|
|
1226
|
-
for (const
|
|
1227
|
-
|
|
1251
|
+
window.addEventListener("online", N), r.drafts !== !1 && (L.inert = !0, rt(k).then((p) => {
|
|
1252
|
+
e.closed || !p || (a.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>', a.querySelector("[data-resume]").onclick = () => {
|
|
1253
|
+
s.value = p.title || "", c.value = p.description || "", n = xe.some((E) => E.value === p.priority) ? p.priority : "MEDIUM", b.querySelectorAll("[data-prio]").forEach((E) => E.setAttribute("aria-pressed", String(E.dataset.prio === n)));
|
|
1254
|
+
for (const E of (p.items || []).slice(0, r.maxAttachments ?? 5)) Y(E);
|
|
1255
|
+
y = !0, q();
|
|
1228
1256
|
}, a.querySelector("[data-discard]").onclick = () => {
|
|
1229
|
-
|
|
1257
|
+
y = !0, q();
|
|
1230
1258
|
});
|
|
1231
1259
|
}).catch(() => {
|
|
1232
1260
|
a.textContent = "Draft storage is unavailable. Keep this tab open.";
|
|
1233
1261
|
}).finally(() => {
|
|
1234
|
-
L.inert =
|
|
1262
|
+
L.inert = e.mustRate(), a.querySelector("[data-resume]") || (y = !0);
|
|
1235
1263
|
})), e.onDestroy(() => {
|
|
1236
|
-
var
|
|
1237
|
-
|
|
1238
|
-
}),
|
|
1239
|
-
|
|
1240
|
-
n =
|
|
1241
|
-
|
|
1264
|
+
var p;
|
|
1265
|
+
q(), clearTimeout($), window.removeEventListener("pagehide", O), window.removeEventListener("online", N), o == null || o.cancel(), i.forEach((E) => E.previewUrl && URL.revokeObjectURL(E.previewUrl)), (p = d.querySelector(".recbar")) == null || p.remove();
|
|
1266
|
+
}), b.querySelectorAll("[data-prio]").forEach((p) => {
|
|
1267
|
+
p.addEventListener("click", () => {
|
|
1268
|
+
n = p.dataset.prio, H(), b.querySelectorAll("[data-prio]").forEach((E) => {
|
|
1269
|
+
E.setAttribute("aria-pressed", String(E === p));
|
|
1242
1270
|
});
|
|
1243
1271
|
});
|
|
1244
1272
|
});
|
|
1245
|
-
const
|
|
1246
|
-
function
|
|
1247
|
-
|
|
1273
|
+
const B = h("#bc-title-err");
|
|
1274
|
+
function Q(p) {
|
|
1275
|
+
B.hidden = !p, B.innerHTML = p ? `${G}<span>${v(p)}</span>` : "", s.classList.toggle("invalid", !!p), s.setAttribute("aria-invalid", String(!!p));
|
|
1248
1276
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1277
|
+
s.addEventListener("input", () => {
|
|
1278
|
+
s.value.trim() && Q("");
|
|
1251
1279
|
});
|
|
1252
|
-
function
|
|
1253
|
-
const
|
|
1254
|
-
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
|
|
1280
|
+
function C() {
|
|
1281
|
+
const p = i.some((I) => I.status === "uploading"), E = e.mustRate();
|
|
1282
|
+
g.disabled = e.sending || p || E || i.some((I) => I.status === "failed"), w.textContent = E ? "Rate your last report to send a new one." : p ? "Waiting for the upload to finish…" : i.some((I) => I.status === "failed") ? "Retry or remove failed attachments before sending." : "";
|
|
1283
|
+
const A = r.maxAttachments ?? 5;
|
|
1284
|
+
b.querySelectorAll(".tool").forEach((I) => {
|
|
1285
|
+
I.disabled = e.sending || i.length >= A;
|
|
1258
1286
|
});
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1262
|
-
e.refreshSendState =
|
|
1263
|
-
function
|
|
1264
|
-
var
|
|
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
|
-
|
|
1287
|
+
const R = h(".field-head .count");
|
|
1288
|
+
R && (R.textContent = i.length ? `${i.length} of ${A}` : "");
|
|
1289
|
+
}
|
|
1290
|
+
e.refreshSendState = C;
|
|
1291
|
+
function M(p) {
|
|
1292
|
+
var W;
|
|
1293
|
+
const E = p.el, A = p.kind === "VIDEO" ? "Video" : "Shot", R = p.kind === "VIDEO" ? `<video src="${p.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${p.previewUrl}" alt="" />`;
|
|
1294
|
+
let I = "";
|
|
1295
|
+
p.status === "uploading" ? I = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(p.progress * 100)}%"></i></div></div>` : p.status === "failed" && (I = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Pe}</button>Failed</div>`), E.innerHTML = `
|
|
1296
|
+
${R}
|
|
1297
|
+
<span class="kind">${A} · ${F(p.size)}</span>
|
|
1298
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${A.toLowerCase()}">${ce}</button>
|
|
1299
|
+
${I}`, E.querySelector('[data-act="drop"]').addEventListener("click", () => D(p)), (W = E.querySelector('[data-act="retry"]')) == null || W.addEventListener("click", () => V(p));
|
|
1300
|
+
}
|
|
1301
|
+
function D(p) {
|
|
1302
|
+
const E = i.indexOf(p);
|
|
1303
|
+
E >= 0 && i.splice(E, 1), p.previewUrl && URL.revokeObjectURL(p.previewUrl), p.el.remove(), q(), C();
|
|
1304
|
+
}
|
|
1305
|
+
async function V(p) {
|
|
1306
|
+
p.status = "uploading", p.progress = 0, M(p), C();
|
|
1279
1307
|
try {
|
|
1280
|
-
const { storageKey:
|
|
1281
|
-
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1308
|
+
const { storageKey: E, mime: A } = await t.uploadAttachment(p.blob, p.mime, (R) => {
|
|
1309
|
+
p.progress = R;
|
|
1310
|
+
const I = p.el.querySelector(".bar i");
|
|
1311
|
+
I && (I.style.width = `${Math.round(R * 100)}%`);
|
|
1284
1312
|
});
|
|
1285
|
-
|
|
1286
|
-
} catch (
|
|
1287
|
-
|
|
1313
|
+
p.storageKey = E, p.mime = A, p.status = "ready";
|
|
1314
|
+
} catch (E) {
|
|
1315
|
+
p.status = "failed", f(E.message.replace("[BugCatch] ", ""));
|
|
1288
1316
|
}
|
|
1289
|
-
|
|
1317
|
+
M(p), C();
|
|
1290
1318
|
}
|
|
1291
|
-
function
|
|
1292
|
-
const
|
|
1293
|
-
if (
|
|
1294
|
-
|
|
1319
|
+
function Y({ blob: p, mime: E, kind: A }) {
|
|
1320
|
+
const R = r.maxAttachmentBytes ?? 26214400;
|
|
1321
|
+
if (p.size > R) {
|
|
1322
|
+
f(`That file is ${F(p.size)} — the limit is ${F(R)}.`);
|
|
1295
1323
|
return;
|
|
1296
1324
|
}
|
|
1297
|
-
const
|
|
1298
|
-
if (!
|
|
1299
|
-
|
|
1325
|
+
const I = ze(E || p.type, be);
|
|
1326
|
+
if (!I) {
|
|
1327
|
+
f("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
|
|
1300
1328
|
return;
|
|
1301
1329
|
}
|
|
1302
|
-
const
|
|
1303
|
-
blob:
|
|
1304
|
-
kind:
|
|
1305
|
-
mime:
|
|
1306
|
-
size:
|
|
1307
|
-
previewUrl: URL.createObjectURL(
|
|
1330
|
+
const W = {
|
|
1331
|
+
blob: p,
|
|
1332
|
+
kind: A,
|
|
1333
|
+
mime: I,
|
|
1334
|
+
size: p.size,
|
|
1335
|
+
previewUrl: URL.createObjectURL(p),
|
|
1308
1336
|
status: "uploading",
|
|
1309
1337
|
progress: 0,
|
|
1310
1338
|
storageKey: null,
|
|
1311
1339
|
el: document.createElement("div")
|
|
1312
1340
|
};
|
|
1313
|
-
|
|
1341
|
+
W.el.className = "thumb", i.push(W), x.appendChild(W.el), f(""), q(), V(W);
|
|
1314
1342
|
}
|
|
1315
|
-
async function X(
|
|
1316
|
-
|
|
1343
|
+
async function X(p) {
|
|
1344
|
+
u.style.opacity = "0", u.style.pointerEvents = "none", await new Promise((E) => requestAnimationFrame(() => requestAnimationFrame(E)));
|
|
1317
1345
|
try {
|
|
1318
|
-
return await
|
|
1346
|
+
return await p();
|
|
1319
1347
|
} finally {
|
|
1320
|
-
|
|
1348
|
+
u.style.opacity = "", u.style.pointerEvents = "";
|
|
1321
1349
|
}
|
|
1322
1350
|
}
|
|
1323
|
-
(K =
|
|
1351
|
+
(K = b.querySelector('[data-act="shot"]')) == null || K.addEventListener("click", async () => {
|
|
1324
1352
|
try {
|
|
1325
|
-
const
|
|
1326
|
-
|
|
1327
|
-
} catch (
|
|
1328
|
-
(
|
|
1353
|
+
const p = await X(Me);
|
|
1354
|
+
Y(p);
|
|
1355
|
+
} catch (p) {
|
|
1356
|
+
(p == null ? void 0 : p.name) !== "NotAllowedError" && f(`Screenshot failed: ${p.message}`);
|
|
1329
1357
|
}
|
|
1330
|
-
}), (U =
|
|
1331
|
-
const
|
|
1332
|
-
[...
|
|
1333
|
-
|
|
1334
|
-
blob:
|
|
1335
|
-
mime:
|
|
1336
|
-
kind:
|
|
1358
|
+
}), (U = b.querySelector('[data-act="file"]')) == null || U.addEventListener("click", () => T.click()), T == null || T.addEventListener("change", () => {
|
|
1359
|
+
const p = (r.maxAttachments ?? 5) - i.length;
|
|
1360
|
+
[...T.files].slice(0, Math.max(p, 0)).forEach((E) => {
|
|
1361
|
+
Y({
|
|
1362
|
+
blob: E,
|
|
1363
|
+
mime: E.type,
|
|
1364
|
+
kind: E.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
|
|
1337
1365
|
});
|
|
1338
|
-
}),
|
|
1339
|
-
}), (
|
|
1340
|
-
const
|
|
1341
|
-
let
|
|
1366
|
+
}), T.value = "";
|
|
1367
|
+
}), (z = b.querySelector('[data-act="rec"]')) == null || z.addEventListener("click", async () => {
|
|
1368
|
+
const p = r.maxRecordingMs ?? 12e4;
|
|
1369
|
+
let E;
|
|
1342
1370
|
try {
|
|
1343
|
-
|
|
1344
|
-
maxMs:
|
|
1345
|
-
onTick: (
|
|
1346
|
-
|
|
1371
|
+
o = await Ce({
|
|
1372
|
+
maxMs: p,
|
|
1373
|
+
onTick: (A) => {
|
|
1374
|
+
E && (E.querySelector(".time").textContent = te(A));
|
|
1347
1375
|
},
|
|
1348
1376
|
onAutoStop: () => {
|
|
1349
|
-
|
|
1377
|
+
o && j({ keep: !0 });
|
|
1350
1378
|
}
|
|
1351
1379
|
});
|
|
1352
|
-
} catch (
|
|
1353
|
-
(
|
|
1380
|
+
} catch (A) {
|
|
1381
|
+
(A == null ? void 0 : A.name) !== "NotAllowedError" && f(`Recording failed: ${A.message}`);
|
|
1354
1382
|
return;
|
|
1355
1383
|
}
|
|
1356
|
-
|
|
1384
|
+
b.style.display = "none", S.hidden = !0, E = document.createElement("div"), E.className = "recbar", E.innerHTML = `
|
|
1357
1385
|
<span class="dot"></span>
|
|
1358
1386
|
<span class="time">0:00</span>
|
|
1359
|
-
<span class="hint">Recording — up to ${
|
|
1387
|
+
<span class="hint">Recording — up to ${te(Math.round(p / 1e3))}</span>
|
|
1360
1388
|
<button class="stop" type="button">Stop</button>
|
|
1361
|
-
<button class="ghost" type="button">Discard</button>`,
|
|
1389
|
+
<button class="ghost" type="button">Discard</button>`, E.querySelector(".stop").addEventListener("click", () => j({ keep: !0 })), E.querySelector(".ghost").addEventListener("click", () => j({ keep: !1 })), d.appendChild(E), E.querySelector(".stop").focus();
|
|
1362
1390
|
});
|
|
1363
|
-
async function
|
|
1364
|
-
var
|
|
1365
|
-
const
|
|
1366
|
-
if (
|
|
1367
|
-
if (
|
|
1368
|
-
|
|
1391
|
+
async function j({ keep: p }) {
|
|
1392
|
+
var A;
|
|
1393
|
+
const E = o;
|
|
1394
|
+
if (E) {
|
|
1395
|
+
if (o = null, (A = d.querySelector(".recbar")) == null || A.remove(), b.style.display = "", S.hidden = !1, !p) {
|
|
1396
|
+
E.cancel(), s.focus();
|
|
1369
1397
|
return;
|
|
1370
1398
|
}
|
|
1371
1399
|
try {
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
} catch (
|
|
1375
|
-
|
|
1400
|
+
const R = await E.stop();
|
|
1401
|
+
R.blob.size ? Y(R) : f("That recording came back empty — nothing was captured.");
|
|
1402
|
+
} catch (R) {
|
|
1403
|
+
f(`Recording failed: ${R.message}`);
|
|
1376
1404
|
}
|
|
1377
|
-
|
|
1405
|
+
s.focus();
|
|
1378
1406
|
}
|
|
1379
1407
|
}
|
|
1380
|
-
e.isRecording = () => !!
|
|
1381
|
-
var
|
|
1382
|
-
const
|
|
1383
|
-
if (!
|
|
1384
|
-
|
|
1408
|
+
e.isRecording = () => !!o, e.stopRecording = j, g.addEventListener("click", async () => {
|
|
1409
|
+
var A;
|
|
1410
|
+
const p = s.value;
|
|
1411
|
+
if (!p.trim()) {
|
|
1412
|
+
Q("Add a few words about what went wrong — a short sentence is plenty."), s.focus();
|
|
1385
1413
|
return;
|
|
1386
1414
|
}
|
|
1387
1415
|
if (e.holdForReference()) return;
|
|
1388
|
-
e.sending = !0,
|
|
1389
|
-
const
|
|
1390
|
-
|
|
1416
|
+
e.sending = !0, f(""), C();
|
|
1417
|
+
const E = g.innerHTML;
|
|
1418
|
+
g.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
|
|
1391
1419
|
try {
|
|
1392
|
-
const
|
|
1393
|
-
title:
|
|
1394
|
-
description:
|
|
1420
|
+
const R = await t.report({
|
|
1421
|
+
title: p,
|
|
1422
|
+
description: c.value,
|
|
1395
1423
|
priority: n,
|
|
1396
1424
|
references: e.answeredReference(),
|
|
1397
|
-
issue: ((
|
|
1398
|
-
attachments:
|
|
1425
|
+
issue: ((A = e.pickedIssue()) == null ? void 0 : A.key) || null,
|
|
1426
|
+
attachments: i.filter((I) => I.status === "ready").map((I) => ({ type: I.kind, storageKey: I.storageKey, mime: I.mime }))
|
|
1399
1427
|
});
|
|
1400
|
-
if (
|
|
1401
|
-
e.sending = !1,
|
|
1428
|
+
if (R != null && R.cancelled) {
|
|
1429
|
+
e.sending = !1, g.innerHTML = E, C();
|
|
1402
1430
|
return;
|
|
1403
1431
|
}
|
|
1404
|
-
|
|
1405
|
-
}), e.succeed(
|
|
1406
|
-
} catch (
|
|
1407
|
-
e.sending = !1,
|
|
1432
|
+
m = !0, clearTimeout($), await l, r.drafts !== !1 && await ae(k, null).catch(() => {
|
|
1433
|
+
}), e.succeed(R);
|
|
1434
|
+
} catch (R) {
|
|
1435
|
+
e.sending = !1, g.innerHTML = E, f(R.message.replace("[BugCatch] ", "")), C(), e.recheckSignIn();
|
|
1408
1436
|
}
|
|
1409
1437
|
});
|
|
1410
1438
|
}
|
|
1411
|
-
function
|
|
1439
|
+
function it(e) {
|
|
1412
1440
|
const {
|
|
1413
1441
|
client: t,
|
|
1414
|
-
say:
|
|
1415
|
-
titleInput:
|
|
1416
|
-
descInput:
|
|
1417
|
-
sendBtn:
|
|
1418
|
-
refsBox:
|
|
1442
|
+
say: r,
|
|
1443
|
+
titleInput: d,
|
|
1444
|
+
descInput: u,
|
|
1445
|
+
sendBtn: S,
|
|
1446
|
+
refsBox: b
|
|
1419
1447
|
} = e;
|
|
1420
|
-
let
|
|
1421
|
-
t.referenceFields().then((
|
|
1422
|
-
|
|
1448
|
+
let h = { policy: "off", fields: [] }, f = !1, s = null, c = "", L = "", g = [], w = "ask", x = !1, T = !1;
|
|
1449
|
+
t.referenceFields().then((Q) => {
|
|
1450
|
+
h = Q, y();
|
|
1423
1451
|
}).catch(() => {
|
|
1424
1452
|
});
|
|
1425
|
-
function
|
|
1426
|
-
return
|
|
1453
|
+
function i() {
|
|
1454
|
+
return h.policy === "off" || !h.fields.length ? { found: [], conflicts: [], loose: [] } : He(h.fields, [d.value, u.value]);
|
|
1427
1455
|
}
|
|
1428
|
-
function n(
|
|
1429
|
-
return
|
|
1456
|
+
function n(Q = i()) {
|
|
1457
|
+
return Q.found.length > 0 && Q.conflicts.length === 0;
|
|
1430
1458
|
}
|
|
1431
|
-
function
|
|
1432
|
-
return !
|
|
1459
|
+
function o() {
|
|
1460
|
+
return !s || !c.trim() ? [] : [{ key: s, value: c.trim().slice(0, 120) }];
|
|
1433
1461
|
}
|
|
1434
1462
|
const a = document.createElement("p");
|
|
1435
|
-
a.className = "ref-found", a.setAttribute("aria-live", "polite"), a.hidden = !0,
|
|
1436
|
-
let
|
|
1437
|
-
function
|
|
1438
|
-
const
|
|
1439
|
-
if (n(
|
|
1440
|
-
const
|
|
1441
|
-
a.innerHTML = `${
|
|
1463
|
+
a.className = "ref-found", a.setAttribute("aria-live", "polite"), a.hidden = !0, u.closest(".field").after(a);
|
|
1464
|
+
let k;
|
|
1465
|
+
function y() {
|
|
1466
|
+
const Q = i();
|
|
1467
|
+
if (n(Q)) {
|
|
1468
|
+
const C = Q.found.slice(0, 2).map((M) => `${v(M.label)} <b>${v(l(M.value))}</b>`).join(", ");
|
|
1469
|
+
a.innerHTML = `${P}<span>Found your ${C} — no need to add it again.</span>`, a.hidden = !1, f && !o().length && (f = !1, H());
|
|
1442
1470
|
} else
|
|
1443
1471
|
a.hidden = !0, a.innerHTML = "";
|
|
1444
1472
|
}
|
|
1445
|
-
const
|
|
1446
|
-
clearTimeout(
|
|
1473
|
+
const m = () => {
|
|
1474
|
+
clearTimeout(k), k = setTimeout(y, 250);
|
|
1447
1475
|
};
|
|
1448
|
-
|
|
1449
|
-
function
|
|
1450
|
-
return
|
|
1476
|
+
d.addEventListener("input", m), u.addEventListener("input", m);
|
|
1477
|
+
function l(Q) {
|
|
1478
|
+
return Q.length > 20 ? `${Q.slice(0, 8)}…${Q.slice(-4)}` : Q;
|
|
1451
1479
|
}
|
|
1452
|
-
function
|
|
1453
|
-
const
|
|
1454
|
-
return
|
|
1480
|
+
function $(Q) {
|
|
1481
|
+
const C = Q.trim().toLowerCase();
|
|
1482
|
+
return g.find((M) => M.value.toLowerCase() === C) || null;
|
|
1455
1483
|
}
|
|
1456
|
-
function
|
|
1457
|
-
|
|
1484
|
+
function q(Q) {
|
|
1485
|
+
c = Q.value, Q.kinds.length === 1 ? s = Q.kinds[0].key : Q.kinds.some((C) => C.key === s) || (s = null), L = "", T = !1;
|
|
1458
1486
|
}
|
|
1459
|
-
function
|
|
1487
|
+
function H() {
|
|
1460
1488
|
var K, U;
|
|
1461
|
-
if (!
|
|
1462
|
-
|
|
1489
|
+
if (!f) {
|
|
1490
|
+
b.hidden = !0, b.innerHTML = "";
|
|
1463
1491
|
return;
|
|
1464
1492
|
}
|
|
1465
|
-
const
|
|
1466
|
-
confirm:
|
|
1493
|
+
const Q = h.fields.find((z) => z.key === s) || null, C = h.policy !== "required", M = $(c), D = M && M.kinds.length > 1 ? h.fields.filter((z) => M.kinds.some((p) => p.key === z.key)) : h.fields, V = g.length > 1 && g.every((z) => z.kinds.length === 1 && z.kinds[0].key === g[0].kinds[0].key), Y = {
|
|
1494
|
+
confirm: g.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
1495
|
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 X =
|
|
1472
|
-
|
|
1496
|
+
ask: C ? ["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."]
|
|
1497
|
+
}[w];
|
|
1498
|
+
b.hidden = !1;
|
|
1499
|
+
const X = D.length > 6;
|
|
1500
|
+
b.innerHTML = `
|
|
1473
1501
|
<div class="ask-head">
|
|
1474
1502
|
<span class="avatar orb" aria-hidden="true"></span>
|
|
1475
1503
|
<div>
|
|
1476
|
-
<strong>${v(
|
|
1477
|
-
<p class="why">${v(
|
|
1504
|
+
<strong>${v(Y[0])}</strong>
|
|
1505
|
+
<p class="why">${v(Y[1])}</p>
|
|
1478
1506
|
</div>
|
|
1479
1507
|
</div>
|
|
1480
|
-
${
|
|
1508
|
+
${g.length > 1 ? `
|
|
1481
1509
|
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1482
|
-
${
|
|
1483
|
-
<button type="button" data-ref-cand="${
|
|
1484
|
-
aria-pressed="${!!
|
|
1510
|
+
${g.map((z, p) => `
|
|
1511
|
+
<button type="button" data-ref-cand="${p}" title="${v(z.value)}"
|
|
1512
|
+
aria-pressed="${!!M && M === z}">${v(l(z.value))}</button>
|
|
1485
1513
|
`).join("")}
|
|
1486
1514
|
</div>` : ""}
|
|
1487
|
-
${
|
|
1515
|
+
${D.length > 1 && !X && !V ? `
|
|
1488
1516
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1489
|
-
${
|
|
1490
|
-
<button type="button" data-ref-kind="${v(
|
|
1517
|
+
${D.map((z) => `
|
|
1518
|
+
<button type="button" data-ref-kind="${v(z.key)}" aria-pressed="${!!Q && z.key === Q.key}">${v(z.label)}</button>
|
|
1491
1519
|
`).join("")}
|
|
1492
1520
|
</div>` : ""}
|
|
1493
1521
|
<div class="row">
|
|
1494
1522
|
${X ? `
|
|
1495
1523
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1496
|
-
${
|
|
1497
|
-
${
|
|
1498
|
-
<option value="${v(
|
|
1524
|
+
${Q ? "" : '<option value="" selected disabled>What is it?</option>'}
|
|
1525
|
+
${D.map((z) => `
|
|
1526
|
+
<option value="${v(z.key)}" ${Q && z.key === Q.key ? "selected" : ""}>${v(z.label)}</option>
|
|
1499
1527
|
`).join("")}
|
|
1500
1528
|
</select>` : ""}
|
|
1501
|
-
<input class="ref-value${L ? " invalid" : ""}" type="${(
|
|
1502
|
-
inputmode="${v((
|
|
1503
|
-
value="${v(
|
|
1504
|
-
placeholder="${v(
|
|
1505
|
-
aria-label="${v(
|
|
1529
|
+
<input class="ref-value${L ? " invalid" : ""}" type="${(Q == null ? void 0 : Q.inputMode) === "email" ? "email" : "text"}"
|
|
1530
|
+
inputmode="${v((Q == null ? void 0 : Q.inputMode) === "numeric" || (Q == null ? void 0 : Q.inputMode) === "tel" ? "numeric" : "text")}"
|
|
1531
|
+
value="${v(c)}"
|
|
1532
|
+
placeholder="${v(Q ? Q.placeholder || Q.label : "Your ID")}"
|
|
1533
|
+
aria-label="${v(Q ? Q.label : "Your ID")}" ${L ? 'aria-invalid="true"' : ""} />
|
|
1506
1534
|
</div>
|
|
1507
|
-
${
|
|
1535
|
+
${Q != null && Q.hint ? `<p class="hint">${v(Q.hint)}</p>` : ""}
|
|
1508
1536
|
${L ? `<p class="field-err" role="alert">${G}<span>${v(L)}</span></p>` : ""}
|
|
1509
|
-
${
|
|
1510
|
-
|
|
1511
|
-
|
|
1537
|
+
${C ? `<button type="button" class="link" data-act="ref-skip">${w === "ask" ? "I don't have this — send without it" : "Not sure — send as it is"}</button>` : ""}`, b.querySelectorAll("[data-ref-cand]").forEach((z) => {
|
|
1538
|
+
z.addEventListener("click", () => {
|
|
1539
|
+
q(g[Number(z.dataset.refCand)]), H();
|
|
1512
1540
|
});
|
|
1513
|
-
}),
|
|
1514
|
-
|
|
1515
|
-
|
|
1541
|
+
}), b.querySelectorAll("[data-ref-kind]").forEach((z) => {
|
|
1542
|
+
z.addEventListener("click", () => {
|
|
1543
|
+
s = z.dataset.refKind, L = "", T = !1, H();
|
|
1516
1544
|
});
|
|
1517
1545
|
});
|
|
1518
|
-
const
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
}),
|
|
1522
|
-
|
|
1523
|
-
}), (K =
|
|
1524
|
-
var
|
|
1525
|
-
|
|
1526
|
-
}), (U =
|
|
1527
|
-
|
|
1528
|
-
}), ((!
|
|
1529
|
-
}
|
|
1530
|
-
function
|
|
1531
|
-
if (
|
|
1532
|
-
if (
|
|
1546
|
+
const j = b.querySelector(".ref-value");
|
|
1547
|
+
j.addEventListener("input", () => {
|
|
1548
|
+
c = j.value, L = "", T = !1;
|
|
1549
|
+
}), j.addEventListener("keydown", (z) => {
|
|
1550
|
+
z.key === "Enter" && (z.preventDefault(), S.click());
|
|
1551
|
+
}), (K = b.querySelector(".ref-kind")) == null || K.addEventListener("change", (z) => {
|
|
1552
|
+
var p;
|
|
1553
|
+
s = z.target.value, L = "", H(), (p = b.querySelector(".ref-value")) == null || p.focus();
|
|
1554
|
+
}), (U = b.querySelector('[data-act="ref-skip"]')) == null || U.addEventListener("click", () => {
|
|
1555
|
+
x = !0, f = !1, s = null, c = "", L = "", T = !1, H(), r("");
|
|
1556
|
+
}), ((!Q && c ? b.querySelector("[data-ref-kind], .ref-kind") : null) || j).focus();
|
|
1557
|
+
}
|
|
1558
|
+
function O(Q) {
|
|
1559
|
+
if (g = Q.conflicts.length ? Q.conflicts : Q.loose.slice(0, 4), w = Q.conflicts.length ? "confirm" : Q.loose.length ? "suggest" : "ask", f = !0, g.length)
|
|
1560
|
+
if (g.length === 1) q(g[0]);
|
|
1533
1561
|
else {
|
|
1534
|
-
|
|
1535
|
-
const [
|
|
1536
|
-
|
|
1562
|
+
c = "";
|
|
1563
|
+
const [C] = g;
|
|
1564
|
+
s = g.every((D) => D.kinds.length === 1 && D.kinds[0].key === C.kinds[0].key) ? C.kinds[0].key : null;
|
|
1537
1565
|
}
|
|
1538
1566
|
else
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
}
|
|
1542
|
-
function B() {
|
|
1543
|
-
if (g.policy === "off" || !g.fields.length || p().length) return !1;
|
|
1544
|
-
const h = E();
|
|
1545
|
-
return n(h) || S && g.policy !== "required" ? !1 : h;
|
|
1567
|
+
s = s || h.fields[0].key;
|
|
1568
|
+
H();
|
|
1546
1569
|
}
|
|
1547
1570
|
function N() {
|
|
1548
|
-
if (
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
if (
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1571
|
+
if (h.policy === "off" || !h.fields.length || o().length) return !1;
|
|
1572
|
+
const Q = i();
|
|
1573
|
+
return n(Q) || x && h.policy !== "required" ? !1 : Q;
|
|
1574
|
+
}
|
|
1575
|
+
function B() {
|
|
1576
|
+
if (f && c.trim() && !s)
|
|
1577
|
+
return L = "Pick what this ID is.", H(), !0;
|
|
1578
|
+
const Q = N();
|
|
1579
|
+
if (Q)
|
|
1580
|
+
return f ? H() : O(Q), r(""), !0;
|
|
1581
|
+
if (s && c.trim()) {
|
|
1582
|
+
const C = h.fields.find((M) => M.key === s);
|
|
1583
|
+
if (!T && C && !Ae(C, c))
|
|
1584
|
+
return L = `That does not look like a ${C.label.toLowerCase()}. Press Send again to use it anyway.`, T = !0, H(), !0;
|
|
1557
1585
|
}
|
|
1558
1586
|
return !1;
|
|
1559
1587
|
}
|
|
1560
|
-
e.holdForReference =
|
|
1588
|
+
e.holdForReference = B, e.answeredReference = o;
|
|
1561
1589
|
}
|
|
1562
|
-
const
|
|
1563
|
-
function
|
|
1564
|
-
const { client: t, cfg:
|
|
1565
|
-
let
|
|
1566
|
-
function
|
|
1567
|
-
const
|
|
1568
|
-
|
|
1590
|
+
const st = 3;
|
|
1591
|
+
function lt(e) {
|
|
1592
|
+
const { client: t, cfg: r, notices: d } = e;
|
|
1593
|
+
let u = [];
|
|
1594
|
+
function S() {
|
|
1595
|
+
const h = u.slice(0, st);
|
|
1596
|
+
d.replaceChildren(...h.map((f) => Re(f, { where: "panel", onDismiss: b }))), d.hidden = h.length === 0;
|
|
1569
1597
|
}
|
|
1570
|
-
function
|
|
1571
|
-
t.dismissAnnouncement(
|
|
1598
|
+
function b(h) {
|
|
1599
|
+
t.dismissAnnouncement(h), u = u.filter((f) => f !== h), S(), e.titleInput.focus();
|
|
1572
1600
|
}
|
|
1573
|
-
|
|
1574
|
-
e.closed || (
|
|
1601
|
+
r.announcements !== !1 && typeof t.announcements == "function" && t.announcements().then((h) => {
|
|
1602
|
+
e.closed || (u = h, S());
|
|
1575
1603
|
}).catch(() => {
|
|
1576
1604
|
});
|
|
1577
1605
|
}
|
|
1578
|
-
function
|
|
1606
|
+
function ct(e) {
|
|
1579
1607
|
const {
|
|
1580
1608
|
client: t,
|
|
1581
|
-
cfg:
|
|
1582
|
-
titleInput:
|
|
1583
|
-
known:
|
|
1609
|
+
cfg: r,
|
|
1610
|
+
titleInput: d,
|
|
1611
|
+
known: u
|
|
1584
1612
|
} = e;
|
|
1585
|
-
let
|
|
1586
|
-
function
|
|
1587
|
-
|
|
1588
|
-
|
|
1613
|
+
let S = [], b = "", h = null, f = null;
|
|
1614
|
+
function s() {
|
|
1615
|
+
r.knownIssues !== !1 && t.knownIssues().then((x) => {
|
|
1616
|
+
S = x, g();
|
|
1589
1617
|
}).catch(() => {
|
|
1590
1618
|
});
|
|
1591
1619
|
}
|
|
1592
|
-
let
|
|
1593
|
-
function L(
|
|
1594
|
-
if (
|
|
1595
|
-
clearTimeout(
|
|
1596
|
-
const
|
|
1597
|
-
if (
|
|
1598
|
-
|
|
1620
|
+
let c = null;
|
|
1621
|
+
function L(x) {
|
|
1622
|
+
if (r.knownIssues === !1) return;
|
|
1623
|
+
clearTimeout(c), f == null || f.abort();
|
|
1624
|
+
const T = (x || "").trim();
|
|
1625
|
+
if (T.length < 3) {
|
|
1626
|
+
s();
|
|
1599
1627
|
return;
|
|
1600
1628
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1629
|
+
c = setTimeout(() => {
|
|
1630
|
+
f = new AbortController(), t.matchKnownIssues(T, { signal: f.signal }).then((i) => {
|
|
1631
|
+
i.length && (S = i, g());
|
|
1604
1632
|
}).catch(() => {
|
|
1605
1633
|
});
|
|
1606
1634
|
}, 250);
|
|
1607
1635
|
}
|
|
1608
|
-
function
|
|
1609
|
-
if (!
|
|
1610
|
-
|
|
1636
|
+
function g() {
|
|
1637
|
+
if (!S.length) {
|
|
1638
|
+
u.hidden = !0, u.innerHTML = "";
|
|
1611
1639
|
return;
|
|
1612
1640
|
}
|
|
1613
|
-
|
|
1641
|
+
u.hidden = !1, u.innerHTML = `
|
|
1614
1642
|
<p class="known-h">Already reported</p>
|
|
1615
|
-
${
|
|
1616
|
-
<div class="issue ${
|
|
1643
|
+
${S.map((x) => `
|
|
1644
|
+
<div class="issue ${x.joined ? "is-joined" : ""}">
|
|
1617
1645
|
<span class="who">
|
|
1618
|
-
<span class="t">${v(
|
|
1619
|
-
<span class="meta">${v(
|
|
1646
|
+
<span class="t">${v(x.title)}</span>
|
|
1647
|
+
<span class="meta">${v(w(x))}</span>
|
|
1620
1648
|
</span>
|
|
1621
|
-
<button class="join" type="button" data-join="${v(
|
|
1622
|
-
${
|
|
1649
|
+
<button class="join" type="button" data-join="${v(x.id)}"
|
|
1650
|
+
${x.joined ? "disabled" : ""}>${x.joined ? "Following" : "Me too"}</button>
|
|
1623
1651
|
</div>
|
|
1624
|
-
${
|
|
1652
|
+
${h === x.id ? `
|
|
1625
1653
|
<div class="ask">
|
|
1626
1654
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1627
1655
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1628
|
-
<button class="ghost" type="button" data-join-confirm="${v(
|
|
1656
|
+
<button class="ghost" type="button" data-join-confirm="${v(x.id)}">Follow</button>
|
|
1629
1657
|
</div>` : ""}
|
|
1630
1658
|
`).join("")}
|
|
1631
|
-
${
|
|
1632
|
-
}
|
|
1633
|
-
function
|
|
1634
|
-
const
|
|
1635
|
-
return `${
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
var a,
|
|
1639
|
-
const
|
|
1640
|
-
if (!
|
|
1641
|
-
const n = (
|
|
1642
|
-
|
|
1643
|
-
const
|
|
1644
|
-
if (!
|
|
1645
|
-
|
|
1659
|
+
${b ? `<p class="err">${v(b)}</p>` : ""}`;
|
|
1660
|
+
}
|
|
1661
|
+
function w(x) {
|
|
1662
|
+
const T = x.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", i = x.affectedCount === 0 ? "" : ` · ${x.affectedCount} ${x.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
|
|
1663
|
+
return `${T} · reported ${J(x.since)}${i}`;
|
|
1664
|
+
}
|
|
1665
|
+
u.addEventListener("click", async (x) => {
|
|
1666
|
+
var a, k, y, m, l;
|
|
1667
|
+
const T = x.target.closest("[data-join]"), i = x.target.closest("[data-join-confirm]");
|
|
1668
|
+
if (!T && !i) return;
|
|
1669
|
+
const n = (i || T).getAttribute(i ? "data-join-confirm" : "data-join");
|
|
1670
|
+
b = "";
|
|
1671
|
+
const o = ((k = (a = u.querySelector(".join-email")) == null ? void 0 : a.value) == null ? void 0 : k.trim()) || ((y = t.signedInAs()) == null ? void 0 : y.email) || ((m = t.config.user) == null ? void 0 : m.email);
|
|
1672
|
+
if (!o) {
|
|
1673
|
+
h = n, g(), (l = u.querySelector(".join-email")) == null || l.focus();
|
|
1646
1674
|
return;
|
|
1647
1675
|
}
|
|
1648
1676
|
try {
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1651
|
-
} catch (
|
|
1652
|
-
|
|
1677
|
+
const $ = await t.meToo(n, { email: o });
|
|
1678
|
+
h = null, S = S.map((q) => q.id === n ? { ...q, joined: !0, affectedCount: $.affectedCount ?? q.affectedCount } : q), g();
|
|
1679
|
+
} catch ($) {
|
|
1680
|
+
b = $.message.replace("[BugCatch] ", ""), g();
|
|
1653
1681
|
}
|
|
1654
|
-
}),
|
|
1682
|
+
}), s(), d.addEventListener("input", () => L(d.value));
|
|
1655
1683
|
}
|
|
1656
|
-
function
|
|
1684
|
+
function dt(e) {
|
|
1657
1685
|
const {
|
|
1658
1686
|
client: t,
|
|
1659
|
-
cfg:
|
|
1660
|
-
titleInput:
|
|
1661
|
-
descInput:
|
|
1662
|
-
picks:
|
|
1687
|
+
cfg: r,
|
|
1688
|
+
titleInput: d,
|
|
1689
|
+
descInput: u,
|
|
1690
|
+
picks: S
|
|
1663
1691
|
} = e;
|
|
1664
|
-
let
|
|
1665
|
-
function
|
|
1666
|
-
if (!
|
|
1667
|
-
|
|
1692
|
+
let b = [], h = null;
|
|
1693
|
+
function f() {
|
|
1694
|
+
if (!b.length) {
|
|
1695
|
+
S.hidden = !0, S.innerHTML = "";
|
|
1668
1696
|
return;
|
|
1669
1697
|
}
|
|
1670
|
-
|
|
1698
|
+
S.hidden = !1, S.innerHTML = `
|
|
1671
1699
|
<p class="picks-h">Get an answer right away</p>
|
|
1672
1700
|
<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
|
-
${
|
|
1701
|
+
${b.map((s, c) => `
|
|
1702
|
+
<button type="button" class="pick" data-pick="${v(s.key)}"
|
|
1703
|
+
${s.hint ? `title="${v(s.hint)}" aria-describedby="bc-pick-h${c}"` : ""}
|
|
1704
|
+
aria-pressed="${(h == null ? void 0 : h.key) === s.key}">
|
|
1705
|
+
<span class="t">${v(s.title)}</span>
|
|
1706
|
+
${s.hint ? `<span class="h sr-only" id="bc-pick-h${c}">${v(s.hint)}</span>` : ""}
|
|
1679
1707
|
</button>`).join("")}
|
|
1680
1708
|
</div>
|
|
1681
|
-
${
|
|
1709
|
+
${h ? `<p class="picks-note">${P}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>` : ""}`;
|
|
1682
1710
|
}
|
|
1683
|
-
|
|
1684
|
-
const
|
|
1685
|
-
if (!
|
|
1686
|
-
const L =
|
|
1711
|
+
S.addEventListener("click", (s) => {
|
|
1712
|
+
const c = s.target.closest("[data-pick]");
|
|
1713
|
+
if (!c) return;
|
|
1714
|
+
const L = b.find((w) => w.key === c.dataset.pick);
|
|
1687
1715
|
if (!L) return;
|
|
1688
|
-
const
|
|
1689
|
-
(
|
|
1690
|
-
}),
|
|
1691
|
-
|
|
1716
|
+
const g = h && d.value.trim() === h.title;
|
|
1717
|
+
(h == null ? void 0 : h.key) === L.key ? (h = null, g && (d.value = "")) : (h = L, (!d.value.trim() || g) && (d.value = L.title)), d.dispatchEvent(new Event("input", { bubbles: !0 })), f(), h && u.focus();
|
|
1718
|
+
}), r.agentIssues !== !1 && typeof t.agentIssues == "function" && t.agentIssues().then((s) => {
|
|
1719
|
+
b = s, f();
|
|
1692
1720
|
}).catch(() => {
|
|
1693
|
-
}), e.pickedIssue = () =>
|
|
1721
|
+
}), e.pickedIssue = () => h;
|
|
1694
1722
|
}
|
|
1695
|
-
function
|
|
1723
|
+
function pt(e) {
|
|
1696
1724
|
const {
|
|
1697
1725
|
client: t,
|
|
1698
|
-
scrim:
|
|
1699
|
-
say:
|
|
1700
|
-
callBtn:
|
|
1701
|
-
close:
|
|
1726
|
+
scrim: r,
|
|
1727
|
+
say: d,
|
|
1728
|
+
callBtn: u,
|
|
1729
|
+
close: S
|
|
1702
1730
|
} = e;
|
|
1703
|
-
let
|
|
1704
|
-
function
|
|
1705
|
-
t.callKind().then((
|
|
1706
|
-
|
|
1731
|
+
let b = !1;
|
|
1732
|
+
function h() {
|
|
1733
|
+
t.callKind().then((c) => {
|
|
1734
|
+
c && (b = !0, e.preloadCall(), u.hidden = e.mustSignIn() || e.mustRate());
|
|
1707
1735
|
}).catch(() => {
|
|
1708
1736
|
});
|
|
1709
1737
|
}
|
|
1710
|
-
|
|
1711
|
-
e.sending = !0,
|
|
1738
|
+
h(), u.addEventListener("click", async () => {
|
|
1739
|
+
e.sending = !0, d(""), e.refreshSendState(), u.disabled = !0, u.innerHTML = '<span class="spinner"></span>Ringing…';
|
|
1712
1740
|
try {
|
|
1713
|
-
const
|
|
1714
|
-
|
|
1715
|
-
} catch (
|
|
1716
|
-
e.sending = !1,
|
|
1741
|
+
const c = await t.startCall();
|
|
1742
|
+
f(c);
|
|
1743
|
+
} catch (c) {
|
|
1744
|
+
e.sending = !1, u.disabled = !1, u.innerHTML = `${re}Talk to the team`, e.refreshSendState(), c.filed ? e.succeed(c.filed, { callFailed: c.reason || "The call could not be started." }) : (d(c.message.replace("[BugCatch] ", "")), e.recheckSignIn());
|
|
1717
1745
|
}
|
|
1718
1746
|
});
|
|
1719
|
-
function
|
|
1720
|
-
const L =
|
|
1747
|
+
function f(c) {
|
|
1748
|
+
const L = r.querySelector(".panel"), g = c != null && c.bugId ? String(c.bugId).slice(0, 8) : null;
|
|
1721
1749
|
L.innerHTML = `
|
|
1722
1750
|
<div class="call">
|
|
1723
1751
|
<div class="call-head">
|
|
@@ -1725,246 +1753,246 @@ function lt(e) {
|
|
|
1725
1753
|
<strong class="call-state">Ringing…</strong>
|
|
1726
1754
|
</div>
|
|
1727
1755
|
<p class="call-note">
|
|
1728
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1756
|
+
We're ringing the team now. Someone will pick up if they're free — your report${g ? ` <code>${v(g)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
|
|
1729
1757
|
</p>
|
|
1730
1758
|
<div class="foot">
|
|
1731
1759
|
<span class="spacer"></span>
|
|
1732
1760
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1733
1761
|
</div>
|
|
1734
1762
|
</div>`;
|
|
1735
|
-
const
|
|
1763
|
+
const w = L.querySelector(".call-state"), x = L.querySelector(".call-dot"), T = {
|
|
1736
1764
|
ringing: "Ringing the team…",
|
|
1737
1765
|
connecting: "Someone answered — connecting…",
|
|
1738
1766
|
connected: "Connected",
|
|
1739
1767
|
missed: "Nobody was free",
|
|
1740
1768
|
ended: "Call ended",
|
|
1741
1769
|
failed: "The call dropped"
|
|
1742
|
-
},
|
|
1743
|
-
if (
|
|
1770
|
+
}, i = ["ended", "failed", "missed"], n = t.on("call", ({ state: o }) => {
|
|
1771
|
+
if (w.textContent = T[o] || o, x.classList.toggle("off", i.includes(o)), i.includes(o) && (L.querySelector('[data-act="hangup"]').textContent = "Close", o === "missed")) {
|
|
1744
1772
|
const a = L.querySelector(".call-note");
|
|
1745
1773
|
a && (a.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
|
|
1746
1774
|
}
|
|
1747
1775
|
});
|
|
1748
1776
|
L.querySelector('[data-act="hangup"]').addEventListener("click", () => {
|
|
1749
|
-
n(), t.endCall(),
|
|
1777
|
+
n(), t.endCall(), S();
|
|
1750
1778
|
});
|
|
1751
1779
|
}
|
|
1752
|
-
function
|
|
1753
|
-
const
|
|
1754
|
-
|
|
1780
|
+
function s(c, L, g) {
|
|
1781
|
+
const w = document.createElement("div");
|
|
1782
|
+
w.className = "livecall", w.innerHTML = `
|
|
1755
1783
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1756
1784
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1757
1785
|
<span class="secs" hidden></span>
|
|
1758
|
-
${
|
|
1786
|
+
${g != null && g.recorded ? '<span class="call-kept">This call is recorded.</span>' : ""}
|
|
1759
1787
|
<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
|
|
1788
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`, c.insertBefore(w, L);
|
|
1789
|
+
const x = w.querySelector(".who"), T = w.querySelector(".secs"), i = w.querySelector(".call-dot"), n = w.querySelector('[data-act="mute"]'), o = w.querySelector('[data-act="hangup"]');
|
|
1762
1790
|
let a = null;
|
|
1763
|
-
const
|
|
1791
|
+
const k = () => {
|
|
1764
1792
|
a && (clearInterval(a), a = null);
|
|
1765
|
-
},
|
|
1766
|
-
|
|
1767
|
-
},
|
|
1768
|
-
if (
|
|
1769
|
-
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
}, 1e3),
|
|
1793
|
+
}, y = (l) => {
|
|
1794
|
+
k(), i.classList.add("off"), w.classList.add("over"), x.textContent = l, T.hidden = !0, n.hidden = !0, o.textContent = "Dismiss", o.classList.remove("danger");
|
|
1795
|
+
}, m = t.on("call", ({ state: l }) => {
|
|
1796
|
+
if (l === "ringing" && (x.textContent = "Calling the team…"), l === "connecting" && (x.textContent = "Someone answered — connecting…"), l === "connected") {
|
|
1797
|
+
x.textContent = "You're on a call with the team", n.hidden = !1, T.hidden = !1;
|
|
1798
|
+
const $ = Date.now();
|
|
1799
|
+
k(), a = setInterval(() => {
|
|
1800
|
+
T.textContent = te(Math.floor((Date.now() - $) / 1e3));
|
|
1801
|
+
}, 1e3), T.textContent = "0s";
|
|
1774
1802
|
}
|
|
1775
|
-
|
|
1803
|
+
l === "missed" && y("Nobody was free. Send a message instead and the team will pick it up."), l === "ended" && y("Call ended."), l === "failed" && y("The call dropped.");
|
|
1776
1804
|
});
|
|
1777
1805
|
n.addEventListener("click", () => {
|
|
1778
|
-
const
|
|
1779
|
-
n.textContent =
|
|
1780
|
-
}),
|
|
1781
|
-
|
|
1806
|
+
const l = g.setMuted(!g.isMuted());
|
|
1807
|
+
n.textContent = l ? "Unmute" : "Mute", x.textContent = l ? "You're muted" : "You're on a call with the team";
|
|
1808
|
+
}), o.addEventListener("click", () => {
|
|
1809
|
+
m(), k(), t.endCall(), w.remove(), e.refreshThread(e.openReportId());
|
|
1782
1810
|
});
|
|
1783
1811
|
}
|
|
1784
|
-
e.offerCall =
|
|
1812
|
+
e.offerCall = h, e.callOffered = () => b, e.showLiveCall = s;
|
|
1785
1813
|
}
|
|
1786
|
-
function
|
|
1787
|
-
var
|
|
1814
|
+
function ut(e) {
|
|
1815
|
+
var m;
|
|
1788
1816
|
const {
|
|
1789
1817
|
client: t,
|
|
1790
|
-
say:
|
|
1791
|
-
compose:
|
|
1792
|
-
sendBtn:
|
|
1793
|
-
historyBtn:
|
|
1794
|
-
callBtn:
|
|
1795
|
-
whoami:
|
|
1818
|
+
say: r,
|
|
1819
|
+
compose: d,
|
|
1820
|
+
sendBtn: u,
|
|
1821
|
+
historyBtn: S,
|
|
1822
|
+
callBtn: b,
|
|
1823
|
+
whoami: h
|
|
1796
1824
|
} = e;
|
|
1797
|
-
let
|
|
1798
|
-
const
|
|
1799
|
-
function
|
|
1800
|
-
const
|
|
1801
|
-
|
|
1825
|
+
let f = { mode: t.lastLoginMode || "off", signedIn: null }, s = "idle", c = ((m = t.config.user) == null ? void 0 : m.email) || "", L = "", g = !1, w = "";
|
|
1826
|
+
const x = () => f.mode === "required" && !f.signedIn;
|
|
1827
|
+
function T() {
|
|
1828
|
+
const l = x();
|
|
1829
|
+
d.hidden = l, u.hidden = l, S && (S.hidden = l), l ? b.hidden = !0 : e.callOffered() && !e.mustRate() && (b.hidden = !1);
|
|
1802
1830
|
}
|
|
1803
|
-
function
|
|
1804
|
-
var
|
|
1805
|
-
if (
|
|
1806
|
-
|
|
1831
|
+
function i() {
|
|
1832
|
+
var $;
|
|
1833
|
+
if (f.mode === "off") {
|
|
1834
|
+
h.hidden = !0, h.innerHTML = "";
|
|
1807
1835
|
return;
|
|
1808
1836
|
}
|
|
1809
|
-
|
|
1810
|
-
const
|
|
1811
|
-
if (
|
|
1812
|
-
if (
|
|
1813
|
-
|
|
1837
|
+
h.hidden = !1, h.classList.toggle("asking", s !== "idle");
|
|
1838
|
+
const l = w ? `<div class="after err">${v(w)}</div>` : "";
|
|
1839
|
+
if (s === "idle") {
|
|
1840
|
+
if (f.signedIn) {
|
|
1841
|
+
h.innerHTML = `<span class="who">Signed in as <strong>${v(f.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
|
|
1814
1842
|
return;
|
|
1815
1843
|
}
|
|
1816
|
-
const
|
|
1817
|
-
|
|
1844
|
+
const q = ($ = t.config.user) == null ? void 0 : $.email;
|
|
1845
|
+
h.innerHTML = `<span class="who">${f.mode === "required" ? "Sign in to report a bug here." : q ? `Reporting as <strong>${v(q)}</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
1846
|
return;
|
|
1819
1847
|
}
|
|
1820
|
-
if (
|
|
1821
|
-
|
|
1848
|
+
if (s === "email") {
|
|
1849
|
+
h.innerHTML = `
|
|
1822
1850
|
<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${
|
|
1851
|
+
It's how you hear back about this report${f.mode === "required" ? ", and this project asks for it" : ""}.</p>
|
|
1824
1852
|
<div class="row">
|
|
1825
|
-
<input type="email" data-fld="email" value="${v(
|
|
1853
|
+
<input type="email" data-fld="email" value="${v(c)}"
|
|
1826
1854
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1827
|
-
aria-label="Your email address" ${
|
|
1828
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1829
|
-
${
|
|
1855
|
+
aria-label="Your email address" ${g ? "disabled" : ""} />
|
|
1856
|
+
<button type="button" class="primary" data-act="code" ${g ? "disabled" : ""}>
|
|
1857
|
+
${g ? "Sending…" : "Send code"}
|
|
1830
1858
|
</button>
|
|
1831
1859
|
</div>
|
|
1832
|
-
${
|
|
1833
|
-
${
|
|
1860
|
+
${l}
|
|
1861
|
+
${f.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
|
|
1834
1862
|
return;
|
|
1835
1863
|
}
|
|
1836
|
-
|
|
1837
|
-
<p class="why">We sent a code to <strong>${v(
|
|
1864
|
+
h.innerHTML = `
|
|
1865
|
+
<p class="why">We sent a code to <strong>${v(c)}</strong>. It expires in ten minutes.</p>
|
|
1838
1866
|
<div class="row">
|
|
1839
1867
|
<input type="text" class="code" data-fld="code" value="${v(L)}"
|
|
1840
1868
|
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
|
-
${
|
|
1869
|
+
maxlength="8" aria-label="The code we emailed you" ${g ? "disabled" : ""} />
|
|
1870
|
+
<button type="button" class="primary" data-act="confirm" ${g ? "disabled" : ""}>
|
|
1871
|
+
${g ? "Checking…" : "Sign in"}
|
|
1844
1872
|
</button>
|
|
1845
1873
|
</div>
|
|
1846
|
-
${
|
|
1874
|
+
${l}
|
|
1847
1875
|
<div class="after">
|
|
1848
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1849
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1876
|
+
<button type="button" class="link" data-act="resend" ${g ? "disabled" : ""}>Send it again</button>
|
|
1877
|
+
<button type="button" class="link" data-act="signin-back" ${g ? "disabled" : ""}>Use another address</button>
|
|
1850
1878
|
</div>`;
|
|
1851
1879
|
}
|
|
1852
|
-
function n({ focus:
|
|
1853
|
-
var
|
|
1854
|
-
if (
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
}),
|
|
1862
|
-
|
|
1880
|
+
function n({ focus: l = !1 } = {}) {
|
|
1881
|
+
var q;
|
|
1882
|
+
if (i(), T(), !l || g) return;
|
|
1883
|
+
const $ = h.querySelector("[data-fld]");
|
|
1884
|
+
$ && ($.focus(), (q = $.setSelectionRange) == null || q.call($, $.value.length, $.value.length));
|
|
1885
|
+
}
|
|
1886
|
+
h.addEventListener("input", (l) => {
|
|
1887
|
+
const $ = l.target.closest("[data-fld]");
|
|
1888
|
+
$ && ($.dataset.fld === "email" ? c = $.value : L = $.value);
|
|
1889
|
+
}), h.addEventListener("keydown", (l) => {
|
|
1890
|
+
l.key !== "Enter" || !l.target.closest("[data-fld]") || (l.preventDefault(), s === "email" ? o() : a());
|
|
1863
1891
|
});
|
|
1864
|
-
async function
|
|
1865
|
-
const
|
|
1866
|
-
if (
|
|
1867
|
-
|
|
1892
|
+
async function o({ resent: l = !1 } = {}) {
|
|
1893
|
+
const $ = c.trim();
|
|
1894
|
+
if (!$) {
|
|
1895
|
+
w = "Enter the address to send the code to.", n({ focus: !0 });
|
|
1868
1896
|
return;
|
|
1869
1897
|
}
|
|
1870
|
-
|
|
1898
|
+
g = !0, w = "", n();
|
|
1871
1899
|
try {
|
|
1872
|
-
await t.signIn(
|
|
1873
|
-
} catch (
|
|
1874
|
-
|
|
1900
|
+
await t.signIn($), c = $, l || (L = ""), s = "code";
|
|
1901
|
+
} catch (q) {
|
|
1902
|
+
w = q.message;
|
|
1875
1903
|
} finally {
|
|
1876
|
-
|
|
1904
|
+
g = !1, n({ focus: !0 });
|
|
1877
1905
|
}
|
|
1878
1906
|
}
|
|
1879
1907
|
async function a() {
|
|
1880
|
-
const
|
|
1881
|
-
if (!
|
|
1882
|
-
|
|
1908
|
+
const l = L.trim();
|
|
1909
|
+
if (!l) {
|
|
1910
|
+
w = "Enter the code we emailed you.", n({ focus: !0 });
|
|
1883
1911
|
return;
|
|
1884
1912
|
}
|
|
1885
|
-
|
|
1913
|
+
g = !0, w = "", n();
|
|
1886
1914
|
try {
|
|
1887
|
-
const
|
|
1888
|
-
|
|
1889
|
-
} catch (
|
|
1890
|
-
|
|
1915
|
+
const $ = await t.confirmSignIn(c.trim(), l);
|
|
1916
|
+
f.signedIn = $, s = "idle", L = "", r(""), e.offerCall();
|
|
1917
|
+
} catch ($) {
|
|
1918
|
+
w = $.message;
|
|
1891
1919
|
} finally {
|
|
1892
|
-
|
|
1920
|
+
g = !1, n({ focus: s !== "idle" });
|
|
1893
1921
|
}
|
|
1894
1922
|
}
|
|
1895
|
-
|
|
1896
|
-
const
|
|
1897
|
-
if (
|
|
1898
|
-
const
|
|
1899
|
-
if (
|
|
1900
|
-
|
|
1923
|
+
h.addEventListener("click", async (l) => {
|
|
1924
|
+
const $ = l.target.closest("button[data-act]");
|
|
1925
|
+
if (!$) return;
|
|
1926
|
+
const q = $.dataset.act;
|
|
1927
|
+
if (q === "signin") {
|
|
1928
|
+
s = "email", w = "", n({ focus: !0 });
|
|
1901
1929
|
return;
|
|
1902
1930
|
}
|
|
1903
|
-
if (
|
|
1904
|
-
|
|
1931
|
+
if (q === "skip") {
|
|
1932
|
+
s = "idle", w = "", n();
|
|
1905
1933
|
return;
|
|
1906
1934
|
}
|
|
1907
|
-
if (
|
|
1908
|
-
|
|
1935
|
+
if (q === "signin-back") {
|
|
1936
|
+
s = "email", w = "", L = "", n({ focus: !0 });
|
|
1909
1937
|
return;
|
|
1910
1938
|
}
|
|
1911
|
-
if (
|
|
1912
|
-
|
|
1939
|
+
if (q === "code") {
|
|
1940
|
+
o();
|
|
1913
1941
|
return;
|
|
1914
1942
|
}
|
|
1915
|
-
if (
|
|
1916
|
-
|
|
1943
|
+
if (q === "resend") {
|
|
1944
|
+
o({ resent: !0 });
|
|
1917
1945
|
return;
|
|
1918
1946
|
}
|
|
1919
|
-
if (
|
|
1947
|
+
if (q === "confirm") {
|
|
1920
1948
|
a();
|
|
1921
1949
|
return;
|
|
1922
1950
|
}
|
|
1923
|
-
if (
|
|
1924
|
-
|
|
1951
|
+
if (q === "signout") {
|
|
1952
|
+
g = !0, n();
|
|
1925
1953
|
try {
|
|
1926
1954
|
await t.signOut();
|
|
1927
1955
|
} finally {
|
|
1928
|
-
|
|
1956
|
+
f.signedIn = null, g = !1, s = f.mode === "required" ? "email" : "idle", n({ focus: s !== "idle" });
|
|
1929
1957
|
}
|
|
1930
1958
|
}
|
|
1931
1959
|
});
|
|
1932
|
-
async function
|
|
1933
|
-
const
|
|
1934
|
-
|
|
1960
|
+
async function k({ announce: l = !1 } = {}) {
|
|
1961
|
+
const $ = await t.loginState();
|
|
1962
|
+
f = { mode: $.mode, signedIn: $.signedIn }, t.lastLoginMode = $.mode, x() && s === "idle" && (s = "email"), f.signedIn && (s = "idle"), l && $.signedOutReason && r($.signedOutReason, "info"), n();
|
|
1935
1963
|
}
|
|
1936
|
-
|
|
1964
|
+
k({ announce: !0 }).catch(() => {
|
|
1937
1965
|
});
|
|
1938
|
-
function
|
|
1939
|
-
|
|
1966
|
+
function y() {
|
|
1967
|
+
f.mode !== "off" && k().catch(() => {
|
|
1940
1968
|
});
|
|
1941
1969
|
}
|
|
1942
|
-
e.mustSignIn =
|
|
1970
|
+
e.mustSignIn = x, e.recheckSignIn = y;
|
|
1943
1971
|
}
|
|
1944
|
-
function
|
|
1972
|
+
function he(e) {
|
|
1945
1973
|
const t = e || [];
|
|
1946
1974
|
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: (L =
|
|
1957
|
-
body: (
|
|
1958
|
-
at:
|
|
1959
|
-
attachments: (
|
|
1960
|
-
},
|
|
1961
|
-
return
|
|
1975
|
+
let r = null, d = null;
|
|
1976
|
+
return t.map((u) => {
|
|
1977
|
+
var c, L, g, w;
|
|
1978
|
+
const S = Z(u.at), b = S && S !== r ? `<div class="day-sep" role="separator">${v(Xe(u.at))}</div>` : "";
|
|
1979
|
+
if (b && (r = S, d = null), !u.from)
|
|
1980
|
+
return d = null, b + bt(u);
|
|
1981
|
+
const h = {
|
|
1982
|
+
from: u.from,
|
|
1983
|
+
author: (c = u.reply) == null ? void 0 : c.author,
|
|
1984
|
+
automated: (L = u.reply) == null ? void 0 : L.automated,
|
|
1985
|
+
body: (g = u.reply) == null ? void 0 : g.body,
|
|
1986
|
+
at: u.at,
|
|
1987
|
+
attachments: (w = u.reply) == null ? void 0 : w.attachments
|
|
1988
|
+
}, f = ht(h), s = d && d.who === f && Math.abs(new Date(u.at).getTime() - new Date(d.at).getTime()) < 5 * 6e4;
|
|
1989
|
+
return d = { who: f, at: u.at }, b + we(h, s ? "cont" : "");
|
|
1962
1990
|
}).join("");
|
|
1963
1991
|
}
|
|
1964
|
-
function
|
|
1992
|
+
function ht(e) {
|
|
1965
1993
|
return e.from === "reporter" ? "me" : e.automated ? "assistant" : `team:${e.author || ""}`;
|
|
1966
1994
|
}
|
|
1967
|
-
function
|
|
1995
|
+
function bt(e) {
|
|
1968
1996
|
const t = ve(e.at);
|
|
1969
1997
|
return `
|
|
1970
1998
|
<div class="sys k-${v(e.kind)}">
|
|
@@ -1973,32 +2001,32 @@ function pt(e) {
|
|
|
1973
2001
|
</div>`;
|
|
1974
2002
|
}
|
|
1975
2003
|
function we(e, t = "") {
|
|
1976
|
-
const
|
|
1977
|
-
let
|
|
1978
|
-
if (
|
|
1979
|
-
|
|
1980
|
-
else if (!
|
|
2004
|
+
const r = e.from === "reporter", d = e.body || "", u = e.attachments || [], S = !r && !!e.automated, b = d ? `<span class="msg-text">${v(d)}</span>` : "", h = u.length ? `<div class="att">${u.map(gt).join("")}</div>` : "";
|
|
2005
|
+
let f = "", s = "";
|
|
2006
|
+
if (S)
|
|
2007
|
+
f = '<span class="msg-who auto">Assistant <span class="tag">AI</span></span>', s = '<span class="av bot orb" aria-hidden="true"></span>';
|
|
2008
|
+
else if (!r) {
|
|
1981
2009
|
const L = e.author || "Support team";
|
|
1982
|
-
|
|
2010
|
+
f = `<span class="msg-who">${v(L)}</span>`, s = `<span class="av" aria-hidden="true">${v(Je(L))}</span>`;
|
|
1983
2011
|
}
|
|
1984
|
-
t.includes("cont") && (
|
|
1985
|
-
const
|
|
1986
|
-
<button type="button" data-quick="Yes, this is the problem">${
|
|
2012
|
+
t.includes("cont") && (f = "");
|
|
2013
|
+
const c = S && /it goes to the same person/i.test(d) ? `<div class="quick" role="group" aria-label="Answer">
|
|
2014
|
+
<button type="button" data-quick="Yes, this is the problem">${P}That's right</button>
|
|
1987
2015
|
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
1988
|
-
</div>` :
|
|
1989
|
-
<button type="button" data-quick="Yes, that answers it">${
|
|
2016
|
+
</div>` : S && Ie.test(d) ? `<div class="quick" role="group" aria-label="Did this answer your question?">
|
|
2017
|
+
<button type="button" data-quick="Yes, that answers it">${P}Yes, that answers it</button>
|
|
1990
2018
|
<button type="button" data-quick="No, I still need help">No, I still need help</button>
|
|
1991
2019
|
</div>` : "";
|
|
1992
2020
|
return `
|
|
1993
|
-
<div class="msg-row ${
|
|
1994
|
-
${
|
|
1995
|
-
${
|
|
1996
|
-
<div class="bubble ${
|
|
1997
|
-
${
|
|
1998
|
-
<span class="msg-when">${v(ve(e.at) ||
|
|
2021
|
+
<div class="msg-row ${r ? "mine" : "theirs"} ${S ? "auto" : ""} ${t}">
|
|
2022
|
+
${s}
|
|
2023
|
+
${f}
|
|
2024
|
+
<div class="bubble ${d ? "" : "silent"}">${b}${h}</div>
|
|
2025
|
+
${c}
|
|
2026
|
+
<span class="msg-when">${v(ve(e.at) || J(e.at))}</span>
|
|
1999
2027
|
</div>`;
|
|
2000
2028
|
}
|
|
2001
|
-
function
|
|
2029
|
+
function ft() {
|
|
2002
2030
|
return `
|
|
2003
2031
|
<div class="typing-row">
|
|
2004
2032
|
<span class="av bot orb" aria-hidden="true"></span>
|
|
@@ -2006,385 +2034,492 @@ function ut() {
|
|
|
2006
2034
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
2007
2035
|
</div>`;
|
|
2008
2036
|
}
|
|
2009
|
-
function
|
|
2037
|
+
function gt(e) {
|
|
2010
2038
|
const t = v(e.name || "attachment");
|
|
2011
2039
|
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="${
|
|
2040
|
+
const r = v(e.url);
|
|
2041
|
+
return e.type === "SCREENSHOT" ? `<a href="${r}" target="_blank" rel="noopener noreferrer"><img src="${r}" alt="${t}" loading="lazy"></a>` : e.type === "AUDIO" ? `<audio controls preload="metadata" src="${r}"></audio>` : e.type === "VIDEO" ? `<video controls preload="metadata" src="${r}"></video>` : `
|
|
2042
|
+
<a class="file" href="${r}" target="_blank" rel="noopener noreferrer" download>
|
|
2015
2043
|
<span class="nm">${t}</span>
|
|
2016
|
-
${e.size ? `<span class="sz">${v(
|
|
2044
|
+
${e.size ? `<span class="sz">${v(F(e.size))}</span>` : ""}
|
|
2017
2045
|
</a>`;
|
|
2018
2046
|
}
|
|
2019
|
-
function
|
|
2020
|
-
var
|
|
2021
|
-
const { client:
|
|
2022
|
-
|
|
2047
|
+
function mt(e, t, r, d) {
|
|
2048
|
+
var y;
|
|
2049
|
+
const { client: u, cfg: S } = e, b = document.createElement("div");
|
|
2050
|
+
b.className = "composer", b.innerHTML = `
|
|
2023
2051
|
<div class="staged" hidden></div>
|
|
2024
2052
|
<div class="row">
|
|
2025
2053
|
<div class="tools">
|
|
2026
|
-
${
|
|
2054
|
+
${S.attachments === !1 ? "" : `
|
|
2027
2055
|
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${fe}</button>
|
|
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>${
|
|
2056
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${pe}</button>`}
|
|
2057
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${re}</button>
|
|
2030
2058
|
</div>
|
|
2031
2059
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
2032
2060
|
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${ge}</button>
|
|
2033
2061
|
</div>
|
|
2034
2062
|
<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="${
|
|
2063
|
+
<input type="file" hidden multiple accept="${De.join(",")}">`, t.appendChild(b);
|
|
2064
|
+
const h = b.querySelector(".staged"), f = b.querySelector("textarea"), s = b.querySelector('[data-act="send"]'), c = b.querySelector('[data-act="voice"]'), L = b.querySelector('[data-act="livecall"]'), g = b.querySelector("input[type=file]"), w = b.querySelector(".note"), x = [];
|
|
2065
|
+
let T = null, i = !1;
|
|
2066
|
+
function n(m, l = "") {
|
|
2067
|
+
w.hidden = !m, w.className = `note ${l}`, w.textContent = m || "";
|
|
2068
|
+
}
|
|
2069
|
+
function o() {
|
|
2070
|
+
const m = x.filter((l) => l.storageKey);
|
|
2071
|
+
s.disabled = i || !f.value.trim() && !m.length, h.hidden = !x.length, h.innerHTML = x.map((l, $) => `
|
|
2072
|
+
<span class="chip ${l.storageKey ? "" : "uploading"}">
|
|
2073
|
+
<span class="nm">${v(l.name)}</span>
|
|
2074
|
+
<span class="sz">${l.storageKey ? F(l.size) : "sending…"}</span>
|
|
2075
|
+
<button type="button" data-drop="${$}" aria-label="Remove ${v(l.name)}">${ce}</button>
|
|
2048
2076
|
</span>`).join("");
|
|
2049
|
-
for (const
|
|
2050
|
-
|
|
2051
|
-
|
|
2077
|
+
for (const l of h.querySelectorAll("[data-drop]"))
|
|
2078
|
+
l.addEventListener("click", () => {
|
|
2079
|
+
x.splice(Number(l.dataset.drop), 1), o();
|
|
2052
2080
|
});
|
|
2053
2081
|
}
|
|
2054
|
-
async function a(
|
|
2055
|
-
const
|
|
2056
|
-
|
|
2082
|
+
async function a(m, l, $) {
|
|
2083
|
+
const q = { name: $, size: m.size, storageKey: null };
|
|
2084
|
+
x.push(q), o();
|
|
2057
2085
|
try {
|
|
2058
|
-
const { storageKey:
|
|
2059
|
-
|
|
2060
|
-
} catch (
|
|
2061
|
-
|
|
2086
|
+
const { storageKey: H, mime: O } = await u.uploadAttachment(m, l);
|
|
2087
|
+
q.storageKey = H, q.mime = O;
|
|
2088
|
+
} catch (H) {
|
|
2089
|
+
x.splice(x.indexOf(q), 1), n(H.message || "That file could not be sent.", "err");
|
|
2062
2090
|
}
|
|
2063
|
-
|
|
2091
|
+
o();
|
|
2064
2092
|
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
}),
|
|
2068
|
-
|
|
2069
|
-
}), (
|
|
2093
|
+
f.addEventListener("input", () => {
|
|
2094
|
+
f.style.height = "auto", f.style.height = `${Math.min(f.scrollHeight, 120)}px`, o();
|
|
2095
|
+
}), f.addEventListener("keydown", (m) => {
|
|
2096
|
+
m.key === "Enter" && !m.shiftKey && !m.isComposing && (m.preventDefault(), k());
|
|
2097
|
+
}), (y = b.querySelector('[data-act="attach"]')) == null || y.addEventListener("click", () => g.click()), g.addEventListener("change", () => {
|
|
2070
2098
|
n("");
|
|
2071
|
-
for (const
|
|
2072
|
-
if (
|
|
2073
|
-
n(`${
|
|
2099
|
+
for (const m of g.files) {
|
|
2100
|
+
if (m.size > u.config.maxAttachmentBytes) {
|
|
2101
|
+
n(`${m.name} is larger than ${F(u.config.maxAttachmentBytes)}.`, "err");
|
|
2074
2102
|
continue;
|
|
2075
2103
|
}
|
|
2076
|
-
a(
|
|
2104
|
+
a(m, m.type, m.name);
|
|
2077
2105
|
}
|
|
2078
|
-
|
|
2079
|
-
}),
|
|
2080
|
-
if (
|
|
2081
|
-
const
|
|
2082
|
-
|
|
2083
|
-
const { blob:
|
|
2084
|
-
|
|
2106
|
+
g.value = "";
|
|
2107
|
+
}), c && !Ve() && (c.disabled = !0, c.title = "This browser cannot record audio"), c == null || c.addEventListener("click", async () => {
|
|
2108
|
+
if (T) {
|
|
2109
|
+
const m = T;
|
|
2110
|
+
T = null, c.classList.remove("recording"), c.innerHTML = pe, n("");
|
|
2111
|
+
const { blob: l, mime: $ } = await m.stop();
|
|
2112
|
+
l.size && a(l, $, "Voice note");
|
|
2085
2113
|
return;
|
|
2086
2114
|
}
|
|
2087
2115
|
try {
|
|
2088
|
-
n(""),
|
|
2089
|
-
maxMs:
|
|
2090
|
-
onTick: (
|
|
2091
|
-
onAutoStop: () =>
|
|
2092
|
-
}),
|
|
2116
|
+
n(""), T = await je({
|
|
2117
|
+
maxMs: u.config.maxRecordingMs,
|
|
2118
|
+
onTick: (m) => n(`Recording — ${te(m)}. Tap the mic to stop.`),
|
|
2119
|
+
onAutoStop: () => c.click()
|
|
2120
|
+
}), c.classList.add("recording"), c.innerHTML = Ye;
|
|
2093
2121
|
} catch {
|
|
2094
|
-
|
|
2122
|
+
T = null, n("The microphone is not available — check the browser permission.", "err");
|
|
2095
2123
|
}
|
|
2096
|
-
}),
|
|
2097
|
-
|
|
2124
|
+
}), u.canCallTeam(d).then((m) => {
|
|
2125
|
+
m && (L.hidden = !1, e.preloadCall());
|
|
2098
2126
|
}).catch(() => {
|
|
2099
2127
|
}), L.addEventListener("click", async () => {
|
|
2100
2128
|
L.disabled = !0, n("");
|
|
2101
2129
|
try {
|
|
2102
|
-
const
|
|
2103
|
-
e.showLiveCall(t,
|
|
2104
|
-
} catch (
|
|
2105
|
-
n(
|
|
2130
|
+
const m = await u.startLiveCall(d);
|
|
2131
|
+
e.showLiveCall(t, r, m);
|
|
2132
|
+
} catch (m) {
|
|
2133
|
+
n(m.message.replace("[BugCatch] ", ""), "err");
|
|
2106
2134
|
} finally {
|
|
2107
2135
|
L.disabled = !1;
|
|
2108
2136
|
}
|
|
2109
|
-
}),
|
|
2110
|
-
var
|
|
2111
|
-
const
|
|
2112
|
-
!
|
|
2137
|
+
}), s.addEventListener("click", k), r.addEventListener("click", (m) => {
|
|
2138
|
+
var $, q;
|
|
2139
|
+
const l = (q = ($ = m.target).closest) == null ? void 0 : q.call($, "[data-quick]");
|
|
2140
|
+
!l || i || (f.value = l.dataset.quick, k());
|
|
2113
2141
|
});
|
|
2114
|
-
async function
|
|
2115
|
-
var
|
|
2116
|
-
const
|
|
2117
|
-
if (!(
|
|
2118
|
-
|
|
2142
|
+
async function k() {
|
|
2143
|
+
var $;
|
|
2144
|
+
const m = f.value.trim(), l = x.filter((q) => q.storageKey);
|
|
2145
|
+
if (!(i || !m && !l.length)) {
|
|
2146
|
+
i = !0, o(), n(""), r.insertAdjacentHTML("beforeend", we({
|
|
2119
2147
|
from: "reporter",
|
|
2120
|
-
body:
|
|
2148
|
+
body: m,
|
|
2121
2149
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2122
|
-
attachments:
|
|
2123
|
-
}, "pending")), _(
|
|
2150
|
+
attachments: l.map((q) => ({ type: "FILE", name: q.name, size: q.size }))
|
|
2151
|
+
}, "pending")), _(r, { smooth: !0 });
|
|
2124
2152
|
try {
|
|
2125
|
-
await
|
|
2126
|
-
body:
|
|
2127
|
-
attachments:
|
|
2128
|
-
storageKey:
|
|
2129
|
-
mime:
|
|
2130
|
-
name:
|
|
2131
|
-
size:
|
|
2153
|
+
await u.replyToReport(d, {
|
|
2154
|
+
body: m,
|
|
2155
|
+
attachments: l.map((q) => ({
|
|
2156
|
+
storageKey: q.storageKey,
|
|
2157
|
+
mime: q.mime,
|
|
2158
|
+
name: q.name,
|
|
2159
|
+
size: q.size
|
|
2132
2160
|
}))
|
|
2133
|
-
}),
|
|
2134
|
-
} catch (
|
|
2135
|
-
(
|
|
2161
|
+
}), f.value = "", f.style.height = "auto", x.length = 0, await e.refreshThread(d);
|
|
2162
|
+
} catch (q) {
|
|
2163
|
+
($ = r.querySelector(".msg-row.pending")) == null || $.classList.replace("pending", "failed"), n(q.message || "That could not be sent — try again.", "err");
|
|
2136
2164
|
} finally {
|
|
2137
|
-
|
|
2165
|
+
i = !1, o();
|
|
2138
2166
|
}
|
|
2139
2167
|
}
|
|
2140
2168
|
}
|
|
2141
|
-
|
|
2169
|
+
o();
|
|
2142
2170
|
}
|
|
2143
|
-
|
|
2144
|
-
function he(e) {
|
|
2171
|
+
function ke(e) {
|
|
2145
2172
|
return JSON.stringify(e ? [e.score, e.current, e.comment || null] : null);
|
|
2146
2173
|
}
|
|
2147
|
-
function
|
|
2174
|
+
function de(e, {
|
|
2175
|
+
client: t,
|
|
2176
|
+
report: r,
|
|
2177
|
+
rating: d,
|
|
2178
|
+
justRated: u = !1,
|
|
2179
|
+
question: S = null,
|
|
2180
|
+
onRated: b = null,
|
|
2181
|
+
onError: h = null
|
|
2182
|
+
}) {
|
|
2183
|
+
var i;
|
|
2184
|
+
e.dataset.key = ke(d);
|
|
2185
|
+
const f = d != null && d.current ? d.score : 0, s = d ? d.current ? u ? "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?", c = u && (d == null ? void 0 : d.current) && !d.comment;
|
|
2186
|
+
e.innerHTML = `
|
|
2187
|
+
<p class="fr-q">${v(s)}</p>
|
|
2188
|
+
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1, 2, 3, 4, 5].map((n) => `
|
|
2189
|
+
<button type="button" data-score="${n}" aria-pressed="${n === f}" aria-label="${n} out of 5${n === 1 ? ", poor" : n === 5 ? ", great" : ""}" class="${n <= f ? "on" : ""}">${me}</button>`).join("")}
|
|
2190
|
+
</div>
|
|
2191
|
+
${d != null && d.current && d.comment ? `<p class="fr-said">“${v(d.comment)}”</p>` : ""}
|
|
2192
|
+
${c ? `
|
|
2193
|
+
<div class="fr-note">
|
|
2194
|
+
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${d.score <= 2 ? "What went wrong? (optional)" : "Anything to add? (optional)"}"></textarea>
|
|
2195
|
+
<button type="button" data-act="rating-note">Add note</button>
|
|
2196
|
+
</div>` : ""}
|
|
2197
|
+
${d ? "" : '<p class="fr-hint">1 is poor, 5 is great.</p>'}
|
|
2198
|
+
<p class="feedback-status" role="status"></p>`;
|
|
2199
|
+
const L = [...e.querySelectorAll("[data-score]")], g = (n) => L.forEach((o) => o.classList.toggle("on", Number(o.dataset.score) <= n)), w = (n) => e.querySelectorAll("button, textarea").forEach((o) => {
|
|
2200
|
+
o.disabled = n;
|
|
2201
|
+
}), x = e.querySelector(".feedback-status");
|
|
2202
|
+
async function T(n, o) {
|
|
2203
|
+
var a;
|
|
2204
|
+
w(!0), x.textContent = "";
|
|
2205
|
+
try {
|
|
2206
|
+
const k = await t.rate(r.id, { score: n, comment: o });
|
|
2207
|
+
de(e, {
|
|
2208
|
+
client: t,
|
|
2209
|
+
report: r,
|
|
2210
|
+
rating: k,
|
|
2211
|
+
justRated: !0,
|
|
2212
|
+
question: S,
|
|
2213
|
+
onRated: b,
|
|
2214
|
+
onError: h
|
|
2215
|
+
}), (a = e.querySelector(".fr-note textarea")) == null || a.focus(), b == null || b(k);
|
|
2216
|
+
} catch (k) {
|
|
2217
|
+
x.textContent = k.message, w(!1), g(f), h == null || h(k);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
for (const n of L) {
|
|
2221
|
+
const o = Number(n.dataset.score);
|
|
2222
|
+
n.addEventListener("mouseenter", () => g(o)), n.addEventListener("focus", () => g(o)), n.addEventListener("blur", () => g(f)), n.addEventListener("click", () => T(o));
|
|
2223
|
+
}
|
|
2224
|
+
e.querySelector(".stars").addEventListener("mouseleave", () => g(f)), (i = e.querySelector('[data-act="rating-note"]')) == null || i.addEventListener("click", () => {
|
|
2225
|
+
var o;
|
|
2226
|
+
const n = e.querySelector(".fr-note textarea").value.trim();
|
|
2227
|
+
if (!n) {
|
|
2228
|
+
(o = e.querySelector(".fr-note")) == null || o.remove();
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
T(d.score, n);
|
|
2232
|
+
});
|
|
2233
|
+
}
|
|
2234
|
+
const se = /* @__PURE__ */ new WeakMap();
|
|
2235
|
+
function vt(e) {
|
|
2148
2236
|
return e.rating ? ` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${me}${Number(e.rating)}</span>` : e.ratingAsked ? ' · <span class="rate-ask">Rate it</span>' : "";
|
|
2149
2237
|
}
|
|
2150
|
-
function
|
|
2151
|
-
var
|
|
2238
|
+
function xt(e) {
|
|
2239
|
+
var T;
|
|
2152
2240
|
const {
|
|
2153
2241
|
client: t,
|
|
2154
|
-
scrim:
|
|
2155
|
-
close:
|
|
2242
|
+
scrim: r,
|
|
2243
|
+
close: d
|
|
2156
2244
|
} = e;
|
|
2157
|
-
let
|
|
2158
|
-
function
|
|
2159
|
-
if (
|
|
2160
|
-
|
|
2161
|
-
|
|
2245
|
+
let u = null;
|
|
2246
|
+
function S(i, { callFailed: n = null } = {}) {
|
|
2247
|
+
if (i != null && i.id && !n) {
|
|
2248
|
+
f(i.id, { fresh: !0 }).then((o) => {
|
|
2249
|
+
o || b(i, { callFailed: n });
|
|
2162
2250
|
});
|
|
2163
2251
|
return;
|
|
2164
2252
|
}
|
|
2165
|
-
|
|
2253
|
+
b(i, { callFailed: n });
|
|
2166
2254
|
}
|
|
2167
|
-
function
|
|
2168
|
-
var
|
|
2169
|
-
const
|
|
2170
|
-
|
|
2255
|
+
function b(i, { callFailed: n = null } = {}) {
|
|
2256
|
+
var y;
|
|
2257
|
+
const o = i != null && i.id ? String(i.id).slice(0, 8) : null, a = (y = i == null ? void 0 : i.estimate) != null && y.label ? String(i.estimate.label) : null, k = n ? `<p class="eta">${v(n)} Your report is filed, and the team will reply in the chat.</p>` : "";
|
|
2258
|
+
r.querySelector(".panel").innerHTML = `
|
|
2171
2259
|
<div class="done">
|
|
2172
|
-
<div class="tick">${
|
|
2260
|
+
<div class="tick">${P}</div>
|
|
2173
2261
|
<h3>Thanks — that's on its way.</h3>
|
|
2174
|
-
<p>${
|
|
2175
|
-
${
|
|
2176
|
-
${
|
|
2177
|
-
</div>`, setTimeout(
|
|
2178
|
-
}
|
|
2179
|
-
async function
|
|
2180
|
-
const
|
|
2181
|
-
clearTimeout(
|
|
2262
|
+
<p>${o ? `Filed as <code>${v(o)}</code>.` : "The team has what they need to reproduce it."}</p>
|
|
2263
|
+
${k}
|
|
2264
|
+
${a ? `<p class="eta">Reports like this usually take <strong>${v(a)}</strong>. We'll let you know when it moves.</p>` : ""}
|
|
2265
|
+
</div>`, setTimeout(d, k ? 6e3 : a ? 4e3 : 2e3);
|
|
2266
|
+
}
|
|
2267
|
+
async function h() {
|
|
2268
|
+
const i = r.querySelector(".panel");
|
|
2269
|
+
clearTimeout(s), u = null, i.classList.remove("is-chat"), i.innerHTML = `
|
|
2182
2270
|
${le({ title: "Your reports", sub: "Where each one has got to.", theme: e.themeLabel() })}
|
|
2183
|
-
<div class="history" aria-busy="true">${
|
|
2184
|
-
let
|
|
2271
|
+
<div class="history" aria-busy="true">${_e(3)}</div>`, i.querySelector('[data-act="close"]').addEventListener("click", d);
|
|
2272
|
+
let n = [];
|
|
2185
2273
|
try {
|
|
2186
|
-
({ reports:
|
|
2274
|
+
({ reports: n } = await t.myReports());
|
|
2187
2275
|
} catch {
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2276
|
+
const a = i.querySelector(".history");
|
|
2277
|
+
a && (a.innerHTML = oe("Couldn't load your reports just now.", G));
|
|
2190
2278
|
return;
|
|
2191
2279
|
}
|
|
2192
|
-
const
|
|
2193
|
-
if (
|
|
2194
|
-
|
|
2195
|
-
<button class="row" type="button" data-report="${v(
|
|
2196
|
-
<span class="row-ico" aria-hidden="true">${
|
|
2280
|
+
const o = i.querySelector(".history");
|
|
2281
|
+
if (o) {
|
|
2282
|
+
o.removeAttribute("aria-busy"), o.innerHTML = n.length ? n.map((a, k) => `
|
|
2283
|
+
<button class="row" type="button" data-report="${v(a.id)}" style="animation-delay:${Math.min(k, 8) * 30}ms">
|
|
2284
|
+
<span class="row-ico" aria-hidden="true">${Oe}</span>
|
|
2197
2285
|
<span class="who">
|
|
2198
|
-
<span class="ttl">${v(
|
|
2199
|
-
<span class="sub">${v(
|
|
2286
|
+
<span class="ttl">${v(a.title)}</span>
|
|
2287
|
+
<span class="sub">${v(a.reference)} · ${v(J(a.createdAt))}${vt(a)}</span>
|
|
2200
2288
|
</span>
|
|
2201
|
-
<span class="pill ${v(String(
|
|
2202
|
-
<span class="chev" aria-hidden="true">${
|
|
2203
|
-
</button>`).join("") :
|
|
2204
|
-
for (const
|
|
2205
|
-
|
|
2289
|
+
<span class="pill ${v(String(a.status).toLowerCase())}">${v(ie(a.status))}</span>
|
|
2290
|
+
<span class="chev" aria-hidden="true">${Fe}</span>
|
|
2291
|
+
</button>`).join("") : oe("You haven't reported anything yet.", Ke);
|
|
2292
|
+
for (const a of o.querySelectorAll("[data-report]"))
|
|
2293
|
+
a.addEventListener("click", () => f(a.dataset.report));
|
|
2206
2294
|
}
|
|
2207
2295
|
}
|
|
2208
|
-
async function
|
|
2209
|
-
var
|
|
2210
|
-
const
|
|
2211
|
-
clearTimeout(
|
|
2296
|
+
async function f(i, { fresh: n = !1 } = {}) {
|
|
2297
|
+
var l;
|
|
2298
|
+
const o = r.querySelector(".panel");
|
|
2299
|
+
clearTimeout(s), o.classList.add("is-chat"), o.innerHTML = `
|
|
2212
2300
|
${le({
|
|
2213
2301
|
back: !0,
|
|
2214
|
-
title:
|
|
2215
|
-
sub:
|
|
2302
|
+
title: n ? "Looking into it" : "Your report",
|
|
2303
|
+
sub: n ? "It may ask you a question here." : "Updates, and a way to reply.",
|
|
2216
2304
|
theme: e.themeLabel()
|
|
2217
2305
|
})}
|
|
2218
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
2219
|
-
let
|
|
2306
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${Ge()}</div></div>`, o.querySelector('[data-act="close"]').addEventListener("click", d), o.querySelector('[data-act="back"]').addEventListener("click", h);
|
|
2307
|
+
let a = null;
|
|
2220
2308
|
try {
|
|
2221
|
-
|
|
2309
|
+
a = await t.myReport(i);
|
|
2222
2310
|
} catch {
|
|
2223
|
-
|
|
2311
|
+
a = null;
|
|
2224
2312
|
}
|
|
2225
|
-
const
|
|
2226
|
-
if (!
|
|
2227
|
-
if (!
|
|
2228
|
-
return
|
|
2229
|
-
|
|
2230
|
-
const
|
|
2231
|
-
|
|
2313
|
+
const k = o.querySelector(".history");
|
|
2314
|
+
if (!k || !o.querySelector('[data-act="back"]')) return !1;
|
|
2315
|
+
if (!a)
|
|
2316
|
+
return n ? (o.classList.remove("is-chat"), !1) : (k.removeAttribute("aria-busy"), k.innerHTML = oe("Couldn't load that report just now.", G), !1);
|
|
2317
|
+
u = i, t.markReportRead(i);
|
|
2318
|
+
const y = he(a.timeline);
|
|
2319
|
+
k.classList.add("chatting"), k.removeAttribute("aria-busy"), k.innerHTML = `
|
|
2232
2320
|
<div class="report-head">
|
|
2233
|
-
<span class="ttl">${v(
|
|
2234
|
-
<span class="sub">${v(
|
|
2235
|
-
<span class="pill ${v(String(
|
|
2236
|
-
${(
|
|
2321
|
+
<span class="ttl">${v(a.title)}</span>
|
|
2322
|
+
<span class="sub">${v(a.reference)} · ${v(a.project || "")}</span>
|
|
2323
|
+
<span class="pill ${v(String(a.status).toLowerCase())}">${v(ie(a.status))}</span>
|
|
2324
|
+
${(l = a.estimate) != null && l.label ? `<span class="eta-line">Usually takes ${v(String(a.estimate.label))}</span>` : ""}
|
|
2237
2325
|
</div>
|
|
2238
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
2239
|
-
const
|
|
2240
|
-
return se.set(
|
|
2241
|
-
}
|
|
2242
|
-
let
|
|
2243
|
-
function
|
|
2244
|
-
var
|
|
2245
|
-
clearTimeout(
|
|
2246
|
-
const
|
|
2247
|
-
let
|
|
2248
|
-
if (!
|
|
2249
|
-
|
|
2326
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${y}</div>`;
|
|
2327
|
+
const m = k.querySelector(".thread");
|
|
2328
|
+
return se.set(m, y), _(m), L(k, a), g(k, a), a.canReply && mt(e, k, m, i), c(k, a, i), _(m), !0;
|
|
2329
|
+
}
|
|
2330
|
+
let s = null;
|
|
2331
|
+
function c(i, n, o) {
|
|
2332
|
+
var B, Q, C;
|
|
2333
|
+
clearTimeout(s);
|
|
2334
|
+
const a = n.assistant, k = i.querySelector(".thread");
|
|
2335
|
+
let y = i.querySelector(".assistant");
|
|
2336
|
+
if (!a) {
|
|
2337
|
+
y == null || y.remove(), (B = k == null ? void 0 : k.querySelector(".typing-row")) == null || B.remove();
|
|
2250
2338
|
return;
|
|
2251
2339
|
}
|
|
2252
|
-
const
|
|
2253
|
-
|
|
2254
|
-
const
|
|
2255
|
-
<div class="as-body${
|
|
2340
|
+
const m = (y == null ? void 0 : y.dataset.phase) || null;
|
|
2341
|
+
y || (y = document.createElement("div"), y.setAttribute("role", "status"), y.setAttribute("aria-live", "polite"), (Q = i.querySelector(".report-head")) == null || Q.after(y)), y.className = `assistant ${v(a.phase)}`, y.dataset.phase = a.phase;
|
|
2342
|
+
const l = a.steps || [], $ = l.filter((M) => M.state === "done").length, q = l.some((M) => M.state === "active") ? 0.5 : 0, H = l.length ? Math.round(($ + q) / l.length * 100) : 0, O = `
|
|
2343
|
+
<div class="as-body${m && m !== a.phase ? " entering" : ""}">
|
|
2256
2344
|
<div class="as-top">
|
|
2257
|
-
<span class="as-orb${
|
|
2345
|
+
<span class="as-orb${a.phase === "calling" || a.phase === "resolved" ? "" : " orb"}" aria-hidden="true">${a.phase === "calling" ? re : a.phase === "resolved" ? P : ""}</span>
|
|
2258
2346
|
<div class="as-text">
|
|
2259
|
-
<div class="as-title">${v(
|
|
2260
|
-
<div class="as-detail">${v(
|
|
2347
|
+
<div class="as-title">${v(a.title)}</div>
|
|
2348
|
+
<div class="as-detail">${v(a.detail)}</div>
|
|
2261
2349
|
</div>
|
|
2262
2350
|
</div>
|
|
2263
2351
|
</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
|
|
2269
|
-
|
|
2270
|
-
const
|
|
2271
|
-
|
|
2272
|
-
|
|
2352
|
+
${l.length ? `
|
|
2353
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${H}"><i style="width:${H}%"></i></div>
|
|
2354
|
+
<ol class="as-steps">${l.map((M) => `<li class="${v(M.state)}"${M.state === "active" ? ' aria-current="step"' : ""}><span class="dot"></span><span class="lbl">${v(M.label)}</span></li>`).join("")}</ol>` : ""}`, N = JSON.stringify([a.phase, a.title, a.detail, l]);
|
|
2355
|
+
if (y.dataset.key !== N) {
|
|
2356
|
+
const M = y.querySelector(".as-progress i"), D = M == null ? void 0 : M.style.width;
|
|
2357
|
+
y.innerHTML = O, y.dataset.key = N;
|
|
2358
|
+
const V = y.querySelector(".as-progress i");
|
|
2359
|
+
V && D && (V.style.width = D, requestAnimationFrame(() => {
|
|
2360
|
+
V.style.width = `${H}%`;
|
|
2273
2361
|
}));
|
|
2274
2362
|
}
|
|
2275
|
-
if (
|
|
2276
|
-
const
|
|
2277
|
-
|
|
2363
|
+
if (k) {
|
|
2364
|
+
const M = ue(k), D = k.querySelector(".typing-row");
|
|
2365
|
+
a.phase !== "analyzing" ? D == null || D.remove() : (!D || D !== k.lastElementChild) && (D == null || D.remove(), k.insertAdjacentHTML("beforeend", ft()), M && _(k));
|
|
2278
2366
|
}
|
|
2279
|
-
|
|
2280
|
-
}
|
|
2281
|
-
function L(
|
|
2282
|
-
var
|
|
2283
|
-
if ((
|
|
2284
|
-
const
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2367
|
+
a.phase === "analyzing" ? s = setTimeout(() => w(o), 3e3) : a.phase === "calling" ? s = setTimeout(() => w(o), 1e4) : a.phase === "needs_info" && m !== "needs_info" && ((C = i.querySelector(".composer textarea")) == null || C.focus());
|
|
2368
|
+
}
|
|
2369
|
+
function L(i, n) {
|
|
2370
|
+
var a, k;
|
|
2371
|
+
if ((a = i.querySelector(".fix-verification")) == null || a.remove(), !n.resolvedAt || !["RESOLVED", "CLOSED"].includes(n.status)) return;
|
|
2372
|
+
const o = document.createElement("div");
|
|
2373
|
+
o.className = "fix-verification", n.verification ? o.textContent = n.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (o.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>', o.querySelectorAll("[data-result]").forEach((y) => {
|
|
2374
|
+
y.onclick = async () => {
|
|
2375
|
+
o.querySelectorAll("button").forEach((m) => {
|
|
2376
|
+
m.disabled = !0;
|
|
2289
2377
|
});
|
|
2290
2378
|
try {
|
|
2291
|
-
await t.verifyFix(
|
|
2292
|
-
} catch (
|
|
2293
|
-
|
|
2294
|
-
|
|
2379
|
+
await t.verifyFix(n.id, { result: y.dataset.result, resolvedAt: n.resolvedAt, note: o.querySelector("textarea").value }), await f(n.id);
|
|
2380
|
+
} catch (m) {
|
|
2381
|
+
o.querySelector(".feedback-status").textContent = m.message, o.querySelectorAll("button").forEach((l) => {
|
|
2382
|
+
l.disabled = !1;
|
|
2295
2383
|
});
|
|
2296
2384
|
}
|
|
2297
2385
|
};
|
|
2298
|
-
})), (
|
|
2386
|
+
})), (k = i.querySelector(".report-head")) == null || k.after(o);
|
|
2299
2387
|
}
|
|
2300
|
-
function
|
|
2301
|
-
var
|
|
2302
|
-
let
|
|
2303
|
-
if (!["RESOLVED", "CLOSED"].includes(
|
|
2304
|
-
|
|
2388
|
+
function g(i, n) {
|
|
2389
|
+
var k;
|
|
2390
|
+
let o = i.querySelector(".fix-rating");
|
|
2391
|
+
if (!["RESOLVED", "CLOSED"].includes(n.status) || !n.ratingAsked) {
|
|
2392
|
+
o == null || o.remove();
|
|
2305
2393
|
return;
|
|
2306
2394
|
}
|
|
2307
|
-
|
|
2308
|
-
}
|
|
2309
|
-
function k(n, p, a, { justRated: s = !1 } = {}) {
|
|
2310
|
-
var N;
|
|
2311
|
-
n.dataset.key = he(a);
|
|
2312
|
-
const u = a != null && a.current ? a.score : 0, r = a ? a.current ? s ? "Thanks — the team will see that." : `You rated this ${a.score} out of 5.` : `You rated an earlier fix ${a.score} out of 5. How did this one go?` : "How did we do?", o = s && (a == null ? void 0 : a.current) && !a.comment;
|
|
2313
|
-
n.innerHTML = `
|
|
2314
|
-
<p class="fr-q">${v(r)}</p>
|
|
2315
|
-
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1, 2, 3, 4, 5].map((h) => `
|
|
2316
|
-
<button type="button" data-score="${h}" aria-pressed="${h === u}" aria-label="${h} out of 5${h === 1 ? ", poor" : h === 5 ? ", great" : ""}" class="${h <= u ? "on" : ""}">${me}</button>`).join("")}
|
|
2317
|
-
</div>
|
|
2318
|
-
${a != null && a.current && a.comment ? `<p class="fr-said">“${v(a.comment)}”</p>` : ""}
|
|
2319
|
-
${o ? `
|
|
2320
|
-
<div class="fr-note">
|
|
2321
|
-
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${a.score <= 2 ? "What went wrong? (optional)" : "Anything to add? (optional)"}"></textarea>
|
|
2322
|
-
<button type="button" data-act="rating-note">Add note</button>
|
|
2323
|
-
</div>` : ""}
|
|
2324
|
-
${a ? "" : '<p class="fr-hint">1 is poor, 5 is great.</p>'}
|
|
2325
|
-
<p class="feedback-status" role="status"></p>`;
|
|
2326
|
-
const f = [...n.querySelectorAll("[data-score]")], $ = (h) => f.forEach((z) => z.classList.toggle("on", Number(z.dataset.score) <= h)), A = (h) => n.querySelectorAll("button, textarea").forEach((z) => {
|
|
2327
|
-
z.disabled = h;
|
|
2328
|
-
}), j = n.querySelector(".feedback-status");
|
|
2329
|
-
async function B(h, z) {
|
|
2330
|
-
var R;
|
|
2331
|
-
A(!0), j.textContent = "";
|
|
2332
|
-
try {
|
|
2333
|
-
const H = await t.rate(p.id, { score: h, comment: z });
|
|
2334
|
-
k(n, p, H, { justRated: !0 }), (R = n.querySelector(".fr-note textarea")) == null || R.focus();
|
|
2335
|
-
} catch (H) {
|
|
2336
|
-
j.textContent = H.message, A(!1), $(u);
|
|
2337
|
-
}
|
|
2338
|
-
}
|
|
2339
|
-
for (const h of f) {
|
|
2340
|
-
const z = Number(h.dataset.score);
|
|
2341
|
-
h.addEventListener("mouseenter", () => $(z)), h.addEventListener("focus", () => $(z)), h.addEventListener("blur", () => $(u)), h.addEventListener("click", () => B(z));
|
|
2342
|
-
}
|
|
2343
|
-
n.querySelector(".stars").addEventListener("mouseleave", () => $(u)), (N = n.querySelector('[data-act="rating-note"]')) == null || N.addEventListener("click", () => {
|
|
2344
|
-
var z;
|
|
2345
|
-
const h = n.querySelector(".fr-note textarea").value.trim();
|
|
2346
|
-
if (!h) {
|
|
2347
|
-
(z = n.querySelector(".fr-note")) == null || z.remove();
|
|
2348
|
-
return;
|
|
2349
|
-
}
|
|
2350
|
-
B(a.score, h);
|
|
2351
|
-
});
|
|
2395
|
+
o && o.dataset.key === ke(n.rating) || (o || (o = document.createElement("div"), o.className = "fix-rating", (k = i.querySelector(".fix-verification") || i.querySelector(".report-head")) == null || k.after(o)), de(o, { client: t, report: n, rating: n.rating || null }));
|
|
2352
2396
|
}
|
|
2353
|
-
async function
|
|
2354
|
-
const
|
|
2355
|
-
if (!
|
|
2356
|
-
let
|
|
2397
|
+
async function w(i) {
|
|
2398
|
+
const n = r.querySelector(".history.chatting"), o = n == null ? void 0 : n.querySelector(".thread");
|
|
2399
|
+
if (!o || u !== i) return;
|
|
2400
|
+
let a = null;
|
|
2357
2401
|
try {
|
|
2358
|
-
|
|
2402
|
+
a = await t.myReport(i);
|
|
2359
2403
|
} catch {
|
|
2360
2404
|
}
|
|
2361
|
-
if (e.closed || !
|
|
2362
|
-
L(
|
|
2363
|
-
const
|
|
2364
|
-
se.get(
|
|
2365
|
-
const
|
|
2366
|
-
|
|
2367
|
-
}
|
|
2368
|
-
const
|
|
2369
|
-
!
|
|
2405
|
+
if (e.closed || !a || u !== i) return;
|
|
2406
|
+
L(n, a), g(n, a);
|
|
2407
|
+
const k = ue(o), y = he(a.timeline);
|
|
2408
|
+
se.get(o) !== y && (o.innerHTML = y, se.set(o, y)), c(n, a, i), k && _(o);
|
|
2409
|
+
const m = n.querySelector(".report-head .pill");
|
|
2410
|
+
m && (m.className = `pill ${String(a.status).toLowerCase()}`, m.textContent = ie(a.status));
|
|
2411
|
+
}
|
|
2412
|
+
const x = t.on("update", (i) => {
|
|
2413
|
+
!u || (i == null ? void 0 : i.bugId) !== u || (t.markReportRead(u), w(u));
|
|
2370
2414
|
});
|
|
2371
2415
|
e.onDestroy(() => {
|
|
2372
|
-
|
|
2373
|
-
}), (
|
|
2416
|
+
x(), clearTimeout(s);
|
|
2417
|
+
}), (T = r.querySelector('[data-act="history"]')) == null || T.addEventListener("click", h), e.succeed = S, e.refreshThread = w, e.openReportId = () => u;
|
|
2418
|
+
}
|
|
2419
|
+
const $e = "bugcatch.rateLater", yt = 50;
|
|
2420
|
+
function Se() {
|
|
2421
|
+
try {
|
|
2422
|
+
const e = JSON.parse(window.localStorage.getItem($e) || "[]");
|
|
2423
|
+
return Array.isArray(e) ? e : [];
|
|
2424
|
+
} catch {
|
|
2425
|
+
return [];
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
function wt(e) {
|
|
2429
|
+
try {
|
|
2430
|
+
const t = Se().filter((r) => r !== e);
|
|
2431
|
+
t.push(e), window.localStorage.setItem($e, JSON.stringify(t.slice(-yt)));
|
|
2432
|
+
} catch {
|
|
2433
|
+
}
|
|
2374
2434
|
}
|
|
2375
|
-
function
|
|
2435
|
+
function kt(e, t = Se()) {
|
|
2436
|
+
const r = new Set(t), d = (e || []).filter((S) => S.ratingDue === "require" || S.ratingDue === "ask" && !r.has(S.id));
|
|
2437
|
+
if (!d.length) return null;
|
|
2438
|
+
const u = (S) => new Date(S.resolvedAt || S.updatedAt || 0).getTime() || 0;
|
|
2439
|
+
return d.reduce((S, b) => u(b) > u(S) ? b : S);
|
|
2440
|
+
}
|
|
2441
|
+
function $t(e) {
|
|
2442
|
+
const {
|
|
2443
|
+
client: t,
|
|
2444
|
+
rateDue: r,
|
|
2445
|
+
compose: d,
|
|
2446
|
+
picks: u,
|
|
2447
|
+
known: S,
|
|
2448
|
+
callBtn: b,
|
|
2449
|
+
titleInput: h,
|
|
2450
|
+
scrim: f
|
|
2451
|
+
} = e;
|
|
2452
|
+
let s = !1;
|
|
2453
|
+
e.mustRate = () => s;
|
|
2454
|
+
function c(x) {
|
|
2455
|
+
s = x;
|
|
2456
|
+
for (const T of [d, u, S])
|
|
2457
|
+
T.classList.toggle("held", x), T.inert = x;
|
|
2458
|
+
x ? b.hidden = !0 : e.callOffered() && !e.mustSignIn() && (b.hidden = !1), e.refreshSendState();
|
|
2459
|
+
}
|
|
2460
|
+
function L() {
|
|
2461
|
+
s && c(!1);
|
|
2462
|
+
}
|
|
2463
|
+
function g() {
|
|
2464
|
+
r.hidden = !0, r.replaceChildren(), L(), h.focus();
|
|
2465
|
+
}
|
|
2466
|
+
function w(x) {
|
|
2467
|
+
var o;
|
|
2468
|
+
const T = x.ratingDue === "require", i = x.resolvedAt ? J(x.resolvedAt) : "", n = x.status === "CLOSED" ? "closed" : "fixed";
|
|
2469
|
+
if (r.hidden = !1, r.classList.toggle("is-required", T), r.innerHTML = `
|
|
2470
|
+
<div class="rd-head">
|
|
2471
|
+
<span class="rd-eyebrow">${T ? "Before you report something new" : `Your report was ${n}`}</span>
|
|
2472
|
+
${T ? "" : '<button type="button" class="link rd-later" data-act="rate-later">Not now</button>'}
|
|
2473
|
+
</div>
|
|
2474
|
+
<p class="rd-report">
|
|
2475
|
+
<span class="rd-ico" aria-hidden="true">${P}</span>
|
|
2476
|
+
<span class="rd-ttl">${v(x.title)}</span>
|
|
2477
|
+
<span class="rd-sub">${v(x.reference)}${i ? ` · ${n} ${v(i)}` : ""}</span>
|
|
2478
|
+
</p>
|
|
2479
|
+
<div class="rd-stars"></div>`, (o = r.querySelector('[data-act="rate-later"]')) == null || o.addEventListener("click", () => {
|
|
2480
|
+
wt(x.id), g();
|
|
2481
|
+
}), de(r.querySelector(".rd-stars"), {
|
|
2482
|
+
client: t,
|
|
2483
|
+
report: x,
|
|
2484
|
+
rating: null,
|
|
2485
|
+
question: T ? "How did we handle it? Rate it to send a new one." : "How did we do?",
|
|
2486
|
+
onRated: () => {
|
|
2487
|
+
var a;
|
|
2488
|
+
r.querySelector(".rd-eyebrow").textContent = `Your report was ${n}`, (a = r.querySelector('[data-act="skip"]')) == null || a.remove(), r.classList.remove("is-required"), L();
|
|
2489
|
+
},
|
|
2490
|
+
// The rating could not be sent. A held form must not turn into a locked
|
|
2491
|
+
// door because of our outage: offer the way past.
|
|
2492
|
+
onError: () => {
|
|
2493
|
+
if (!s || r.querySelector('[data-act="skip"]')) return;
|
|
2494
|
+
const a = document.createElement("button");
|
|
2495
|
+
a.type = "button", a.className = "link rd-later", a.dataset.act = "skip", a.textContent = "Skip for now", a.addEventListener("click", g), r.querySelector(".rd-head").append(a);
|
|
2496
|
+
}
|
|
2497
|
+
}), T) {
|
|
2498
|
+
c(!0);
|
|
2499
|
+
const a = f.getRootNode().activeElement;
|
|
2500
|
+
(!a || !r.contains(a)) && r.focus();
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
t.hasReports() && t.myReports().then(({ reports: x }) => {
|
|
2504
|
+
if (e.closed) return;
|
|
2505
|
+
const T = kt(x);
|
|
2506
|
+
T && w(T);
|
|
2507
|
+
}).catch(() => {
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2510
|
+
function Qt({
|
|
2376
2511
|
root: e,
|
|
2377
2512
|
host: t,
|
|
2378
|
-
dock:
|
|
2379
|
-
client:
|
|
2380
|
-
onClose:
|
|
2381
|
-
preloadCall:
|
|
2513
|
+
dock: r,
|
|
2514
|
+
client: d,
|
|
2515
|
+
onClose: u,
|
|
2516
|
+
preloadCall: S = () => {
|
|
2382
2517
|
},
|
|
2383
|
-
themeControls:
|
|
2518
|
+
themeControls: b = null
|
|
2384
2519
|
}) {
|
|
2385
|
-
|
|
2386
|
-
const
|
|
2387
|
-
|
|
2520
|
+
St(e);
|
|
2521
|
+
const h = d.config, f = () => (b == null ? void 0 : b.label()) || "", s = document.createElement("div");
|
|
2522
|
+
s.className = `scrim ${r.classList.contains("at-left") ? "at-left" : "at-right"} ${r.classList.contains("at-top") ? "at-top" : "at-bottom"}`, s.style.setProperty("--bc-dock-h", `${Math.round(r.getBoundingClientRect().height)}px`), s.innerHTML = `
|
|
2388
2523
|
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
|
|
2389
2524
|
${le({
|
|
2390
2525
|
id: "bc-h",
|
|
@@ -2392,10 +2527,13 @@ function xt({
|
|
|
2392
2527
|
// a few pixels below. The header names the errand the launcher named.
|
|
2393
2528
|
title: "Report a bug",
|
|
2394
2529
|
sub: "We attach the page details for you.",
|
|
2395
|
-
theme:
|
|
2530
|
+
theme: f()
|
|
2396
2531
|
})}
|
|
2397
2532
|
<div class="body">
|
|
2398
2533
|
<div class="slot" role="alert"></div>
|
|
2534
|
+
<!-- A settled report still waiting for its rating. Drawn only when the
|
|
2535
|
+
project asks for one here; see rate-due.js. -->
|
|
2536
|
+
<div class="rate-due fix-rating" tabindex="-1" hidden></div>
|
|
2399
2537
|
<!-- What the project's team is telling visitors. Drawn only when it
|
|
2400
2538
|
has published something. -->
|
|
2401
2539
|
<div class="notices" hidden></div>
|
|
@@ -2404,52 +2542,53 @@ function xt({
|
|
|
2404
2542
|
close by itself. Drawn only when the project offers any. -->
|
|
2405
2543
|
<div class="picks" hidden></div>
|
|
2406
2544
|
<div class="known" hidden></div>
|
|
2407
|
-
${
|
|
2545
|
+
${nt(h)}
|
|
2408
2546
|
</div>
|
|
2409
2547
|
<div class="foot">
|
|
2410
2548
|
<span class="note" aria-live="polite"></span>
|
|
2411
|
-
${
|
|
2549
|
+
${d.hasReports() ? '<button class="quiet" type="button" data-act="history">Your reports</button>' : ""}
|
|
2412
2550
|
<span class="spacer"></span>
|
|
2413
2551
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
2414
2552
|
most cannot. Drawn here rather than as a second launcher because it
|
|
2415
2553
|
is the same errand as Send report — the difference is only whether
|
|
2416
2554
|
the reporter would rather say it than type it. -->
|
|
2417
|
-
<button class="ghost" type="button" data-act="call" hidden>${
|
|
2555
|
+
<button class="ghost" type="button" data-act="call" hidden>${re}Talk to the team</button>
|
|
2418
2556
|
<button class="primary" type="button" data-act="send">Send report ${ge}</button>
|
|
2419
2557
|
</div>
|
|
2420
2558
|
<div class="powered">Powered by
|
|
2421
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
2559
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Ue}</a>
|
|
2422
2560
|
</div>
|
|
2423
2561
|
</div>`;
|
|
2424
|
-
const
|
|
2425
|
-
client:
|
|
2426
|
-
cfg:
|
|
2562
|
+
const c = (y) => s.querySelector(y), L = c(".slot"), g = [], w = {
|
|
2563
|
+
client: d,
|
|
2564
|
+
cfg: h,
|
|
2427
2565
|
root: e,
|
|
2428
2566
|
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:
|
|
2567
|
+
dock: r,
|
|
2568
|
+
scrim: s,
|
|
2569
|
+
$: c,
|
|
2570
|
+
titleInput: c("#bc-title"),
|
|
2571
|
+
descInput: c("#bc-desc"),
|
|
2572
|
+
compose: c(".compose"),
|
|
2573
|
+
sendBtn: c('[data-act="send"]'),
|
|
2574
|
+
callBtn: c('[data-act="call"]'),
|
|
2575
|
+
historyBtn: c('[data-act="history"]'),
|
|
2576
|
+
note: c(".foot .note"),
|
|
2577
|
+
whoami: c(".whoami"),
|
|
2578
|
+
refsBox: c(".refs"),
|
|
2579
|
+
notices: c(".notices"),
|
|
2580
|
+
known: c(".known"),
|
|
2581
|
+
picks: c(".picks"),
|
|
2582
|
+
rateDue: c(".rate-due"),
|
|
2444
2583
|
// A report or a call is on its way. Escape and a click outside wait for it.
|
|
2445
2584
|
sending: !1,
|
|
2446
2585
|
closed: !1,
|
|
2447
|
-
say:
|
|
2448
|
-
close:
|
|
2449
|
-
preloadCall:
|
|
2450
|
-
themeLabel:
|
|
2451
|
-
onDestroy: (
|
|
2452
|
-
|
|
2586
|
+
say: k,
|
|
2587
|
+
close: o,
|
|
2588
|
+
preloadCall: S,
|
|
2589
|
+
themeLabel: f,
|
|
2590
|
+
onDestroy: (y) => {
|
|
2591
|
+
g.push(y);
|
|
2453
2592
|
},
|
|
2454
2593
|
// compose.js
|
|
2455
2594
|
refreshSendState: null,
|
|
@@ -2467,65 +2606,67 @@ function xt({
|
|
|
2467
2606
|
// signin.js
|
|
2468
2607
|
mustSignIn: null,
|
|
2469
2608
|
recheckSignIn: null,
|
|
2609
|
+
// rate-due.js
|
|
2610
|
+
mustRate: () => !1,
|
|
2470
2611
|
// thread.js
|
|
2471
2612
|
succeed: null,
|
|
2472
2613
|
refreshThread: null,
|
|
2473
2614
|
openReportId: null
|
|
2474
2615
|
};
|
|
2475
|
-
|
|
2476
|
-
const
|
|
2477
|
-
|
|
2616
|
+
ot(w), it(w), lt(w), ct(w), dt(w), pt(w), ut(w), xt(w), $t(w);
|
|
2617
|
+
const x = document.activeElement, T = document.documentElement.style, i = T.overflow;
|
|
2618
|
+
T.overflow = "hidden";
|
|
2478
2619
|
function n() {
|
|
2479
|
-
|
|
2620
|
+
w.closed || (g.forEach((y) => y()), w.closed = !0, T.overflow = i, document.removeEventListener("keydown", a, !0), s.remove(), r.hidden = !1, t.style.opacity = "", u == null || u());
|
|
2480
2621
|
}
|
|
2481
|
-
function
|
|
2482
|
-
var
|
|
2483
|
-
if (!
|
|
2484
|
-
|
|
2622
|
+
function o() {
|
|
2623
|
+
var y;
|
|
2624
|
+
if (!w.closed) {
|
|
2625
|
+
s.classList.add("closing"), setTimeout(n, 160);
|
|
2485
2626
|
try {
|
|
2486
|
-
(
|
|
2627
|
+
(y = x == null ? void 0 : x.focus) == null || y.call(x);
|
|
2487
2628
|
} catch {
|
|
2488
2629
|
}
|
|
2489
2630
|
}
|
|
2490
2631
|
}
|
|
2491
|
-
function a(
|
|
2492
|
-
if (
|
|
2493
|
-
if (
|
|
2494
|
-
|
|
2632
|
+
function a(y) {
|
|
2633
|
+
if (y.key === "Escape") {
|
|
2634
|
+
if (y.stopPropagation(), w.isRecording()) {
|
|
2635
|
+
w.stopRecording({ keep: !1 });
|
|
2495
2636
|
return;
|
|
2496
2637
|
}
|
|
2497
|
-
|
|
2638
|
+
w.sending || o();
|
|
2498
2639
|
return;
|
|
2499
2640
|
}
|
|
2500
|
-
if (
|
|
2501
|
-
const
|
|
2641
|
+
if (y.key !== "Tab" || w.isRecording()) return;
|
|
2642
|
+
const m = [...s.querySelectorAll(
|
|
2502
2643
|
"button:not(:disabled), input:not([hidden]), textarea, select, [href]"
|
|
2503
|
-
)].filter((
|
|
2504
|
-
if (!
|
|
2505
|
-
const
|
|
2506
|
-
|
|
2507
|
-
}
|
|
2508
|
-
document.addEventListener("keydown", a, !0),
|
|
2509
|
-
|
|
2510
|
-
}),
|
|
2511
|
-
const
|
|
2512
|
-
if (!
|
|
2513
|
-
const
|
|
2514
|
-
|
|
2644
|
+
)].filter((H) => H.offsetParent !== null || H === document.activeElement);
|
|
2645
|
+
if (!m.length) return;
|
|
2646
|
+
const l = m[0], $ = m[m.length - 1], q = s.getRootNode().activeElement;
|
|
2647
|
+
y.shiftKey && q === l ? (y.preventDefault(), $.focus()) : !y.shiftKey && q === $ && (y.preventDefault(), l.focus());
|
|
2648
|
+
}
|
|
2649
|
+
document.addEventListener("keydown", a, !0), s.addEventListener("click", (y) => {
|
|
2650
|
+
y.target === s && !w.sending && o();
|
|
2651
|
+
}), c('[data-act="close"]').addEventListener("click", o), s.addEventListener("click", (y) => {
|
|
2652
|
+
const m = y.target.closest('[data-act="theme"]');
|
|
2653
|
+
if (!m || !b) return;
|
|
2654
|
+
const l = b.cycle();
|
|
2655
|
+
m.title = `Theme: ${l.label}`, m.setAttribute("aria-label", `Theme: ${l.label}. Change theme`);
|
|
2515
2656
|
});
|
|
2516
|
-
function
|
|
2517
|
-
L.innerHTML =
|
|
2657
|
+
function k(y, m = "err") {
|
|
2658
|
+
L.innerHTML = y ? `<div class="msg ${m}">${m === "err" ? G : ""}<span>${v(y)}</span></div>` : "";
|
|
2518
2659
|
}
|
|
2519
|
-
return e.appendChild(
|
|
2660
|
+
return e.appendChild(s), w.refreshSendState(), w.titleInput.focus(), { destroy: n, close: o };
|
|
2520
2661
|
}
|
|
2521
|
-
function
|
|
2662
|
+
function St(e) {
|
|
2522
2663
|
if (e.querySelector("style[data-panel]")) return;
|
|
2523
2664
|
const t = document.createElement("style");
|
|
2524
|
-
t.setAttribute("data-panel", ""), t.textContent =
|
|
2525
|
-
const
|
|
2526
|
-
|
|
2665
|
+
t.setAttribute("data-panel", ""), t.textContent = Ze;
|
|
2666
|
+
const r = e.querySelector("style");
|
|
2667
|
+
r ? r.after(t) : e.prepend(t);
|
|
2527
2668
|
}
|
|
2528
2669
|
export {
|
|
2529
|
-
|
|
2670
|
+
Qt as openPanel
|
|
2530
2671
|
};
|
|
2531
2672
|
//# sourceMappingURL=bugcatch-panel.es.js.map
|