@sphoro/bugcatch-web-sdk 0.18.0 → 0.19.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 +36 -3
- package/dist/bugcatch-call.es.js +201 -200
- package/dist/bugcatch-call.es.js.map +1 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-call.umd.js.map +1 -1
- package/dist/bugcatch-core.es.js +1085 -1007
- package/dist/bugcatch-core.es.js.map +1 -1
- package/dist/bugcatch-panel.es.js +1179 -1050
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +397 -326
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +520 -437
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +132 -120
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/accent.js +38 -0
- package/src/incoming-call.js +17 -15
- package/src/index.d.ts +43 -2
- package/src/index.js +26 -7
- package/src/panel/icons.js +2 -0
- package/src/panel/index.js +17 -3
- package/src/panel/messages.js +2 -2
- package/src/panel/picks.js +6 -2
- package/src/panel/refs.js +1 -1
- package/src/panel/render.js +11 -3
- package/src/panel/styles.js +242 -186
- package/src/panel/thread.js +117 -7
- package/src/updates.js +77 -27
- package/src/widget.js +160 -141
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const Ie = '<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>', Ae = '<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>', Re = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', Ve = '<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>', ne = '<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>', De = '<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>', X = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.5c.5 4.6 2.9 7 7.5 7.5v.1c-4.6.5-7 2.9-7.5 7.5h-.1c-.5-4.6-2.9-7-7.5-7.5V10c4.6-.5 7-2.9 7.5-7.5z"/><path d="M18.6 15.2c.2 1.9 1.2 2.9 3.1 3.1v.1c-1.9.2-2.9 1.2-3.1 3.1h-.1c-.2-1.9-1.2-2.9-3.1-3.1v-.1c1.9-.2 2.9-1.2 3.1-3.1z" opacity=".7"/></svg>', je = '<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>', Oe = '<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>', Be = '<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>', Ne = `
|
|
1
|
+
import { s as ke, m as $e, a as Se, c as ce, b as Le, d as Qe, R as be, h as P, n as Te, e as Ee, f as qe, g as ee, i as G, j as F, r as ze, v as Me, k as Ce, S as He, U as Ae, l as Ie, o as Re, p as De } from "./bugcatch-core.es.js";
|
|
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 = `
|
|
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 } }
|
|
@@ -15,9 +15,12 @@ const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-wi
|
|
|
15
15
|
@keyframes bc-shimmer { from { background-position: 200% 0 } to { background-position: -200% 0 } }
|
|
16
16
|
|
|
17
17
|
/* ---------- scrim + panel ---------- */
|
|
18
|
+
/* Still modal — focus stays in the panel and a click outside closes it — but
|
|
19
|
+
the host's page only dims enough to say so. It is their product, and the
|
|
20
|
+
visitor is reporting something about what is on it. */
|
|
18
21
|
.scrim {
|
|
19
22
|
position: fixed; inset: 0; z-index: 2147483001;
|
|
20
|
-
background: rgba(
|
|
23
|
+
background: rgba(14,14,16,.14);
|
|
21
24
|
animation: bc-fade-in 200ms ease both;
|
|
22
25
|
}
|
|
23
26
|
.scrim.closing { animation: bc-fade-out 170ms ease both; }
|
|
@@ -29,12 +32,11 @@ const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-wi
|
|
|
29
32
|
.panel {
|
|
30
33
|
position: fixed;
|
|
31
34
|
display: flex; flex-direction: column;
|
|
32
|
-
width: calc(100vw - 40px); max-width:
|
|
35
|
+
width: calc(100vw - 40px); max-width: 400px;
|
|
33
36
|
max-height: calc(100vh - var(--bc-dock-h, 84px) - 52px);
|
|
34
37
|
overflow: hidden;
|
|
35
38
|
background: var(--bc-bg); color: var(--bc-fg);
|
|
36
39
|
border-radius: var(--bc-r-xl); box-shadow: var(--bc-shadow);
|
|
37
|
-
border: 1px solid color-mix(in srgb, var(--bc-border) 70%, transparent);
|
|
38
40
|
animation: bc-panel-in 340ms var(--bc-ease) both;
|
|
39
41
|
}
|
|
40
42
|
/* A conversation wants a height of its own, so the thread fills the panel
|
|
@@ -49,57 +51,58 @@ const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-wi
|
|
|
49
51
|
/* ---------- header ---------- */
|
|
50
52
|
.head {
|
|
51
53
|
flex: none; position: relative;
|
|
52
|
-
display: flex; align-items: center; gap:
|
|
53
|
-
padding:
|
|
54
|
-
background:
|
|
54
|
+
display: flex; align-items: center; gap: 11px;
|
|
55
|
+
padding: 14px 10px 13px var(--bc-pad);
|
|
56
|
+
background: var(--bc-bg);
|
|
55
57
|
border-bottom: 1px solid var(--bc-border);
|
|
56
58
|
}
|
|
57
|
-
.head .mark
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
|
|
61
|
-
color: var(--bc-on-accent); font-size: 19px;
|
|
62
|
-
box-shadow: 0 4px 12px color-mix(in srgb, var(--bc-accent) 30%, transparent);
|
|
63
|
-
}
|
|
64
|
-
/* The little "online" dot says someone — or something — is on the other end. */
|
|
65
|
-
.head .mark::after {
|
|
66
|
-
content: ''; position: absolute; right: -1px; bottom: -1px;
|
|
67
|
-
width: 11px; height: 11px; border-radius: 50%;
|
|
68
|
-
background: #22c55e; border: 2px solid var(--bc-bg);
|
|
69
|
-
}
|
|
59
|
+
.head .mark { width: 32px; }
|
|
60
|
+
/* The assistant asking its one follow-up wears the same orb, smaller. */
|
|
61
|
+
.avatar.orb { width: 26px; }
|
|
70
62
|
.head .titles { flex: 1; min-width: 0; }
|
|
71
63
|
.head h2 {
|
|
72
|
-
margin: 0 0
|
|
64
|
+
margin: 0 0 1px; font-size: var(--bc-fs-lg); font-weight: 600; letter-spacing: -.015em; line-height: 1.3;
|
|
65
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
66
|
+
}
|
|
67
|
+
.head p {
|
|
68
|
+
margin: 0; font-size: var(--bc-fs-sm); line-height: 1.4; color: var(--bc-muted);
|
|
73
69
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
74
70
|
}
|
|
75
|
-
.head p { margin: 0; font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted); }
|
|
76
71
|
.icon-btn {
|
|
77
72
|
flex: none; display: grid; place-items: center;
|
|
78
73
|
width: 32px; height: 32px; padding: 0; font-size: 16px;
|
|
79
|
-
border: none; border-radius:
|
|
74
|
+
border: none; border-radius: 999px; background: none; color: var(--bc-muted);
|
|
80
75
|
cursor: pointer; transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
81
76
|
}
|
|
82
77
|
.icon-btn:hover { background: color-mix(in srgb, var(--bc-fg) 7%, transparent); color: var(--bc-fg); }
|
|
83
78
|
.icon-btn:active { transform: scale(.92); }
|
|
84
79
|
.icon-btn.back { margin: 0 -6px 0 -8px; }
|
|
80
|
+
/* The theme button holds all three glyphs; the host's class picks one. */
|
|
81
|
+
.icon-btn.theme { font-size: 15px; margin-right: -4px; }
|
|
82
|
+
.icon-btn.theme > span { display: none; }
|
|
83
|
+
:host(.bc-light) .icon-btn.theme .m-light,
|
|
84
|
+
:host(.bc-dark) .icon-btn.theme .m-dark,
|
|
85
|
+
:host(.bc-auto) .icon-btn.theme .m-auto { display: block; }
|
|
85
86
|
|
|
86
87
|
.body {
|
|
87
88
|
flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
|
|
88
|
-
padding:
|
|
89
|
+
padding: 14px var(--bc-pad) 4px;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
label { display: block; font-size:
|
|
92
|
+
label { display: block; font-size: 13px; font-weight: 560; color: var(--bc-fg); margin-bottom: 6px; letter-spacing: -.005em; }
|
|
92
93
|
label .opt { font-weight: 450; color: var(--bc-faint); }
|
|
94
|
+
/* Fields are stone wells that turn white when you are in them, the way the
|
|
95
|
+
rest of the product's forms do. */
|
|
93
96
|
input[type=text], input[type=email], textarea {
|
|
94
|
-
width: 100%; padding:
|
|
95
|
-
color: var(--bc-fg); background: var(--bc-
|
|
96
|
-
border: 1px solid
|
|
97
|
+
width: 100%; padding: 10px 12px; font-size: var(--bc-fs-md); line-height: 1.45;
|
|
98
|
+
color: var(--bc-fg); background: var(--bc-stone);
|
|
99
|
+
border: 1px solid transparent; border-radius: var(--bc-r-md);
|
|
97
100
|
transition: border-color 160ms, box-shadow 160ms, background 160ms;
|
|
98
101
|
}
|
|
99
102
|
input[type=text]::placeholder, input[type=email]::placeholder, textarea::placeholder { color: var(--bc-faint); }
|
|
100
|
-
input[type=text]:hover, input[type=email]:hover, textarea:hover { border-color:
|
|
103
|
+
input[type=text]:hover, input[type=email]:hover, textarea:hover { border-color: var(--bc-border); }
|
|
101
104
|
input[type=text]:focus, input[type=email]:focus, textarea:focus {
|
|
102
|
-
outline: none; border-color: var(--bc-accent); box-shadow: var(--bc-ring);
|
|
105
|
+
outline: none; background: var(--bc-bg); border-color: var(--bc-accent); box-shadow: var(--bc-ring);
|
|
103
106
|
}
|
|
104
107
|
input.invalid, input.invalid:focus, textarea.invalid {
|
|
105
108
|
border-color: var(--bc-danger); animation: bc-nudge 240ms ease;
|
|
@@ -111,8 +114,8 @@ input.invalid, input.invalid:focus, textarea.invalid {
|
|
|
111
114
|
animation: bc-rise 200ms var(--bc-ease) both;
|
|
112
115
|
}
|
|
113
116
|
.field-err svg { font-size: 13px; flex: none; }
|
|
114
|
-
textarea { min-height:
|
|
115
|
-
.field { margin-bottom:
|
|
117
|
+
textarea { min-height: 76px; resize: vertical; }
|
|
118
|
+
.field { margin-bottom: 14px; }
|
|
116
119
|
.field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
|
|
117
120
|
.field-head .count { font-size: var(--bc-fs-xs); color: var(--bc-faint); font-variant-numeric: tabular-nums; }
|
|
118
121
|
|
|
@@ -122,15 +125,15 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
122
125
|
.compose > .note:has(button) {
|
|
123
126
|
display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
|
|
124
127
|
margin: 0 0 14px; padding: 10px 12px; border-radius: var(--bc-r-md);
|
|
125
|
-
background: var(--bc-
|
|
128
|
+
background: var(--bc-subtle); border: 1px solid var(--bc-border);
|
|
126
129
|
font-size: var(--bc-fs-sm); color: var(--bc-fg);
|
|
127
130
|
}
|
|
128
131
|
.compose > .note button {
|
|
129
|
-
padding: 5px 11px; font: inherit; font-size: var(--bc-fs-xs); font-weight:
|
|
132
|
+
padding: 5px 11px; font: inherit; font-size: var(--bc-fs-xs); font-weight: 600;
|
|
130
133
|
border-radius: 999px; cursor: pointer;
|
|
131
134
|
border: 1px solid var(--bc-accent); background: var(--bc-accent); color: var(--bc-on-accent);
|
|
132
135
|
}
|
|
133
|
-
.compose > .note button[data-discard] { background:
|
|
136
|
+
.compose > .note button[data-discard] { background: var(--bc-bg); color: var(--bc-fg); border-color: var(--bc-border); }
|
|
134
137
|
|
|
135
138
|
/* ---------- what is already known ----------
|
|
136
139
|
A help surface in front of the form, not a step in it. Everything here is
|
|
@@ -138,58 +141,57 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
138
141
|
leave, tap "this is happening to me too" and leave, or type straight past all
|
|
139
142
|
of it and file the report they came to file. Nothing is ever in their way,
|
|
140
143
|
because a reporter who feels handled rather than helped stops reporting. */
|
|
141
|
-
|
|
142
|
-
.known .known-h {
|
|
143
|
-
margin: 0 0
|
|
144
|
+
/* One small eyebrow style for every group above the form. */
|
|
145
|
+
.known .known-h, .picks .picks-h {
|
|
146
|
+
margin: 0 0 7px; font-size: 11px; font-weight: 600; letter-spacing: .07em;
|
|
144
147
|
text-transform: uppercase; color: var(--bc-faint);
|
|
145
148
|
}
|
|
149
|
+
.known { margin-bottom: 14px; }
|
|
150
|
+
/* Hairline rows on the panel's own white, so they read as a list to scan
|
|
151
|
+
rather than more coloured cards to wade through. */
|
|
146
152
|
.known .issue {
|
|
147
153
|
display: flex; align-items: center; gap: 10px;
|
|
148
|
-
padding:
|
|
149
|
-
background: var(--bc-
|
|
154
|
+
padding: 8px 8px 8px 12px; margin-bottom: 6px;
|
|
155
|
+
background: var(--bc-bg); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
|
|
150
156
|
animation: bc-rise 240ms var(--bc-ease) both;
|
|
151
157
|
}
|
|
152
|
-
.known .issue.is-joined {
|
|
158
|
+
.known .issue.is-joined { background: color-mix(in srgb, var(--bc-ok) 6%, var(--bc-bg)); }
|
|
153
159
|
.known .issue .who { flex: 1; min-width: 0; }
|
|
154
160
|
.known .issue .t {
|
|
155
|
-
display: block; font-size: 13px; font-weight:
|
|
161
|
+
display: block; font-size: 13px; font-weight: 560; line-height: 1.4;
|
|
156
162
|
color: var(--bc-fg); overflow-wrap: anywhere;
|
|
157
163
|
}
|
|
158
164
|
.known .issue .meta {
|
|
159
|
-
display: block; margin-top:
|
|
165
|
+
display: block; margin-top: 2px; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted);
|
|
160
166
|
}
|
|
161
167
|
.known .issue .join {
|
|
162
|
-
flex: none; padding:
|
|
163
|
-
color: var(--bc-
|
|
164
|
-
border:
|
|
165
|
-
transition: background 160ms,
|
|
168
|
+
flex: none; height: 30px; padding: 0 12px; font: inherit; font-size: 12px; font-weight: 560;
|
|
169
|
+
color: var(--bc-fg); background: var(--bc-stone);
|
|
170
|
+
border: 0; border-radius: 999px; cursor: pointer;
|
|
171
|
+
transition: background 160ms, color 160ms;
|
|
166
172
|
}
|
|
167
|
-
.known .issue .join:hover {
|
|
168
|
-
.known .issue .join:disabled { color: var(--bc-ok);
|
|
173
|
+
.known .issue .join:hover { background: color-mix(in srgb, var(--bc-fg) 12%, var(--bc-stone)); }
|
|
174
|
+
.known .issue .join:disabled { color: var(--bc-ok); background: transparent; cursor: default; opacity: 1; }
|
|
169
175
|
.known .ask { display: flex; gap: 8px; margin: 2px 0 8px; }
|
|
170
176
|
.known .ask input { flex: 1; min-width: 0; }
|
|
171
177
|
.known .ask button { flex: none; }
|
|
172
178
|
.known .err { margin: 6px 0 0; font-size: 12px; line-height: 1.45; color: var(--bc-danger); }
|
|
173
179
|
|
|
174
180
|
/* ---------- questions the assistant answers by itself ---------- */
|
|
175
|
-
.picks { margin-bottom:
|
|
176
|
-
.picks .picks-
|
|
177
|
-
margin: 0 0 8px; font-size: 11px; font-weight: 680; letter-spacing: .06em;
|
|
178
|
-
text-transform: uppercase; color: var(--bc-faint);
|
|
179
|
-
}
|
|
180
|
-
.picks .picks-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
|
|
181
|
+
.picks { margin-bottom: 14px; }
|
|
182
|
+
.picks .picks-grid { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
181
183
|
.picks .pick {
|
|
182
|
-
display: flex;
|
|
183
|
-
padding:
|
|
184
|
-
color: var(--bc-fg); background: var(--bc-
|
|
185
|
-
border: 1px solid
|
|
186
|
-
transition: background 160ms, border-color 160ms, transform 160ms;
|
|
184
|
+
display: inline-flex; align-items: center; max-width: 100%;
|
|
185
|
+
min-height: 32px; padding: 6px 13px; text-align: left; cursor: pointer; font: inherit;
|
|
186
|
+
color: var(--bc-fg); background: var(--bc-stone);
|
|
187
|
+
border: 1px solid transparent; border-radius: 999px;
|
|
188
|
+
transition: background 160ms, border-color 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
187
189
|
animation: bc-rise 240ms var(--bc-ease) both;
|
|
188
190
|
}
|
|
189
|
-
.picks .pick:hover {
|
|
190
|
-
.picks .pick
|
|
191
|
-
.picks .pick
|
|
192
|
-
.picks .pick .
|
|
191
|
+
.picks .pick:hover { background: color-mix(in srgb, var(--bc-fg) 10%, var(--bc-stone)); }
|
|
192
|
+
.picks .pick:active { transform: scale(.97); }
|
|
193
|
+
.picks .pick[aria-pressed="true"] { background: var(--bc-accent); color: var(--bc-on-accent); }
|
|
194
|
+
.picks .pick .t { font-size: 13px; font-weight: 520; line-height: 1.35; overflow-wrap: anywhere; }
|
|
193
195
|
.picks .picks-note {
|
|
194
196
|
display: flex; gap: 6px; align-items: flex-start; margin: 8px 0 0;
|
|
195
197
|
font-size: 12px; line-height: 1.45; color: var(--bc-muted);
|
|
@@ -203,18 +205,21 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
203
205
|
strip is the whole panel. */
|
|
204
206
|
.whoami {
|
|
205
207
|
display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
|
|
206
|
-
margin-bottom:
|
|
208
|
+
margin-bottom: 14px; padding: 9px 12px;
|
|
207
209
|
font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted);
|
|
208
210
|
background: var(--bc-subtle); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
|
|
209
211
|
}
|
|
210
212
|
.whoami.asking { display: block; padding: 14px; }
|
|
213
|
+
.whoami.asking .row input { background: var(--bc-bg); border-color: var(--bc-border); }
|
|
211
214
|
.whoami .who { flex: 1; min-width: 0; }
|
|
212
215
|
.whoami .who strong { color: var(--bc-fg); font-weight: 620; word-break: break-all; }
|
|
213
216
|
.link {
|
|
214
|
-
padding: 0; font: inherit; font-size: var(--bc-fs-sm); font-weight:
|
|
215
|
-
color: var(--bc-
|
|
217
|
+
padding: 0; font: inherit; font-size: var(--bc-fs-sm); font-weight: 560; line-height: 1.45;
|
|
218
|
+
color: var(--bc-fg); background: none; border: none; cursor: pointer; border-radius: 4px;
|
|
219
|
+
text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--bc-fg) 30%, transparent);
|
|
220
|
+
text-underline-offset: 3px;
|
|
216
221
|
}
|
|
217
|
-
.link:hover { text-decoration
|
|
222
|
+
.link:hover { text-decoration-color: currentColor; }
|
|
218
223
|
.link:disabled { color: var(--bc-faint); cursor: default; text-decoration: none; }
|
|
219
224
|
.whoami .why { margin: 0 0 10px; font-size: var(--bc-fs-sm); line-height: 1.5; color: var(--bc-muted); }
|
|
220
225
|
.whoami .why strong { color: var(--bc-fg); font-weight: 620; word-break: break-all; }
|
|
@@ -231,18 +236,17 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
231
236
|
assistant asking one friendly follow-up, not as a form field that appeared. */
|
|
232
237
|
.refs {
|
|
233
238
|
position: relative;
|
|
234
|
-
margin-bottom:
|
|
239
|
+
margin-bottom: 14px; padding: 14px;
|
|
235
240
|
font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted);
|
|
236
|
-
background: var(--bc-
|
|
237
|
-
border: 1px solid var(--bc-
|
|
241
|
+
background: var(--bc-subtle);
|
|
242
|
+
border: 1px solid var(--bc-border); border-radius: var(--bc-r-lg);
|
|
238
243
|
animation: bc-item-in 280ms var(--bc-ease) both;
|
|
239
244
|
}
|
|
240
245
|
.refs .ask-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 11px; }
|
|
241
|
-
.refs .ask-head
|
|
242
|
-
.refs .ask-head strong { display: block; font-size: 13.5px; font-weight: 650; color: var(--bc-fg); margin-bottom: 1px; }
|
|
246
|
+
.refs .ask-head strong { display: block; font-size: 13.5px; font-weight: 600; color: var(--bc-fg); margin-bottom: 1px; }
|
|
243
247
|
.refs .why { margin: 0; font-size: var(--bc-fs-sm); line-height: 1.5; color: var(--bc-muted); }
|
|
244
248
|
.refs .row { display: flex; gap: 8px; align-items: stretch; }
|
|
245
|
-
.refs .row input { flex: 1; min-width: 0; background: var(--bc-bg); }
|
|
249
|
+
.refs .row input { flex: 1; min-width: 0; background: var(--bc-bg); border-color: var(--bc-border); }
|
|
246
250
|
.refs select {
|
|
247
251
|
flex: none; max-width: 45%; padding: 10px 10px; font-size: 13px;
|
|
248
252
|
color: var(--bc-fg); background: var(--bc-bg);
|
|
@@ -270,40 +274,44 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
270
274
|
.ref-found svg { width: 14px; height: 14px; flex: none; color: var(--bc-ok); }
|
|
271
275
|
.ref-found b { font-weight: 600; color: var(--bc-fg); }
|
|
272
276
|
|
|
273
|
-
/* ---------- severity ----------
|
|
274
|
-
|
|
277
|
+
/* ---------- severity ----------
|
|
278
|
+
The segmented control from the product: a stone track, the choice lifted out
|
|
279
|
+
of it on white. */
|
|
280
|
+
.seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; padding: 3px; background: var(--bc-stone); border-radius: 999px; }
|
|
275
281
|
.seg button {
|
|
276
282
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
277
|
-
padding:
|
|
278
|
-
color: var(--bc-muted); background: none; border: none; border-radius:
|
|
283
|
+
height: 30px; padding: 0 4px; font: inherit; font-size: var(--bc-fs-sm); font-weight: 520; line-height: 1;
|
|
284
|
+
color: var(--bc-muted); background: none; border: none; border-radius: 999px;
|
|
279
285
|
cursor: pointer; transition: background 180ms var(--bc-ease), color 180ms, box-shadow 180ms;
|
|
280
286
|
}
|
|
281
|
-
.seg button::before { content: ''; width:
|
|
282
|
-
.seg button[data-prio="LOW"] { --sev:
|
|
283
|
-
.seg button[data-prio="MEDIUM"] { --sev:
|
|
284
|
-
.seg button[data-prio="HIGH"] { --sev:
|
|
285
|
-
.seg button[data-prio="CRITICAL"] { --sev:
|
|
287
|
+
.seg button::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--sev, var(--bc-faint)); opacity: .5; transition: opacity 180ms; }
|
|
288
|
+
.seg button[data-prio="LOW"] { --sev: var(--bc-ok); }
|
|
289
|
+
.seg button[data-prio="MEDIUM"] { --sev: var(--bc-info); }
|
|
290
|
+
.seg button[data-prio="HIGH"] { --sev: var(--bc-warn); }
|
|
291
|
+
.seg button[data-prio="CRITICAL"] { --sev: var(--bc-danger); }
|
|
286
292
|
.seg button:hover { color: var(--bc-fg); }
|
|
287
293
|
.seg button[aria-pressed=true] {
|
|
288
|
-
background: var(--bc-raised); color: var(--bc-fg); font-weight:
|
|
289
|
-
box-shadow: 0 1px
|
|
294
|
+
background: var(--bc-raised); color: var(--bc-fg); font-weight: 600;
|
|
295
|
+
box-shadow: 0 1px 2px rgba(20,18,14,.10), 0 0 0 .5px rgba(20,18,14,.08);
|
|
290
296
|
}
|
|
291
297
|
.seg button[aria-pressed=true]::before { opacity: 1; }
|
|
292
298
|
.seg button:focus-visible { outline-offset: -2px; }
|
|
293
299
|
|
|
294
|
-
/* ---------- attachments ----------
|
|
295
|
-
|
|
300
|
+
/* ---------- attachments ----------
|
|
301
|
+
Three ring pills in a row: optional, so they take one line, not a band of
|
|
302
|
+
dashed drop zones. */
|
|
303
|
+
.tools { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
296
304
|
.tool {
|
|
297
|
-
display: inline-flex;
|
|
298
|
-
padding:
|
|
299
|
-
color: var(--bc-fg); background: var(--bc-
|
|
300
|
-
border: 1px
|
|
305
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
306
|
+
height: 32px; padding: 0 11px 0 9px; font: inherit; font-size: 12.5px; font-weight: 520; line-height: 1; white-space: nowrap;
|
|
307
|
+
color: var(--bc-fg); background: var(--bc-bg);
|
|
308
|
+
border: 1px solid var(--bc-border); border-radius: 999px; cursor: pointer;
|
|
301
309
|
transition: border-color 160ms, background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
302
310
|
}
|
|
303
|
-
.tool svg { font-size:
|
|
304
|
-
.tool:hover:not(:disabled) {
|
|
305
|
-
.tool:hover:not(:disabled) svg { color: var(--bc-
|
|
306
|
-
.tool:active:not(:disabled) { transform:
|
|
311
|
+
.tool svg { font-size: 15px; color: var(--bc-muted); transition: color 160ms; }
|
|
312
|
+
.tool:hover:not(:disabled) { background: var(--bc-subtle); border-color: color-mix(in srgb, var(--bc-fg) 20%, var(--bc-border)); }
|
|
313
|
+
.tool:hover:not(:disabled) svg { color: var(--bc-fg); }
|
|
314
|
+
.tool:active:not(:disabled) { transform: scale(.97); }
|
|
307
315
|
.tool:disabled { opacity: .45; cursor: not-allowed; }
|
|
308
316
|
.attach-hint { margin: 8px 0 0; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
309
317
|
|
|
@@ -354,7 +362,7 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
354
362
|
.foot {
|
|
355
363
|
flex: none;
|
|
356
364
|
display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
|
|
357
|
-
padding: 12px var(--bc-pad); border-top: 1px solid var(--bc-border);
|
|
365
|
+
padding: 12px 14px 12px var(--bc-pad); border-top: 1px solid var(--bc-border);
|
|
358
366
|
background: var(--bc-bg);
|
|
359
367
|
}
|
|
360
368
|
.foot .spacer { flex: 1; }
|
|
@@ -367,36 +375,39 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
367
375
|
size, and dimming it on top of that left it as a smudge in both themes. */
|
|
368
376
|
.powered {
|
|
369
377
|
flex: none; display: flex; align-items: center; justify-content: center; gap: 6px;
|
|
370
|
-
padding:
|
|
371
|
-
background: var(--bc-
|
|
378
|
+
padding: 0 var(--bc-pad) 10px; font-size: 10.5px; color: var(--bc-faint);
|
|
379
|
+
background: var(--bc-bg);
|
|
372
380
|
}
|
|
373
381
|
.brand-credit { display: flex; align-items: center; transition: color 0.15s; border-radius: 4px; }
|
|
374
|
-
.bc-brand { height:
|
|
382
|
+
.bc-brand { height: 15px; width: auto; display: block; color: var(--bc-brand-ink); }
|
|
375
383
|
.brand-credit:hover .bc-brand { color: var(--bc-fg); }
|
|
384
|
+
/* The product's two pills: ink for the one thing to do, a white ring for the
|
|
385
|
+
alternative. Flat — no glow, no lift. */
|
|
376
386
|
button.ghost, button.primary {
|
|
377
387
|
display: inline-flex; align-items: center; justify-content: center; gap: 7px;
|
|
378
|
-
height: 38px; padding: 0 15px; font: inherit; font-size:
|
|
388
|
+
height: 38px; padding: 0 15px; font: inherit; font-size: 13.5px; font-weight: 560; line-height: 1;
|
|
379
389
|
border-radius: 999px; cursor: pointer; white-space: nowrap;
|
|
380
390
|
transition: transform 160ms var(--bc-ease), filter 160ms, background 160ms, border-color 160ms, color 160ms, box-shadow 160ms;
|
|
381
391
|
}
|
|
382
|
-
button.ghost { background: var(--bc-bg); border:
|
|
383
|
-
button.ghost:hover:not(:disabled) { background: var(--bc-subtle);
|
|
392
|
+
button.ghost { background: var(--bc-bg); border: 0; color: var(--bc-fg); box-shadow: 0 0 0 1px var(--bc-border), 0 1px 2px rgba(20,18,14,.05); }
|
|
393
|
+
button.ghost:hover:not(:disabled) { background: var(--bc-subtle); }
|
|
384
394
|
button.ghost svg, button.primary svg { font-size: 15px; }
|
|
385
395
|
button.primary {
|
|
386
396
|
padding: 0 18px;
|
|
387
|
-
background: var(--bc-accent); border:
|
|
388
|
-
box-shadow: 0
|
|
397
|
+
background: var(--bc-accent); border: 0; color: var(--bc-on-accent);
|
|
398
|
+
box-shadow: 0 1px 2px rgba(0,0,0,.14);
|
|
389
399
|
}
|
|
390
|
-
button.primary:hover:not(:disabled) {
|
|
391
|
-
button.primary:active:not(:disabled) { transform:
|
|
392
|
-
button:disabled { opacity: .
|
|
400
|
+
button.primary:hover:not(:disabled) { filter: brightness(1.12) contrast(.96); }
|
|
401
|
+
button.primary:active:not(:disabled) { transform: scale(.98); }
|
|
402
|
+
button:disabled { opacity: .45; cursor: not-allowed; }
|
|
393
403
|
button.primary:disabled { box-shadow: none; }
|
|
394
|
-
button.primary .spinner { border-color:
|
|
404
|
+
button.primary .spinner { border-color: color-mix(in srgb, var(--bc-on-accent) 40%, transparent); border-top-color: var(--bc-on-accent); width: 14px; height: 14px; }
|
|
395
405
|
button.quiet {
|
|
396
|
-
padding: 0 4px; height: 38px; font: inherit; font-size: 13px; font-weight:
|
|
406
|
+
padding: 0 4px; height: 38px; font: inherit; font-size: 13px; font-weight: 520;
|
|
397
407
|
border: none; background: none; color: var(--bc-muted); cursor: pointer; border-radius: 8px;
|
|
408
|
+
text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px;
|
|
398
409
|
}
|
|
399
|
-
button.quiet:hover { color: var(--bc-
|
|
410
|
+
button.quiet:hover { color: var(--bc-fg); text-decoration-color: color-mix(in srgb, var(--bc-fg) 35%, transparent); }
|
|
400
411
|
|
|
401
412
|
/* ---------- your reports ---------- */
|
|
402
413
|
.history {
|
|
@@ -416,13 +427,13 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
416
427
|
.history .row:last-child { border-bottom: 0; }
|
|
417
428
|
.history .who { flex: 1; min-width: 0; }
|
|
418
429
|
.history .ttl {
|
|
419
|
-
display: block; font-size: 13.5px; font-weight:
|
|
430
|
+
display: block; font-size: 13.5px; font-weight: 560; color: var(--bc-fg);
|
|
420
431
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
421
432
|
}
|
|
422
433
|
.history .sub { display: block; margin-top: 3px; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
423
434
|
.history .row-ico {
|
|
424
435
|
flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
|
|
425
|
-
background: var(--bc-
|
|
436
|
+
background: var(--bc-stone); color: var(--bc-muted); font-size: 16px;
|
|
426
437
|
}
|
|
427
438
|
.history .chev { flex: none; color: var(--bc-faint); font-size: 15px; transition: transform 160ms var(--bc-ease), color 160ms; }
|
|
428
439
|
.empty {
|
|
@@ -431,7 +442,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
431
442
|
}
|
|
432
443
|
.empty .empty-ico {
|
|
433
444
|
display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
|
|
434
|
-
background: var(--bc-
|
|
445
|
+
background: var(--bc-stone); color: var(--bc-fg); font-size: 20px;
|
|
435
446
|
}
|
|
436
447
|
.skel {
|
|
437
448
|
display: block; height: 12px; border-radius: 6px; margin: 6px 0;
|
|
@@ -447,7 +458,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
447
458
|
animation: bc-rise 260ms var(--bc-ease) both;
|
|
448
459
|
}
|
|
449
460
|
.history button.row:hover { background: var(--bc-subtle); }
|
|
450
|
-
.history button.row:hover .chev { transform: translateX(2px); color: var(--bc-
|
|
461
|
+
.history button.row:hover .chev { transform: translateX(2px); color: var(--bc-fg); }
|
|
451
462
|
.history button.row:focus-visible { outline-offset: -2px; }
|
|
452
463
|
|
|
453
464
|
/* ---------- one report, and what happened to it ---------- */
|
|
@@ -457,7 +468,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
457
468
|
padding: 10px var(--bc-pad); border-bottom: 1px solid var(--bc-border);
|
|
458
469
|
background: var(--bc-bg);
|
|
459
470
|
}
|
|
460
|
-
.report-head .ttl { font-size:
|
|
471
|
+
.report-head .ttl { font-size: 13.5px; font-weight: 600; color: var(--bc-fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
461
472
|
.report-head .sub { font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
462
473
|
.report-head .pill { grid-row: 1 / span 2; grid-column: 2; align-self: center; }
|
|
463
474
|
|
|
@@ -491,9 +502,9 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
491
502
|
border-radius: 50%; background: var(--bc-muted); vertical-align: middle;
|
|
492
503
|
}
|
|
493
504
|
.sys .t { color: var(--bc-faint); }
|
|
494
|
-
.sys.k-status .dot { background:
|
|
495
|
-
.sys.k-severity .dot { background:
|
|
496
|
-
.sys.k-assignment .dot { background:
|
|
505
|
+
.sys.k-status .dot { background: var(--bc-info); }
|
|
506
|
+
.sys.k-severity .dot { background: var(--bc-warn); }
|
|
507
|
+
.sys.k-assignment .dot { background: var(--bc-brand-mark); }
|
|
497
508
|
.sys.k-filed .dot { background: var(--bc-faint); }
|
|
498
509
|
|
|
499
510
|
/* ---------- the conversation ----------
|
|
@@ -526,24 +537,21 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
526
537
|
.msg-row.mine > * { grid-column: 1; }
|
|
527
538
|
.av {
|
|
528
539
|
display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
|
|
529
|
-
font-size: 11px; font-weight:
|
|
530
|
-
background:
|
|
540
|
+
font-size: 11px; font-weight: 650; letter-spacing: .02em;
|
|
541
|
+
background: var(--bc-stone); color: var(--bc-fg);
|
|
531
542
|
}
|
|
532
|
-
.av.bot {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
.msg-who { font-size: var(--bc-fs-xs); font-weight: 620; color: var(--bc-muted); padding: 0 4px 4px; }
|
|
537
|
-
.msg-who.auto { color: var(--bc-accent); display: inline-flex; align-items: center; gap: 5px; }
|
|
543
|
+
.av.bot { width: 28px; }
|
|
544
|
+
.msg-who { font-size: var(--bc-fs-xs); font-weight: 560; color: var(--bc-muted); padding: 0 4px 4px; }
|
|
545
|
+
.msg-who.auto { color: var(--bc-fg); display: inline-flex; align-items: center; gap: 5px; }
|
|
538
546
|
.msg-who .tag {
|
|
539
|
-
padding: 1px 6px; border-radius: 999px; font-size: 9.5px; font-weight:
|
|
540
|
-
text-transform: uppercase; background: var(--bc-
|
|
547
|
+
padding: 1px 6px; border-radius: 999px; font-size: 9.5px; font-weight: 650; letter-spacing: .05em;
|
|
548
|
+
text-transform: uppercase; background: var(--bc-stone); color: var(--bc-muted);
|
|
541
549
|
}
|
|
542
550
|
.bubble {
|
|
543
551
|
justify-self: start; max-width: 100%;
|
|
544
552
|
padding: 9px 13px; border-radius: 18px; font-size: 13.5px; line-height: 1.5;
|
|
545
|
-
background: var(--bc-
|
|
546
|
-
border: 1px solid
|
|
553
|
+
background: var(--bc-stone); color: var(--bc-fg);
|
|
554
|
+
border: 1px solid transparent;
|
|
547
555
|
border-bottom-left-radius: 6px;
|
|
548
556
|
}
|
|
549
557
|
/* pre-wrap belongs to the text, not the box — on the box it would also render
|
|
@@ -556,9 +564,10 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
556
564
|
}
|
|
557
565
|
.msg-row.cont.theirs .bubble { border-top-left-radius: 6px; }
|
|
558
566
|
.msg-row.cont.mine .bubble { border-top-right-radius: 6px; }
|
|
559
|
-
/* A reply nobody wrote:
|
|
560
|
-
it, so it reads the same to someone who cannot
|
|
561
|
-
|
|
567
|
+
/* A reply nobody wrote: drawn on white with a hairline, beside the orb and
|
|
568
|
+
labelled "Assistant" above it, so it reads the same to someone who cannot
|
|
569
|
+
see the difference at all. */
|
|
570
|
+
.msg-row.auto .bubble { background: var(--bc-bg); border-color: var(--bc-border); }
|
|
562
571
|
/* An attachment-only message has no text to wrap, so the bubble would be an
|
|
563
572
|
empty coloured box around it. */
|
|
564
573
|
.bubble.silent { padding: 0; background: none !important; border: 0; }
|
|
@@ -572,7 +581,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
572
581
|
/* The assistant, thinking. Three dots in a bubble where its next message will be. */
|
|
573
582
|
.typing { display: inline-flex; align-items: center; gap: 4px; padding: 12px 14px; justify-self: start; }
|
|
574
583
|
.typing i {
|
|
575
|
-
width:
|
|
584
|
+
width: 6px; height: 6px; border-radius: 50%; background: var(--bc-muted); opacity: .45;
|
|
576
585
|
animation: bc-typing 1.2s ease-in-out infinite;
|
|
577
586
|
}
|
|
578
587
|
.typing i:nth-child(2) { animation-delay: .15s; }
|
|
@@ -608,30 +617,29 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
608
617
|
background: var(--bc-subtle);
|
|
609
618
|
transition: background 400ms ease, border-color 400ms ease;
|
|
610
619
|
}
|
|
611
|
-
.assistant.
|
|
612
|
-
background: var(--bc-accent-soft); border-color: var(--bc-accent-line);
|
|
613
|
-
}
|
|
614
|
-
.assistant.resolved { background: color-mix(in srgb, var(--bc-ok) 9%, var(--bc-bg)); border-color: color-mix(in srgb, var(--bc-ok) 35%, var(--bc-border)); }
|
|
620
|
+
.assistant.resolved { background: color-mix(in srgb, var(--bc-ok) 7%, var(--bc-bg)); border-color: color-mix(in srgb, var(--bc-ok) 30%, var(--bc-border)); }
|
|
615
621
|
/* On a call: the call's own card is what they are watching. This one states
|
|
616
|
-
what is happening and stops moving — no
|
|
622
|
+
what is happening and stops moving — no breathing orb, no travelling bar. */
|
|
617
623
|
.assistant.calling { background: var(--bc-bg); }
|
|
618
624
|
.assistant.calling .as-progress i { transition: none; }
|
|
619
625
|
.as-body.entering { animation: bc-rise 360ms var(--bc-ease) both; }
|
|
620
626
|
.as-top { display: flex; gap: 11px; align-items: center; }
|
|
627
|
+
/* The orb, while the assistant is at work; a plain disc with a glyph once it
|
|
628
|
+
is on a call or has finished. */
|
|
621
629
|
.as-orb {
|
|
622
630
|
flex: none; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
|
|
623
|
-
color: var(--bc-on-accent); font-size: 15px;
|
|
624
|
-
background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
|
|
631
|
+
color: var(--bc-on-accent); font-size: 15px; background: var(--bc-accent);
|
|
625
632
|
}
|
|
626
|
-
.
|
|
627
|
-
.assistant.
|
|
628
|
-
|
|
629
|
-
|
|
633
|
+
.as-orb.orb { background: var(--bc-o2); }
|
|
634
|
+
.assistant.analyzing .as-orb.orb { animation: as-breathe 2.4s ease-in-out infinite; }
|
|
635
|
+
@keyframes as-breathe { 50% { transform: scale(.88); } }
|
|
636
|
+
.assistant.resolved .as-orb { background: var(--bc-ok); color: #fff; }
|
|
637
|
+
.assistant.reviewing .as-orb.orb { filter: saturate(.35); }
|
|
630
638
|
.as-text { min-width: 0; flex: 1; }
|
|
631
|
-
.as-title { font-weight:
|
|
639
|
+
.as-title { font-weight: 600; font-size: 13.5px; letter-spacing: -.01em; color: var(--bc-fg); }
|
|
632
640
|
.as-detail { font-size: 12px; line-height: 1.45; color: var(--bc-muted); margin-top: 2px; }
|
|
633
641
|
.as-progress {
|
|
634
|
-
height:
|
|
642
|
+
height: 3px; margin: 12px 0 0; border-radius: 999px; overflow: hidden;
|
|
635
643
|
background: color-mix(in srgb, var(--bc-fg) 9%, transparent);
|
|
636
644
|
}
|
|
637
645
|
.as-progress i {
|
|
@@ -640,39 +648,42 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
640
648
|
}
|
|
641
649
|
.assistant.resolved .as-progress i { background: var(--bc-ok); }
|
|
642
650
|
.assistant.analyzing .as-progress i {
|
|
643
|
-
background: linear-gradient(90deg, var(--bc-accent) 0%, color-mix(in srgb, var(--bc-accent)
|
|
651
|
+
background: linear-gradient(90deg, var(--bc-accent) 0%, color-mix(in srgb, var(--bc-accent) 35%, var(--bc-bg)) 50%, var(--bc-accent) 100%);
|
|
644
652
|
background-size: 200% 100%; animation: bc-shimmer 1.6s linear infinite;
|
|
645
653
|
}
|
|
654
|
+
/* Four short labels under the bar. Allowed to wrap rather than be cut: at this
|
|
655
|
+
width "Report received" ellipsised to "Report recei…". */
|
|
646
656
|
.as-steps {
|
|
647
|
-
list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
|
|
648
|
-
margin: 8px 0 0; padding: 0; font-size: 10.5px; color: var(--bc-faint);
|
|
657
|
+
list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px 6px;
|
|
658
|
+
margin: 8px 0 0; padding: 0; font-size: 10.5px; line-height: 1.3; color: var(--bc-faint);
|
|
649
659
|
}
|
|
650
|
-
.as-steps li { display: flex; align-items:
|
|
651
|
-
.as-steps li .lbl { min-width: 0; overflow
|
|
652
|
-
.as-steps li .dot { flex: none; width:
|
|
660
|
+
.as-steps li { display: flex; align-items: flex-start; gap: 5px; min-width: 0; }
|
|
661
|
+
.as-steps li .lbl { min-width: 0; overflow-wrap: anywhere; }
|
|
662
|
+
.as-steps li .dot { flex: none; width: 7px; height: 7px; margin-top: 3px; border-radius: 50%; border: 1.5px solid currentColor; }
|
|
653
663
|
.as-steps li.done { color: var(--bc-muted); }
|
|
654
664
|
.as-steps li.done .dot { background: var(--bc-accent); border-color: var(--bc-accent); }
|
|
655
665
|
.assistant.resolved .as-steps li.done .dot { background: var(--bc-ok); border-color: var(--bc-ok); }
|
|
656
|
-
.as-steps li.active { color: var(--bc-fg); font-weight:
|
|
666
|
+
.as-steps li.active { color: var(--bc-fg); font-weight: 600; }
|
|
657
667
|
.as-steps li.active .dot { border-color: var(--bc-accent); background: var(--bc-bg); animation: as-pulse 1.2s ease-in-out infinite; }
|
|
658
|
-
@keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent)
|
|
659
|
-
@media (prefers-reduced-motion: reduce) { .as-
|
|
668
|
+
@keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent) 18%, transparent); } }
|
|
669
|
+
@media (prefers-reduced-motion: reduce) { .as-orb, .as-steps li.active .dot, .assistant.analyzing .as-progress i, .typing i { animation: none; } }
|
|
660
670
|
|
|
661
671
|
/* Quick answers under the confirm question — only on the latest message. */
|
|
662
672
|
.msg-row .quick { display: none; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
|
|
663
673
|
.msg-row:last-child .quick { display: flex; }
|
|
664
674
|
.quick button {
|
|
665
675
|
display: inline-flex; align-items: center; gap: 6px;
|
|
666
|
-
font: inherit; font-size: 13px; font-weight:
|
|
667
|
-
border:
|
|
676
|
+
font: inherit; font-size: 13px; font-weight: 560; height: 34px; padding: 0 14px; border-radius: 999px; cursor: pointer;
|
|
677
|
+
border: 0; background: var(--bc-bg); color: var(--bc-fg); box-shadow: 0 0 0 1px var(--bc-border);
|
|
668
678
|
transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
669
679
|
animation: bc-item-in 300ms var(--bc-ease) both;
|
|
670
680
|
}
|
|
671
|
-
.quick button:first-child { background: var(--bc-accent); color: var(--bc-on-accent); }
|
|
681
|
+
.quick button:first-child { background: var(--bc-accent); color: var(--bc-on-accent); box-shadow: none; }
|
|
672
682
|
.quick button:nth-child(2) { animation-delay: 60ms; }
|
|
673
683
|
.quick button svg { font-size: 13px; }
|
|
674
|
-
.quick button:hover {
|
|
675
|
-
.quick button:first-child:hover { background: var(--bc-accent); filter: brightness(1.
|
|
684
|
+
.quick button:hover { background: var(--bc-subtle); }
|
|
685
|
+
.quick button:first-child:hover { background: var(--bc-accent); filter: brightness(1.12) contrast(.96); }
|
|
686
|
+
.quick button:active { transform: scale(.97); }
|
|
676
687
|
|
|
677
688
|
/* ---------- the composer ---------- */
|
|
678
689
|
.composer {
|
|
@@ -689,10 +700,10 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
689
700
|
.composer .row {
|
|
690
701
|
display: flex; align-items: flex-end; gap: 4px;
|
|
691
702
|
padding: 5px; border-radius: 22px;
|
|
692
|
-
background: var(--bc-
|
|
693
|
-
transition: border-color 160ms, box-shadow 160ms;
|
|
703
|
+
background: var(--bc-stone); border: 1px solid transparent;
|
|
704
|
+
transition: border-color 160ms, box-shadow 160ms, background 160ms;
|
|
694
705
|
}
|
|
695
|
-
.composer .row:focus-within { border-color: var(--bc-accent); box-shadow: var(--bc-ring); }
|
|
706
|
+
.composer .row:focus-within { background: var(--bc-bg); border-color: var(--bc-accent); box-shadow: var(--bc-ring); }
|
|
696
707
|
.composer textarea {
|
|
697
708
|
flex: 1; min-width: 0; min-height: 34px; max-height: 120px; resize: none; padding: 7px 6px;
|
|
698
709
|
font: inherit; font-size: 13.5px; line-height: 1.45;
|
|
@@ -717,8 +728,8 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
717
728
|
display: grid; place-items: center;
|
|
718
729
|
transition: transform 160ms var(--bc-ease), opacity 160ms, filter 160ms;
|
|
719
730
|
}
|
|
720
|
-
.composer .send:hover:not(:disabled) { filter: brightness(1.
|
|
721
|
-
.composer .send:disabled { opacity: .
|
|
731
|
+
.composer .send:hover:not(:disabled) { filter: brightness(1.12) contrast(.96); transform: scale(1.04); }
|
|
732
|
+
.composer .send:disabled { opacity: .3; cursor: default; background: var(--bc-faint); }
|
|
722
733
|
.composer .staged { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 8px; }
|
|
723
734
|
.composer .chip {
|
|
724
735
|
display: flex; align-items: center; gap: 6px; max-width: 200px;
|
|
@@ -741,23 +752,16 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
741
752
|
lands on — which is what someone opening this screen came to check. */
|
|
742
753
|
.pill {
|
|
743
754
|
flex: none; display: inline-flex; align-items: center; gap: 5px;
|
|
744
|
-
font-size: 11px; font-weight:
|
|
755
|
+
font-size: 11px; font-weight: 600;
|
|
745
756
|
padding: 3px 9px; border-radius: 999px;
|
|
746
|
-
color: var(--bc-muted); background: var(--bc-
|
|
757
|
+
color: var(--bc-muted); background: var(--bc-stone);
|
|
747
758
|
}
|
|
748
759
|
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
|
749
|
-
|
|
750
|
-
.pill.
|
|
751
|
-
.pill.
|
|
760
|
+
/* The theme's own status colours, which already have a dark cut. */
|
|
761
|
+
.pill.open { color: var(--bc-warn); background: color-mix(in srgb, var(--bc-warn) 12%, var(--bc-bg)); }
|
|
762
|
+
.pill.in_progress { color: var(--bc-info); background: color-mix(in srgb, var(--bc-info) 12%, var(--bc-bg)); }
|
|
763
|
+
.pill.resolved { color: var(--bc-ok); background: color-mix(in srgb, var(--bc-ok) 12%, var(--bc-bg)); }
|
|
752
764
|
.pill.closed { color: var(--bc-muted); }
|
|
753
|
-
:host(.bc-dark) .pill.open { color: #fbbf24; }
|
|
754
|
-
:host(.bc-dark) .pill.in_progress { color: #7cb8ff; }
|
|
755
|
-
:host(.bc-dark) .pill.resolved { color: #4ade9a; }
|
|
756
|
-
@media (prefers-color-scheme: dark) {
|
|
757
|
-
:host(.bc-auto) .pill.open { color: #fbbf24; }
|
|
758
|
-
:host(.bc-auto) .pill.in_progress { color: #7cb8ff; }
|
|
759
|
-
:host(.bc-auto) .pill.resolved { color: #4ade9a; }
|
|
760
|
-
}
|
|
761
765
|
|
|
762
766
|
/* ---------- does the fix work ---------- */
|
|
763
767
|
.fix-verification {
|
|
@@ -777,6 +781,47 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
777
781
|
.fix-verification .feedback-status { margin: 6px 0 0; font-weight: 450; color: var(--bc-danger); font-size: var(--bc-fs-xs); }
|
|
778
782
|
.fix-verification .feedback-status:empty { display: none; }
|
|
779
783
|
|
|
784
|
+
/* ---------- how did we do ----------
|
|
785
|
+
Quieter than the card above it: that one asks whether the fix works, which
|
|
786
|
+
the team acts on; this asks how it felt, which they learn from. The stars
|
|
787
|
+
carry the only colour, so the one thing to do here is the thing you see. */
|
|
788
|
+
.fix-rating {
|
|
789
|
+
--bc-star: #f0a81c;
|
|
790
|
+
flex: none; margin: 10px 12px 0; padding: 12px 14px;
|
|
791
|
+
border-radius: var(--bc-r-lg); border: 1px solid var(--bc-border); background: var(--bc-bg);
|
|
792
|
+
font-size: var(--bc-fs-sm); color: var(--bc-fg);
|
|
793
|
+
animation: bc-rise 280ms var(--bc-ease) both;
|
|
794
|
+
}
|
|
795
|
+
.fix-rating .fr-q { margin: 0 0 6px; font-weight: 620; }
|
|
796
|
+
.fix-rating .stars { display: flex; gap: 2px; margin: 0 0 2px -4px; }
|
|
797
|
+
.fix-rating .stars button {
|
|
798
|
+
display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0;
|
|
799
|
+
border: 0; border-radius: 8px; background: transparent; cursor: pointer;
|
|
800
|
+
color: color-mix(in srgb, var(--bc-fg) 18%, transparent);
|
|
801
|
+
transition: color 120ms ease, transform 120ms var(--bc-ease);
|
|
802
|
+
}
|
|
803
|
+
.fix-rating .stars button svg { width: 24px; height: 24px; }
|
|
804
|
+
.fix-rating .stars button.on { color: var(--bc-star); }
|
|
805
|
+
.fix-rating .stars button:hover:not(:disabled) { transform: scale(1.08); }
|
|
806
|
+
.fix-rating .stars button:focus-visible { outline: none; box-shadow: var(--bc-ring); }
|
|
807
|
+
.fix-rating .stars button:disabled { cursor: default; }
|
|
808
|
+
.fix-rating .fr-hint { margin: 2px 0 0; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
809
|
+
.fix-rating .fr-said { margin: 6px 0 0; font-size: 13px; color: var(--bc-muted); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
810
|
+
.fix-rating .fr-note { margin-top: 8px; }
|
|
811
|
+
.fix-rating .fr-note textarea { min-height: 52px; margin-bottom: 8px; font-size: 13px; }
|
|
812
|
+
.fix-rating .fr-note button {
|
|
813
|
+
padding: 7px 13px; font: inherit; font-size: 12.5px; font-weight: 620; border-radius: 999px; cursor: pointer;
|
|
814
|
+
border: 1px solid var(--bc-border); background: var(--bc-bg); color: var(--bc-fg);
|
|
815
|
+
}
|
|
816
|
+
.fix-rating .feedback-status { margin: 6px 0 0; color: var(--bc-danger); font-size: var(--bc-fs-xs); }
|
|
817
|
+
.fix-rating .feedback-status:empty { display: none; }
|
|
818
|
+
@media (prefers-reduced-motion: reduce) { .fix-rating .stars button { transition: none; } .fix-rating .stars button:hover { transform: none; } }
|
|
819
|
+
|
|
820
|
+
/* The rating on a history row: the score given, or a nudge to give one. */
|
|
821
|
+
.history .sub .rated { display: inline-flex; align-items: center; gap: 2px; color: var(--bc-muted); font-weight: 600; }
|
|
822
|
+
.history .sub .rated svg { width: 11px; height: 11px; color: #f0a81c; }
|
|
823
|
+
.history .sub .rate-ask { color: var(--bc-fg); font-weight: 600; }
|
|
824
|
+
|
|
780
825
|
/* A call in progress, in place of the form.
|
|
781
826
|
---------------------------------------------------------------------------
|
|
782
827
|
Deliberately not styled as a chat. Nothing arrives here to read — the
|
|
@@ -826,13 +871,13 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
826
871
|
and this screen's padding was landing on every one of them. */
|
|
827
872
|
div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 240ms ease both; }
|
|
828
873
|
.done .tick {
|
|
829
|
-
width:
|
|
830
|
-
display: grid; place-items: center; font-size:
|
|
831
|
-
background:
|
|
832
|
-
box-shadow: 0 0 0
|
|
874
|
+
width: 52px; height: 52px; margin: 0 auto 16px; border-radius: 50%;
|
|
875
|
+
display: grid; place-items: center; font-size: 24px;
|
|
876
|
+
background: var(--bc-ok); color: #fff;
|
|
877
|
+
box-shadow: 0 0 0 7px color-mix(in srgb, var(--bc-ok) 12%, transparent);
|
|
833
878
|
animation: bc-pop 420ms var(--bc-ease) both;
|
|
834
879
|
}
|
|
835
|
-
.done h3 { margin: 0 0 6px; font-size:
|
|
880
|
+
.done h3 { margin: 0 0 6px; font-size: 18px; font-weight: 600; letter-spacing: -.02em; }
|
|
836
881
|
.done p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--bc-muted); }
|
|
837
882
|
.done code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; padding: 1px 5px; border-radius: 5px; background: var(--bc-subtle); color: var(--bc-fg); }
|
|
838
883
|
/* The likely wait. Set apart from the reference line above it by a rule rather
|
|
@@ -896,7 +941,7 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
896
941
|
is open — the sheet has its own close button, and a launcher floating over
|
|
897
942
|
the send button would be in the way of the one thing that matters. */
|
|
898
943
|
@media (max-width: 480px) {
|
|
899
|
-
.scrim { background: rgba(
|
|
944
|
+
.scrim { background: rgba(14,14,16,.4); }
|
|
900
945
|
.panel, .scrim.at-right .panel, .scrim.at-left .panel, .scrim.at-bottom .panel, .scrim.at-top .panel {
|
|
901
946
|
inset: 0; width: 100%; max-width: none; height: 100%; max-height: none;
|
|
902
947
|
border-radius: 0; border: 0;
|
|
@@ -911,6 +956,16 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
911
956
|
.foot:has(+ .powered) { padding-bottom: 12px; }
|
|
912
957
|
.recbar .hint { display: none; }
|
|
913
958
|
.msg-row, .typing-row { max-width: 92%; }
|
|
959
|
+
/* The question chips are one row that scrolls sideways, edge to edge, rather
|
|
960
|
+
than three stacked rows pushing the form down the screen. */
|
|
961
|
+
.picks .picks-grid {
|
|
962
|
+
flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
|
|
963
|
+
margin: 0 calc(var(--bc-pad) * -1); padding: 0 var(--bc-pad) 2px;
|
|
964
|
+
scroll-snap-type: x proximity; scroll-padding: 0 var(--bc-pad);
|
|
965
|
+
}
|
|
966
|
+
.picks .picks-grid::-webkit-scrollbar { display: none; }
|
|
967
|
+
.picks .pick { flex: none; scroll-snap-align: start; }
|
|
968
|
+
.picks .pick .t { white-space: nowrap; }
|
|
914
969
|
}
|
|
915
970
|
|
|
916
971
|
@media (pointer: coarse) {
|
|
@@ -925,7 +980,8 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
925
980
|
under it, on the one surface in the product designed for someone who is
|
|
926
981
|
not an operator and gets no second attempt. */
|
|
927
982
|
.seg button { min-height: 44px; }
|
|
928
|
-
.tool { min-height:
|
|
983
|
+
.tool, .known .issue .join { min-height: 44px; }
|
|
984
|
+
.picks .pick { min-height: 40px; }
|
|
929
985
|
button.primary, button.ghost { height: 44px; }
|
|
930
986
|
.composer .send, .composer .tool { width: 40px; height: 40px; min-height: 0; }
|
|
931
987
|
textarea { min-height: 104px; }
|
|
@@ -934,7 +990,7 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
934
990
|
/* The close button and the thumbnails' remove buttons are small glyphs whose
|
|
935
991
|
boxes cannot grow without moving what is beside them, so each keeps its
|
|
936
992
|
size and gets an invisible target drawn around it instead. The theme
|
|
937
|
-
|
|
993
|
+
button in the header is one of these. */
|
|
938
994
|
.head .icon-btn, .thumb .drop, .brand-credit { position: relative; }
|
|
939
995
|
.thumb .drop { position: absolute; opacity: 1; }
|
|
940
996
|
.head .icon-btn::after, .thumb .drop::after, .brand-credit::after {
|
|
@@ -949,29 +1005,31 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
949
1005
|
.tool:hover:not(:disabled) { transform: none; }
|
|
950
1006
|
}
|
|
951
1007
|
`;
|
|
952
|
-
function
|
|
1008
|
+
function le({ title: e, sub: t, id: i = "", back: w = !1, theme: b = "" }) {
|
|
953
1009
|
return `
|
|
954
1010
|
<div class="head">
|
|
955
|
-
${
|
|
956
|
-
<
|
|
1011
|
+
${w ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${Ne}</button>` : ""}
|
|
1012
|
+
<span class="orb mark" aria-hidden="true"></span>
|
|
957
1013
|
<div class="titles">
|
|
958
|
-
<h2${
|
|
959
|
-
<p>${
|
|
1014
|
+
<h2${i ? ` id="${i}"` : ""}>${v(e)}</h2>
|
|
1015
|
+
<p>${v(t)}</p>
|
|
960
1016
|
</div>
|
|
961
|
-
|
|
1017
|
+
${b ? `<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${v(b)}"
|
|
1018
|
+
aria-label="Theme: ${v(b)}. Change theme"><span class="m-light">${ke}</span><span class="m-dark">${$e}</span><span class="m-auto">${Se}</span></button>` : ""}
|
|
1019
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${ce}</button>
|
|
962
1020
|
</div>`;
|
|
963
1021
|
}
|
|
964
|
-
function
|
|
965
|
-
return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${
|
|
1022
|
+
function re(e, t) {
|
|
1023
|
+
return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${v(e)}</div>`;
|
|
966
1024
|
}
|
|
967
|
-
function
|
|
1025
|
+
function Ke(e) {
|
|
968
1026
|
return Array.from({ length: e }, () => `
|
|
969
1027
|
<div class="row" aria-hidden="true">
|
|
970
1028
|
<span class="row-ico"></span>
|
|
971
1029
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
972
1030
|
</div>`).join("") + '<span class="sr-only">Loading…</span>';
|
|
973
1031
|
}
|
|
974
|
-
function
|
|
1032
|
+
function Ue() {
|
|
975
1033
|
return `
|
|
976
1034
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
977
1035
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
@@ -980,7 +1038,7 @@ function Pe() {
|
|
|
980
1038
|
</div>
|
|
981
1039
|
<span class="sr-only">Loading…</span>`;
|
|
982
1040
|
}
|
|
983
|
-
function
|
|
1041
|
+
function Ze(e) {
|
|
984
1042
|
const t = String(e).trim().split(/\s+/).filter(Boolean);
|
|
985
1043
|
return t.length ? (t[0][0] + (t.length > 1 ? t[t.length - 1][0] : "")).toUpperCase() : "?";
|
|
986
1044
|
}
|
|
@@ -988,22 +1046,22 @@ function Z(e) {
|
|
|
988
1046
|
const t = new Date(e);
|
|
989
1047
|
return Number.isFinite(t.getTime()) ? `${t.getFullYear()}-${t.getMonth()}-${t.getDate()}` : null;
|
|
990
1048
|
}
|
|
991
|
-
function
|
|
992
|
-
const t = new Date(e),
|
|
993
|
-
if (Z(t) === Z(
|
|
994
|
-
if (Z(t) === Z(
|
|
1049
|
+
function _e(e) {
|
|
1050
|
+
const t = new Date(e), i = /* @__PURE__ */ new Date(), w = new Date(i.getFullYear(), i.getMonth(), i.getDate() - 1);
|
|
1051
|
+
if (Z(t) === Z(i)) return "Today";
|
|
1052
|
+
if (Z(t) === Z(w)) return "Yesterday";
|
|
995
1053
|
try {
|
|
996
1054
|
return t.toLocaleDateString(void 0, {
|
|
997
1055
|
weekday: "short",
|
|
998
1056
|
day: "numeric",
|
|
999
1057
|
month: "short",
|
|
1000
|
-
...t.getFullYear() !==
|
|
1058
|
+
...t.getFullYear() !== i.getFullYear() ? { year: "numeric" } : {}
|
|
1001
1059
|
});
|
|
1002
1060
|
} catch {
|
|
1003
|
-
return
|
|
1061
|
+
return ne(e);
|
|
1004
1062
|
}
|
|
1005
1063
|
}
|
|
1006
|
-
function
|
|
1064
|
+
function ve(e) {
|
|
1007
1065
|
const t = new Date(e);
|
|
1008
1066
|
if (!Number.isFinite(t.getTime())) return "";
|
|
1009
1067
|
try {
|
|
@@ -1012,14 +1070,14 @@ function me(e) {
|
|
|
1012
1070
|
return "";
|
|
1013
1071
|
}
|
|
1014
1072
|
}
|
|
1015
|
-
function
|
|
1073
|
+
function pe(e) {
|
|
1016
1074
|
return e.scrollHeight - e.scrollTop - e.clientHeight < 40;
|
|
1017
1075
|
}
|
|
1018
1076
|
function _(e, { smooth: t = !1 } = {}) {
|
|
1019
|
-
const
|
|
1020
|
-
t && !
|
|
1077
|
+
const i = typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1078
|
+
t && !i && e.scrollTo ? e.scrollTo({ top: e.scrollHeight, behavior: "smooth" }) : e.scrollTop = e.scrollHeight;
|
|
1021
1079
|
}
|
|
1022
|
-
function
|
|
1080
|
+
function ie(e) {
|
|
1023
1081
|
return {
|
|
1024
1082
|
OPEN: "Open",
|
|
1025
1083
|
IN_PROGRESS: "In progress",
|
|
@@ -1027,52 +1085,52 @@ function se(e) {
|
|
|
1027
1085
|
CLOSED: "Closed"
|
|
1028
1086
|
}[e] || String(e || "").toLowerCase();
|
|
1029
1087
|
}
|
|
1030
|
-
function
|
|
1088
|
+
function ne(e) {
|
|
1031
1089
|
const t = new Date(e).getTime();
|
|
1032
1090
|
if (!Number.isFinite(t)) return "";
|
|
1033
|
-
const
|
|
1034
|
-
if (
|
|
1035
|
-
if (
|
|
1036
|
-
if (
|
|
1037
|
-
const
|
|
1038
|
-
return
|
|
1039
|
-
}
|
|
1040
|
-
function
|
|
1091
|
+
const i = Math.floor((Date.now() - t) / 864e5);
|
|
1092
|
+
if (i <= 0) return "today";
|
|
1093
|
+
if (i === 1) return "yesterday";
|
|
1094
|
+
if (i < 30) return `${i} days ago`;
|
|
1095
|
+
const w = Math.floor(i / 30);
|
|
1096
|
+
return w === 1 ? "a month ago" : `${w} months ago`;
|
|
1097
|
+
}
|
|
1098
|
+
function v(e) {
|
|
1041
1099
|
return String(e).replace(/[&<>"']/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[t]);
|
|
1042
1100
|
}
|
|
1043
|
-
const
|
|
1044
|
-
let
|
|
1045
|
-
function
|
|
1046
|
-
return
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1101
|
+
const Ge = 7 * 24 * 60 * 60 * 1e3;
|
|
1102
|
+
let J;
|
|
1103
|
+
function Xe() {
|
|
1104
|
+
return J || (J = new Promise((e, t) => {
|
|
1105
|
+
const i = indexedDB.open("bugcatch-drafts", 1);
|
|
1106
|
+
i.onupgradeneeded = () => i.result.createObjectStore("drafts"), i.onsuccess = () => e(i.result), i.onerror = () => t(i.error), i.onblocked = () => t(new Error("Draft storage is blocked."));
|
|
1049
1107
|
}).catch((e) => {
|
|
1050
|
-
throw
|
|
1051
|
-
})),
|
|
1052
|
-
}
|
|
1053
|
-
function
|
|
1054
|
-
var
|
|
1055
|
-
return JSON.stringify([e.apiBase, e.projectId, t || ((
|
|
1056
|
-
}
|
|
1057
|
-
async function
|
|
1058
|
-
const
|
|
1059
|
-
return new Promise((
|
|
1060
|
-
const T =
|
|
1061
|
-
T.oncomplete = () =>
|
|
1108
|
+
throw J = null, e;
|
|
1109
|
+
})), J;
|
|
1110
|
+
}
|
|
1111
|
+
function Je(e, t) {
|
|
1112
|
+
var i, w;
|
|
1113
|
+
return JSON.stringify([e.apiBase, e.projectId, t || ((i = e.user) == null ? void 0 : i.email) || ((w = e.user) == null ? void 0 : w.id) || "anonymous"]);
|
|
1114
|
+
}
|
|
1115
|
+
async function te(e, t) {
|
|
1116
|
+
const i = await Xe();
|
|
1117
|
+
return new Promise((w, b) => {
|
|
1118
|
+
const T = i.transaction("drafts", t === void 0 ? "readonly" : "readwrite"), x = T.objectStore("drafts"), g = t === void 0 ? x.get(e) : t === null ? x.delete(e) : x.put({ ...t, savedAt: Date.now() }, e);
|
|
1119
|
+
T.oncomplete = () => w(g.result), T.onerror = () => b(T.error), T.onabort = () => b(T.error || new Error("Draft was not saved."));
|
|
1062
1120
|
});
|
|
1063
1121
|
}
|
|
1064
|
-
async function
|
|
1065
|
-
const t = await
|
|
1066
|
-
return t && Date.now() - t.savedAt >
|
|
1122
|
+
async function et(e) {
|
|
1123
|
+
const t = await te(e);
|
|
1124
|
+
return t && Date.now() - t.savedAt > Ge ? (await te(e, null), null) : t || null;
|
|
1067
1125
|
}
|
|
1068
|
-
const
|
|
1126
|
+
const xe = [
|
|
1069
1127
|
{ value: "LOW", label: "Low" },
|
|
1070
1128
|
{ value: "MEDIUM", label: "Medium" },
|
|
1071
1129
|
{ value: "HIGH", label: "High" },
|
|
1072
1130
|
{ value: "CRITICAL", label: "Critical" }
|
|
1073
|
-
],
|
|
1074
|
-
function
|
|
1075
|
-
const t = e.attachments !== !1,
|
|
1131
|
+
], ye = "MEDIUM";
|
|
1132
|
+
function tt(e) {
|
|
1133
|
+
const t = e.attachments !== !1, i = t && Le(), w = t && Qe();
|
|
1076
1134
|
return `
|
|
1077
1135
|
<div class="compose">
|
|
1078
1136
|
<div class="field">
|
|
@@ -1093,8 +1151,8 @@ function Ge(e) {
|
|
|
1093
1151
|
<div class="field">
|
|
1094
1152
|
<label id="bc-prio-l">How much is it getting in your way?</label>
|
|
1095
1153
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
1096
|
-
${
|
|
1097
|
-
<button type="button" data-prio="${
|
|
1154
|
+
${xe.map((b) => `
|
|
1155
|
+
<button type="button" data-prio="${b.value}" aria-pressed="${b.value === ye}">${b.label}</button>
|
|
1098
1156
|
`).join("")}
|
|
1099
1157
|
</div>
|
|
1100
1158
|
</div>
|
|
@@ -1105,8 +1163,8 @@ function Ge(e) {
|
|
|
1105
1163
|
<span class="count" aria-live="polite"></span>
|
|
1106
1164
|
</div>
|
|
1107
1165
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1108
|
-
${
|
|
1109
|
-
${
|
|
1166
|
+
${i ? `<button class="tool" type="button" data-act="shot">${Ve}Screenshot</button>` : ""}
|
|
1167
|
+
${w ? `<button class="tool" type="button" data-act="rec">${je}Record screen</button>` : ""}
|
|
1110
1168
|
<button class="tool" type="button" data-act="file">${fe}Upload file</button>
|
|
1111
1169
|
</div>
|
|
1112
1170
|
<div class="thumbs"></div>
|
|
@@ -1114,1162 +1172,1227 @@ function Ge(e) {
|
|
|
1114
1172
|
</div>` : ""}
|
|
1115
1173
|
</div>`;
|
|
1116
1174
|
}
|
|
1117
|
-
function
|
|
1118
|
-
var
|
|
1175
|
+
function at(e) {
|
|
1176
|
+
var oe, K, U, M;
|
|
1119
1177
|
const {
|
|
1120
1178
|
client: t,
|
|
1121
|
-
cfg:
|
|
1122
|
-
root:
|
|
1123
|
-
host:
|
|
1179
|
+
cfg: i,
|
|
1180
|
+
root: w,
|
|
1181
|
+
host: b,
|
|
1124
1182
|
dock: T,
|
|
1125
|
-
scrim:
|
|
1126
|
-
$:
|
|
1127
|
-
say:
|
|
1128
|
-
titleInput:
|
|
1129
|
-
descInput:
|
|
1130
|
-
compose:
|
|
1131
|
-
sendBtn:
|
|
1132
|
-
note:
|
|
1133
|
-
} = e,
|
|
1134
|
-
let
|
|
1135
|
-
const
|
|
1136
|
-
|
|
1137
|
-
const
|
|
1138
|
-
let
|
|
1139
|
-
function
|
|
1140
|
-
if (clearTimeout(
|
|
1141
|
-
const
|
|
1142
|
-
title:
|
|
1143
|
-
description:
|
|
1144
|
-
priority:
|
|
1145
|
-
items:
|
|
1183
|
+
scrim: x,
|
|
1184
|
+
$: g,
|
|
1185
|
+
say: m,
|
|
1186
|
+
titleInput: l,
|
|
1187
|
+
descInput: d,
|
|
1188
|
+
compose: L,
|
|
1189
|
+
sendBtn: y,
|
|
1190
|
+
note: k
|
|
1191
|
+
} = e, S = g(".thumbs"), q = x.querySelector("input[type=file]"), E = [];
|
|
1192
|
+
let n = ye, p = null;
|
|
1193
|
+
const a = document.createElement("div");
|
|
1194
|
+
a.setAttribute("role", "status"), a.className = "note", L.prepend(a);
|
|
1195
|
+
const s = Je(i, (oe = t.signedInAs()) == null ? void 0 : oe.email);
|
|
1196
|
+
let u = i.drafts === !1, r = !1, o = Promise.resolve(), f;
|
|
1197
|
+
function $() {
|
|
1198
|
+
if (clearTimeout(f), !u || r || i.drafts === !1) return o;
|
|
1199
|
+
const c = l.value || d.value || E.length ? {
|
|
1200
|
+
title: l.value,
|
|
1201
|
+
description: d.value,
|
|
1202
|
+
priority: n,
|
|
1203
|
+
items: E.map(({ blob: Q, mime: I, kind: C }) => ({ blob: Q, mime: I, kind: C }))
|
|
1146
1204
|
} : null;
|
|
1147
|
-
return
|
|
1148
|
-
}).then(() =>
|
|
1149
|
-
|
|
1205
|
+
return o = o.catch(() => {
|
|
1206
|
+
}).then(() => te(s, c)).then(() => {
|
|
1207
|
+
a.textContent = c ? "Draft saved on this device" : "";
|
|
1150
1208
|
}).catch(() => {
|
|
1151
|
-
|
|
1152
|
-
}),
|
|
1209
|
+
a.textContent = "Draft could not be saved. Keep this tab open.";
|
|
1210
|
+
}), o;
|
|
1153
1211
|
}
|
|
1154
1212
|
function A() {
|
|
1155
|
-
clearTimeout(
|
|
1213
|
+
clearTimeout(f), f = setTimeout($, 250);
|
|
1156
1214
|
}
|
|
1157
|
-
|
|
1158
|
-
const
|
|
1159
|
-
|
|
1215
|
+
L.addEventListener("input", A), L.addEventListener("change", A);
|
|
1216
|
+
const j = () => {
|
|
1217
|
+
$();
|
|
1160
1218
|
};
|
|
1161
|
-
window.addEventListener("pagehide",
|
|
1162
|
-
function
|
|
1163
|
-
|
|
1219
|
+
window.addEventListener("pagehide", j);
|
|
1220
|
+
function B() {
|
|
1221
|
+
E.filter((c) => c.status === "failed").forEach(D);
|
|
1164
1222
|
}
|
|
1165
|
-
window.addEventListener("online",
|
|
1166
|
-
e.closed || !
|
|
1167
|
-
|
|
1168
|
-
for (const
|
|
1169
|
-
|
|
1170
|
-
},
|
|
1171
|
-
|
|
1223
|
+
window.addEventListener("online", B), i.drafts !== !1 && (L.inert = !0, et(s).then((c) => {
|
|
1224
|
+
e.closed || !c || (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 = () => {
|
|
1225
|
+
l.value = c.title || "", d.value = c.description || "", n = xe.some((Q) => Q.value === c.priority) ? c.priority : "MEDIUM", x.querySelectorAll("[data-prio]").forEach((Q) => Q.setAttribute("aria-pressed", String(Q.dataset.prio === n)));
|
|
1226
|
+
for (const Q of (c.items || []).slice(0, i.maxAttachments ?? 5)) O(Q);
|
|
1227
|
+
u = !0, $();
|
|
1228
|
+
}, a.querySelector("[data-discard]").onclick = () => {
|
|
1229
|
+
u = !0, $();
|
|
1172
1230
|
});
|
|
1173
1231
|
}).catch(() => {
|
|
1174
|
-
|
|
1232
|
+
a.textContent = "Draft storage is unavailable. Keep this tab open.";
|
|
1175
1233
|
}).finally(() => {
|
|
1176
|
-
|
|
1234
|
+
L.inert = !1, a.querySelector("[data-resume]") || (u = !0);
|
|
1177
1235
|
})), e.onDestroy(() => {
|
|
1178
|
-
var
|
|
1179
|
-
|
|
1180
|
-
}),
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1236
|
+
var c;
|
|
1237
|
+
$(), clearTimeout(f), window.removeEventListener("pagehide", j), window.removeEventListener("online", B), p == null || p.cancel(), E.forEach((Q) => Q.previewUrl && URL.revokeObjectURL(Q.previewUrl)), (c = w.querySelector(".recbar")) == null || c.remove();
|
|
1238
|
+
}), x.querySelectorAll("[data-prio]").forEach((c) => {
|
|
1239
|
+
c.addEventListener("click", () => {
|
|
1240
|
+
n = c.dataset.prio, A(), x.querySelectorAll("[data-prio]").forEach((Q) => {
|
|
1241
|
+
Q.setAttribute("aria-pressed", String(Q === c));
|
|
1184
1242
|
});
|
|
1185
1243
|
});
|
|
1186
1244
|
});
|
|
1187
|
-
const
|
|
1188
|
-
function
|
|
1189
|
-
|
|
1245
|
+
const N = g("#bc-title-err");
|
|
1246
|
+
function h(c) {
|
|
1247
|
+
N.hidden = !c, N.innerHTML = c ? `${G}<span>${v(c)}</span>` : "", l.classList.toggle("invalid", !!c), l.setAttribute("aria-invalid", String(!!c));
|
|
1190
1248
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1249
|
+
l.addEventListener("input", () => {
|
|
1250
|
+
l.value.trim() && h("");
|
|
1193
1251
|
});
|
|
1194
|
-
function
|
|
1195
|
-
const
|
|
1196
|
-
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1199
|
-
C.disabled = e.sending ||
|
|
1252
|
+
function z() {
|
|
1253
|
+
const c = E.some((C) => C.status === "uploading");
|
|
1254
|
+
y.disabled = e.sending || c || E.some((C) => C.status === "failed"), k.textContent = c ? "Waiting for the upload to finish…" : E.some((C) => C.status === "failed") ? "Retry or remove failed attachments before sending." : "";
|
|
1255
|
+
const Q = i.maxAttachments ?? 5;
|
|
1256
|
+
x.querySelectorAll(".tool").forEach((C) => {
|
|
1257
|
+
C.disabled = e.sending || E.length >= Q;
|
|
1200
1258
|
});
|
|
1201
|
-
const I =
|
|
1202
|
-
I && (I.textContent =
|
|
1259
|
+
const I = g(".field-head .count");
|
|
1260
|
+
I && (I.textContent = E.length ? `${E.length} of ${Q}` : "");
|
|
1203
1261
|
}
|
|
1204
|
-
e.refreshSendState =
|
|
1205
|
-
function
|
|
1262
|
+
e.refreshSendState = z;
|
|
1263
|
+
function R(c) {
|
|
1206
1264
|
var Y;
|
|
1207
|
-
const
|
|
1208
|
-
let
|
|
1209
|
-
|
|
1265
|
+
const Q = c.el, I = c.kind === "VIDEO" ? "Video" : "Shot", C = c.kind === "VIDEO" ? `<video src="${c.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${c.previewUrl}" alt="" />`;
|
|
1266
|
+
let V = "";
|
|
1267
|
+
c.status === "uploading" ? V = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(c.progress * 100)}%"></i></div></div>` : c.status === "failed" && (V = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Be}</button>Failed</div>`), Q.innerHTML = `
|
|
1210
1268
|
${C}
|
|
1211
|
-
<span class="kind">${I} · ${P(
|
|
1212
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${I.toLowerCase()}">${
|
|
1213
|
-
${
|
|
1269
|
+
<span class="kind">${I} · ${P(c.size)}</span>
|
|
1270
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${I.toLowerCase()}">${ce}</button>
|
|
1271
|
+
${V}`, Q.querySelector('[data-act="drop"]').addEventListener("click", () => H(c)), (Y = Q.querySelector('[data-act="retry"]')) == null || Y.addEventListener("click", () => D(c));
|
|
1214
1272
|
}
|
|
1215
|
-
function
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1273
|
+
function H(c) {
|
|
1274
|
+
const Q = E.indexOf(c);
|
|
1275
|
+
Q >= 0 && E.splice(Q, 1), c.previewUrl && URL.revokeObjectURL(c.previewUrl), c.el.remove(), $(), z();
|
|
1218
1276
|
}
|
|
1219
|
-
async function
|
|
1220
|
-
|
|
1277
|
+
async function D(c) {
|
|
1278
|
+
c.status = "uploading", c.progress = 0, R(c), z();
|
|
1221
1279
|
try {
|
|
1222
|
-
const { storageKey:
|
|
1223
|
-
|
|
1224
|
-
const
|
|
1225
|
-
|
|
1280
|
+
const { storageKey: Q, mime: I } = await t.uploadAttachment(c.blob, c.mime, (C) => {
|
|
1281
|
+
c.progress = C;
|
|
1282
|
+
const V = c.el.querySelector(".bar i");
|
|
1283
|
+
V && (V.style.width = `${Math.round(C * 100)}%`);
|
|
1226
1284
|
});
|
|
1227
|
-
|
|
1228
|
-
} catch (
|
|
1229
|
-
|
|
1285
|
+
c.storageKey = Q, c.mime = I, c.status = "ready";
|
|
1286
|
+
} catch (Q) {
|
|
1287
|
+
c.status = "failed", m(Q.message.replace("[BugCatch] ", ""));
|
|
1230
1288
|
}
|
|
1231
|
-
|
|
1289
|
+
R(c), z();
|
|
1232
1290
|
}
|
|
1233
|
-
function
|
|
1234
|
-
const C =
|
|
1235
|
-
if (
|
|
1236
|
-
|
|
1291
|
+
function O({ blob: c, mime: Q, kind: I }) {
|
|
1292
|
+
const C = i.maxAttachmentBytes ?? 26214400;
|
|
1293
|
+
if (c.size > C) {
|
|
1294
|
+
m(`That file is ${P(c.size)} — the limit is ${P(C)}.`);
|
|
1237
1295
|
return;
|
|
1238
1296
|
}
|
|
1239
|
-
const
|
|
1240
|
-
if (!
|
|
1241
|
-
|
|
1297
|
+
const V = Te(Q || c.type, be);
|
|
1298
|
+
if (!V) {
|
|
1299
|
+
m("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
|
|
1242
1300
|
return;
|
|
1243
1301
|
}
|
|
1244
1302
|
const Y = {
|
|
1245
|
-
blob:
|
|
1303
|
+
blob: c,
|
|
1246
1304
|
kind: I,
|
|
1247
|
-
mime:
|
|
1248
|
-
size:
|
|
1249
|
-
previewUrl: URL.createObjectURL(
|
|
1305
|
+
mime: V,
|
|
1306
|
+
size: c.size,
|
|
1307
|
+
previewUrl: URL.createObjectURL(c),
|
|
1250
1308
|
status: "uploading",
|
|
1251
1309
|
progress: 0,
|
|
1252
1310
|
storageKey: null,
|
|
1253
1311
|
el: document.createElement("div")
|
|
1254
1312
|
};
|
|
1255
|
-
Y.el.className = "thumb",
|
|
1313
|
+
Y.el.className = "thumb", E.push(Y), S.appendChild(Y.el), m(""), $(), D(Y);
|
|
1256
1314
|
}
|
|
1257
|
-
async function
|
|
1258
|
-
|
|
1315
|
+
async function X(c) {
|
|
1316
|
+
b.style.opacity = "0", b.style.pointerEvents = "none", await new Promise((Q) => requestAnimationFrame(() => requestAnimationFrame(Q)));
|
|
1259
1317
|
try {
|
|
1260
|
-
return await
|
|
1318
|
+
return await c();
|
|
1261
1319
|
} finally {
|
|
1262
|
-
|
|
1320
|
+
b.style.opacity = "", b.style.pointerEvents = "";
|
|
1263
1321
|
}
|
|
1264
1322
|
}
|
|
1265
|
-
(
|
|
1323
|
+
(K = x.querySelector('[data-act="shot"]')) == null || K.addEventListener("click", async () => {
|
|
1266
1324
|
try {
|
|
1267
|
-
const
|
|
1268
|
-
|
|
1269
|
-
} catch (
|
|
1270
|
-
(
|
|
1325
|
+
const c = await X(Ee);
|
|
1326
|
+
O(c);
|
|
1327
|
+
} catch (c) {
|
|
1328
|
+
(c == null ? void 0 : c.name) !== "NotAllowedError" && m(`Screenshot failed: ${c.message}`);
|
|
1271
1329
|
}
|
|
1272
|
-
}), (U =
|
|
1273
|
-
const
|
|
1274
|
-
[...
|
|
1275
|
-
|
|
1276
|
-
blob:
|
|
1277
|
-
mime:
|
|
1278
|
-
kind:
|
|
1330
|
+
}), (U = x.querySelector('[data-act="file"]')) == null || U.addEventListener("click", () => q.click()), q == null || q.addEventListener("change", () => {
|
|
1331
|
+
const c = (i.maxAttachments ?? 5) - E.length;
|
|
1332
|
+
[...q.files].slice(0, Math.max(c, 0)).forEach((Q) => {
|
|
1333
|
+
O({
|
|
1334
|
+
blob: Q,
|
|
1335
|
+
mime: Q.type,
|
|
1336
|
+
kind: Q.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
|
|
1279
1337
|
});
|
|
1280
|
-
}),
|
|
1281
|
-
}), (
|
|
1282
|
-
const
|
|
1283
|
-
let
|
|
1338
|
+
}), q.value = "";
|
|
1339
|
+
}), (M = x.querySelector('[data-act="rec"]')) == null || M.addEventListener("click", async () => {
|
|
1340
|
+
const c = i.maxRecordingMs ?? 12e4;
|
|
1341
|
+
let Q;
|
|
1284
1342
|
try {
|
|
1285
|
-
|
|
1286
|
-
maxMs:
|
|
1343
|
+
p = await qe({
|
|
1344
|
+
maxMs: c,
|
|
1287
1345
|
onTick: (I) => {
|
|
1288
|
-
|
|
1346
|
+
Q && (Q.querySelector(".time").textContent = ee(I));
|
|
1289
1347
|
},
|
|
1290
1348
|
onAutoStop: () => {
|
|
1291
|
-
|
|
1349
|
+
p && W({ keep: !0 });
|
|
1292
1350
|
}
|
|
1293
1351
|
});
|
|
1294
1352
|
} catch (I) {
|
|
1295
|
-
(I == null ? void 0 : I.name) !== "NotAllowedError" &&
|
|
1353
|
+
(I == null ? void 0 : I.name) !== "NotAllowedError" && m(`Recording failed: ${I.message}`);
|
|
1296
1354
|
return;
|
|
1297
1355
|
}
|
|
1298
|
-
|
|
1356
|
+
x.style.display = "none", T.hidden = !0, Q = document.createElement("div"), Q.className = "recbar", Q.innerHTML = `
|
|
1299
1357
|
<span class="dot"></span>
|
|
1300
1358
|
<span class="time">0:00</span>
|
|
1301
|
-
<span class="hint">Recording — up to ${
|
|
1359
|
+
<span class="hint">Recording — up to ${ee(Math.round(c / 1e3))}</span>
|
|
1302
1360
|
<button class="stop" type="button">Stop</button>
|
|
1303
|
-
<button class="ghost" type="button">Discard</button>`,
|
|
1361
|
+
<button class="ghost" type="button">Discard</button>`, Q.querySelector(".stop").addEventListener("click", () => W({ keep: !0 })), Q.querySelector(".ghost").addEventListener("click", () => W({ keep: !1 })), w.appendChild(Q), Q.querySelector(".stop").focus();
|
|
1304
1362
|
});
|
|
1305
|
-
async function
|
|
1363
|
+
async function W({ keep: c }) {
|
|
1306
1364
|
var I;
|
|
1307
|
-
const
|
|
1308
|
-
if (
|
|
1309
|
-
if (
|
|
1310
|
-
|
|
1365
|
+
const Q = p;
|
|
1366
|
+
if (Q) {
|
|
1367
|
+
if (p = null, (I = w.querySelector(".recbar")) == null || I.remove(), x.style.display = "", T.hidden = !1, !c) {
|
|
1368
|
+
Q.cancel(), l.focus();
|
|
1311
1369
|
return;
|
|
1312
1370
|
}
|
|
1313
1371
|
try {
|
|
1314
|
-
const C = await
|
|
1315
|
-
C.blob.size ?
|
|
1372
|
+
const C = await Q.stop();
|
|
1373
|
+
C.blob.size ? O(C) : m("That recording came back empty — nothing was captured.");
|
|
1316
1374
|
} catch (C) {
|
|
1317
|
-
|
|
1375
|
+
m(`Recording failed: ${C.message}`);
|
|
1318
1376
|
}
|
|
1319
|
-
|
|
1377
|
+
l.focus();
|
|
1320
1378
|
}
|
|
1321
1379
|
}
|
|
1322
|
-
e.isRecording = () => !!
|
|
1380
|
+
e.isRecording = () => !!p, e.stopRecording = W, y.addEventListener("click", async () => {
|
|
1323
1381
|
var I;
|
|
1324
|
-
const
|
|
1325
|
-
if (!
|
|
1326
|
-
|
|
1382
|
+
const c = l.value;
|
|
1383
|
+
if (!c.trim()) {
|
|
1384
|
+
h("Add a few words about what went wrong — a short sentence is plenty."), l.focus();
|
|
1327
1385
|
return;
|
|
1328
1386
|
}
|
|
1329
1387
|
if (e.holdForReference()) return;
|
|
1330
|
-
e.sending = !0,
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1388
|
+
e.sending = !0, m(""), z();
|
|
1389
|
+
const Q = y.innerHTML;
|
|
1390
|
+
y.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
|
|
1333
1391
|
try {
|
|
1334
1392
|
const C = await t.report({
|
|
1335
|
-
title:
|
|
1336
|
-
description:
|
|
1337
|
-
priority:
|
|
1393
|
+
title: c,
|
|
1394
|
+
description: d.value,
|
|
1395
|
+
priority: n,
|
|
1338
1396
|
references: e.answeredReference(),
|
|
1339
1397
|
issue: ((I = e.pickedIssue()) == null ? void 0 : I.key) || null,
|
|
1340
|
-
attachments:
|
|
1398
|
+
attachments: E.filter((V) => V.status === "ready").map((V) => ({ type: V.kind, storageKey: V.storageKey, mime: V.mime }))
|
|
1341
1399
|
});
|
|
1342
1400
|
if (C != null && C.cancelled) {
|
|
1343
|
-
e.sending = !1,
|
|
1401
|
+
e.sending = !1, y.innerHTML = Q, z();
|
|
1344
1402
|
return;
|
|
1345
1403
|
}
|
|
1346
|
-
|
|
1404
|
+
r = !0, clearTimeout(f), await o, i.drafts !== !1 && await te(s, null).catch(() => {
|
|
1347
1405
|
}), e.succeed(C);
|
|
1348
1406
|
} catch (C) {
|
|
1349
|
-
e.sending = !1,
|
|
1407
|
+
e.sending = !1, y.innerHTML = Q, m(C.message.replace("[BugCatch] ", "")), z(), e.recheckSignIn();
|
|
1350
1408
|
}
|
|
1351
1409
|
});
|
|
1352
1410
|
}
|
|
1353
|
-
function
|
|
1411
|
+
function nt(e) {
|
|
1354
1412
|
const {
|
|
1355
1413
|
client: t,
|
|
1356
|
-
say:
|
|
1357
|
-
titleInput:
|
|
1358
|
-
descInput:
|
|
1414
|
+
say: i,
|
|
1415
|
+
titleInput: w,
|
|
1416
|
+
descInput: b,
|
|
1359
1417
|
sendBtn: T,
|
|
1360
|
-
refsBox:
|
|
1418
|
+
refsBox: x
|
|
1361
1419
|
} = e;
|
|
1362
|
-
let
|
|
1363
|
-
t.referenceFields().then((
|
|
1364
|
-
|
|
1420
|
+
let g = { policy: "off", fields: [] }, m = !1, l = null, d = "", L = "", y = [], k = "ask", S = !1, q = !1;
|
|
1421
|
+
t.referenceFields().then((h) => {
|
|
1422
|
+
g = h, u();
|
|
1365
1423
|
}).catch(() => {
|
|
1366
1424
|
});
|
|
1367
|
-
function
|
|
1368
|
-
return
|
|
1425
|
+
function E() {
|
|
1426
|
+
return g.policy === "off" || !g.fields.length ? { found: [], conflicts: [], loose: [] } : ze(g.fields, [w.value, b.value]);
|
|
1369
1427
|
}
|
|
1370
|
-
function
|
|
1371
|
-
return
|
|
1428
|
+
function n(h = E()) {
|
|
1429
|
+
return h.found.length > 0 && h.conflicts.length === 0;
|
|
1372
1430
|
}
|
|
1373
|
-
function
|
|
1374
|
-
return !
|
|
1431
|
+
function p() {
|
|
1432
|
+
return !l || !d.trim() ? [] : [{ key: l, value: d.trim().slice(0, 120) }];
|
|
1375
1433
|
}
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
let
|
|
1379
|
-
function
|
|
1380
|
-
const
|
|
1381
|
-
if (
|
|
1382
|
-
const
|
|
1383
|
-
|
|
1434
|
+
const a = document.createElement("p");
|
|
1435
|
+
a.className = "ref-found", a.setAttribute("aria-live", "polite"), a.hidden = !0, b.closest(".field").after(a);
|
|
1436
|
+
let s;
|
|
1437
|
+
function u() {
|
|
1438
|
+
const h = E();
|
|
1439
|
+
if (n(h)) {
|
|
1440
|
+
const z = h.found.slice(0, 2).map((R) => `${v(R.label)} <b>${v(o(R.value))}</b>`).join(", ");
|
|
1441
|
+
a.innerHTML = `${F}<span>Found your ${z} — no need to add it again.</span>`, a.hidden = !1, m && !p().length && (m = !1, A());
|
|
1384
1442
|
} else
|
|
1385
|
-
|
|
1443
|
+
a.hidden = !0, a.innerHTML = "";
|
|
1386
1444
|
}
|
|
1387
|
-
const
|
|
1388
|
-
clearTimeout(
|
|
1445
|
+
const r = () => {
|
|
1446
|
+
clearTimeout(s), s = setTimeout(u, 250);
|
|
1389
1447
|
};
|
|
1390
|
-
|
|
1391
|
-
function
|
|
1392
|
-
return
|
|
1448
|
+
w.addEventListener("input", r), b.addEventListener("input", r);
|
|
1449
|
+
function o(h) {
|
|
1450
|
+
return h.length > 20 ? `${h.slice(0, 8)}…${h.slice(-4)}` : h;
|
|
1393
1451
|
}
|
|
1394
|
-
function
|
|
1395
|
-
const
|
|
1396
|
-
return
|
|
1452
|
+
function f(h) {
|
|
1453
|
+
const z = h.trim().toLowerCase();
|
|
1454
|
+
return y.find((R) => R.value.toLowerCase() === z) || null;
|
|
1397
1455
|
}
|
|
1398
|
-
function
|
|
1399
|
-
|
|
1456
|
+
function $(h) {
|
|
1457
|
+
d = h.value, h.kinds.length === 1 ? l = h.kinds[0].key : h.kinds.some((z) => z.key === l) || (l = null), L = "", q = !1;
|
|
1400
1458
|
}
|
|
1401
1459
|
function A() {
|
|
1402
|
-
var
|
|
1403
|
-
if (!
|
|
1404
|
-
|
|
1460
|
+
var K, U;
|
|
1461
|
+
if (!m) {
|
|
1462
|
+
x.hidden = !0, x.innerHTML = "";
|
|
1405
1463
|
return;
|
|
1406
1464
|
}
|
|
1407
|
-
const
|
|
1408
|
-
confirm:
|
|
1465
|
+
const h = g.fields.find((M) => M.key === l) || null, z = g.policy !== "required", R = f(d), H = R && R.kinds.length > 1 ? g.fields.filter((M) => R.kinds.some((c) => c.key === M.key)) : g.fields, D = y.length > 1 && y.every((M) => M.kinds.length === 1 && M.kinds[0].key === y[0].kinds[0].key), O = {
|
|
1466
|
+
confirm: y.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."],
|
|
1409
1467
|
suggest: ["Is this your ID?", "We spotted this in your message. Tell us what it is so we can find your record."],
|
|
1410
|
-
ask:
|
|
1411
|
-
}[
|
|
1412
|
-
|
|
1413
|
-
const
|
|
1414
|
-
|
|
1468
|
+
ask: z ? ["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."]
|
|
1469
|
+
}[k];
|
|
1470
|
+
x.hidden = !1;
|
|
1471
|
+
const X = H.length > 6;
|
|
1472
|
+
x.innerHTML = `
|
|
1415
1473
|
<div class="ask-head">
|
|
1416
|
-
<span class="avatar" aria-hidden="true"
|
|
1474
|
+
<span class="avatar orb" aria-hidden="true"></span>
|
|
1417
1475
|
<div>
|
|
1418
|
-
<strong>${
|
|
1419
|
-
<p class="why">${
|
|
1476
|
+
<strong>${v(O[0])}</strong>
|
|
1477
|
+
<p class="why">${v(O[1])}</p>
|
|
1420
1478
|
</div>
|
|
1421
1479
|
</div>
|
|
1422
|
-
${
|
|
1480
|
+
${y.length > 1 ? `
|
|
1423
1481
|
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1424
|
-
${
|
|
1425
|
-
<button type="button" data-ref-cand="${
|
|
1426
|
-
aria-pressed="${!!
|
|
1482
|
+
${y.map((M, c) => `
|
|
1483
|
+
<button type="button" data-ref-cand="${c}" title="${v(M.value)}"
|
|
1484
|
+
aria-pressed="${!!R && R === M}">${v(o(M.value))}</button>
|
|
1427
1485
|
`).join("")}
|
|
1428
1486
|
</div>` : ""}
|
|
1429
|
-
${
|
|
1487
|
+
${H.length > 1 && !X && !D ? `
|
|
1430
1488
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1431
|
-
${
|
|
1432
|
-
<button type="button" data-ref-kind="${
|
|
1489
|
+
${H.map((M) => `
|
|
1490
|
+
<button type="button" data-ref-kind="${v(M.key)}" aria-pressed="${!!h && M.key === h.key}">${v(M.label)}</button>
|
|
1433
1491
|
`).join("")}
|
|
1434
1492
|
</div>` : ""}
|
|
1435
1493
|
<div class="row">
|
|
1436
|
-
${
|
|
1494
|
+
${X ? `
|
|
1437
1495
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1438
|
-
${
|
|
1439
|
-
${
|
|
1440
|
-
<option value="${
|
|
1496
|
+
${h ? "" : '<option value="" selected disabled>What is it?</option>'}
|
|
1497
|
+
${H.map((M) => `
|
|
1498
|
+
<option value="${v(M.key)}" ${h && M.key === h.key ? "selected" : ""}>${v(M.label)}</option>
|
|
1441
1499
|
`).join("")}
|
|
1442
1500
|
</select>` : ""}
|
|
1443
|
-
<input class="ref-value${
|
|
1444
|
-
inputmode="${
|
|
1445
|
-
value="${
|
|
1446
|
-
placeholder="${
|
|
1447
|
-
aria-label="${
|
|
1501
|
+
<input class="ref-value${L ? " invalid" : ""}" type="${(h == null ? void 0 : h.inputMode) === "email" ? "email" : "text"}"
|
|
1502
|
+
inputmode="${v((h == null ? void 0 : h.inputMode) === "numeric" || (h == null ? void 0 : h.inputMode) === "tel" ? "numeric" : "text")}"
|
|
1503
|
+
value="${v(d)}"
|
|
1504
|
+
placeholder="${v(h ? h.placeholder || h.label : "Your ID")}"
|
|
1505
|
+
aria-label="${v(h ? h.label : "Your ID")}" ${L ? 'aria-invalid="true"' : ""} />
|
|
1448
1506
|
</div>
|
|
1449
|
-
${
|
|
1450
|
-
${
|
|
1451
|
-
${
|
|
1452
|
-
|
|
1453
|
-
|
|
1507
|
+
${h != null && h.hint ? `<p class="hint">${v(h.hint)}</p>` : ""}
|
|
1508
|
+
${L ? `<p class="field-err" role="alert">${G}<span>${v(L)}</span></p>` : ""}
|
|
1509
|
+
${z ? `<button type="button" class="link" data-act="ref-skip">${k === "ask" ? "I don't have this — send without it" : "Not sure — send as it is"}</button>` : ""}`, x.querySelectorAll("[data-ref-cand]").forEach((M) => {
|
|
1510
|
+
M.addEventListener("click", () => {
|
|
1511
|
+
$(y[Number(M.dataset.refCand)]), A();
|
|
1454
1512
|
});
|
|
1455
|
-
}),
|
|
1456
|
-
|
|
1457
|
-
|
|
1513
|
+
}), x.querySelectorAll("[data-ref-kind]").forEach((M) => {
|
|
1514
|
+
M.addEventListener("click", () => {
|
|
1515
|
+
l = M.dataset.refKind, L = "", q = !1, A();
|
|
1458
1516
|
});
|
|
1459
1517
|
});
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
}),
|
|
1464
|
-
|
|
1465
|
-
}), (
|
|
1466
|
-
var
|
|
1467
|
-
|
|
1468
|
-
}), (U =
|
|
1469
|
-
|
|
1470
|
-
}), ((!
|
|
1518
|
+
const W = x.querySelector(".ref-value");
|
|
1519
|
+
W.addEventListener("input", () => {
|
|
1520
|
+
d = W.value, L = "", q = !1;
|
|
1521
|
+
}), W.addEventListener("keydown", (M) => {
|
|
1522
|
+
M.key === "Enter" && (M.preventDefault(), T.click());
|
|
1523
|
+
}), (K = x.querySelector(".ref-kind")) == null || K.addEventListener("change", (M) => {
|
|
1524
|
+
var c;
|
|
1525
|
+
l = M.target.value, L = "", A(), (c = x.querySelector(".ref-value")) == null || c.focus();
|
|
1526
|
+
}), (U = x.querySelector('[data-act="ref-skip"]')) == null || U.addEventListener("click", () => {
|
|
1527
|
+
S = !0, m = !1, l = null, d = "", L = "", q = !1, A(), i("");
|
|
1528
|
+
}), ((!h && d ? x.querySelector("[data-ref-kind], .ref-kind") : null) || W).focus();
|
|
1471
1529
|
}
|
|
1472
|
-
function
|
|
1473
|
-
if (
|
|
1474
|
-
if (
|
|
1530
|
+
function j(h) {
|
|
1531
|
+
if (y = h.conflicts.length ? h.conflicts : h.loose.slice(0, 4), k = h.conflicts.length ? "confirm" : h.loose.length ? "suggest" : "ask", m = !0, y.length)
|
|
1532
|
+
if (y.length === 1) $(y[0]);
|
|
1475
1533
|
else {
|
|
1476
|
-
|
|
1477
|
-
const [
|
|
1478
|
-
|
|
1534
|
+
d = "";
|
|
1535
|
+
const [z] = y;
|
|
1536
|
+
l = y.every((H) => H.kinds.length === 1 && H.kinds[0].key === z.kinds[0].key) ? z.kinds[0].key : null;
|
|
1479
1537
|
}
|
|
1480
1538
|
else
|
|
1481
|
-
|
|
1539
|
+
l = l || g.fields[0].key;
|
|
1482
1540
|
A();
|
|
1483
1541
|
}
|
|
1484
|
-
function O() {
|
|
1485
|
-
if (s.policy === "off" || !s.fields.length || a().length) return !1;
|
|
1486
|
-
const k = d();
|
|
1487
|
-
return l(k) || Q && s.policy !== "required" ? !1 : k;
|
|
1488
|
-
}
|
|
1489
1542
|
function B() {
|
|
1490
|
-
if (
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
if (
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
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;
|
|
1546
|
+
}
|
|
1547
|
+
function N() {
|
|
1548
|
+
if (m && d.trim() && !l)
|
|
1549
|
+
return L = "Pick what this ID is.", A(), !0;
|
|
1550
|
+
const h = B();
|
|
1551
|
+
if (h)
|
|
1552
|
+
return m ? A() : j(h), i(""), !0;
|
|
1553
|
+
if (l && d.trim()) {
|
|
1554
|
+
const z = g.fields.find((R) => R.key === l);
|
|
1555
|
+
if (!q && z && !Me(z, d))
|
|
1556
|
+
return L = `That does not look like a ${z.label.toLowerCase()}. Press Send again to use it anyway.`, q = !0, A(), !0;
|
|
1499
1557
|
}
|
|
1500
1558
|
return !1;
|
|
1501
1559
|
}
|
|
1502
|
-
e.holdForReference =
|
|
1560
|
+
e.holdForReference = N, e.answeredReference = p;
|
|
1503
1561
|
}
|
|
1504
|
-
const
|
|
1505
|
-
function
|
|
1506
|
-
const { client: t, cfg:
|
|
1507
|
-
let
|
|
1562
|
+
const ot = 3;
|
|
1563
|
+
function rt(e) {
|
|
1564
|
+
const { client: t, cfg: i, notices: w } = e;
|
|
1565
|
+
let b = [];
|
|
1508
1566
|
function T() {
|
|
1509
|
-
const
|
|
1510
|
-
|
|
1567
|
+
const g = b.slice(0, ot);
|
|
1568
|
+
w.replaceChildren(...g.map((m) => Ce(m, { where: "panel", onDismiss: x }))), w.hidden = g.length === 0;
|
|
1511
1569
|
}
|
|
1512
|
-
function
|
|
1513
|
-
t.dismissAnnouncement(
|
|
1570
|
+
function x(g) {
|
|
1571
|
+
t.dismissAnnouncement(g), b = b.filter((m) => m !== g), T(), e.titleInput.focus();
|
|
1514
1572
|
}
|
|
1515
|
-
|
|
1516
|
-
e.closed || (
|
|
1573
|
+
i.announcements !== !1 && typeof t.announcements == "function" && t.announcements().then((g) => {
|
|
1574
|
+
e.closed || (b = g, T());
|
|
1517
1575
|
}).catch(() => {
|
|
1518
1576
|
});
|
|
1519
1577
|
}
|
|
1520
|
-
function
|
|
1578
|
+
function it(e) {
|
|
1521
1579
|
const {
|
|
1522
1580
|
client: t,
|
|
1523
|
-
cfg:
|
|
1524
|
-
titleInput:
|
|
1525
|
-
known:
|
|
1581
|
+
cfg: i,
|
|
1582
|
+
titleInput: w,
|
|
1583
|
+
known: b
|
|
1526
1584
|
} = e;
|
|
1527
|
-
let T = [],
|
|
1528
|
-
function
|
|
1529
|
-
|
|
1530
|
-
T =
|
|
1585
|
+
let T = [], x = "", g = null, m = null;
|
|
1586
|
+
function l() {
|
|
1587
|
+
i.knownIssues !== !1 && t.knownIssues().then((S) => {
|
|
1588
|
+
T = S, y();
|
|
1531
1589
|
}).catch(() => {
|
|
1532
1590
|
});
|
|
1533
1591
|
}
|
|
1534
|
-
let
|
|
1535
|
-
function
|
|
1536
|
-
if (
|
|
1537
|
-
clearTimeout(
|
|
1538
|
-
const
|
|
1539
|
-
if (
|
|
1540
|
-
|
|
1592
|
+
let d = null;
|
|
1593
|
+
function L(S) {
|
|
1594
|
+
if (i.knownIssues === !1) return;
|
|
1595
|
+
clearTimeout(d), m == null || m.abort();
|
|
1596
|
+
const q = (S || "").trim();
|
|
1597
|
+
if (q.length < 3) {
|
|
1598
|
+
l();
|
|
1541
1599
|
return;
|
|
1542
1600
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1601
|
+
d = setTimeout(() => {
|
|
1602
|
+
m = new AbortController(), t.matchKnownIssues(q, { signal: m.signal }).then((E) => {
|
|
1603
|
+
E.length && (T = E, y());
|
|
1546
1604
|
}).catch(() => {
|
|
1547
1605
|
});
|
|
1548
1606
|
}, 250);
|
|
1549
1607
|
}
|
|
1550
|
-
function
|
|
1608
|
+
function y() {
|
|
1551
1609
|
if (!T.length) {
|
|
1552
|
-
|
|
1610
|
+
b.hidden = !0, b.innerHTML = "";
|
|
1553
1611
|
return;
|
|
1554
1612
|
}
|
|
1555
|
-
|
|
1613
|
+
b.hidden = !1, b.innerHTML = `
|
|
1556
1614
|
<p class="known-h">Already reported</p>
|
|
1557
|
-
${T.map((
|
|
1558
|
-
<div class="issue ${
|
|
1615
|
+
${T.map((S) => `
|
|
1616
|
+
<div class="issue ${S.joined ? "is-joined" : ""}">
|
|
1559
1617
|
<span class="who">
|
|
1560
|
-
<span class="t">${
|
|
1561
|
-
<span class="meta">${
|
|
1618
|
+
<span class="t">${v(S.title)}</span>
|
|
1619
|
+
<span class="meta">${v(k(S))}</span>
|
|
1562
1620
|
</span>
|
|
1563
|
-
<button class="join" type="button" data-join="${
|
|
1564
|
-
${
|
|
1621
|
+
<button class="join" type="button" data-join="${v(S.id)}"
|
|
1622
|
+
${S.joined ? "disabled" : ""}>${S.joined ? "Following" : "Me too"}</button>
|
|
1565
1623
|
</div>
|
|
1566
|
-
${
|
|
1624
|
+
${g === S.id ? `
|
|
1567
1625
|
<div class="ask">
|
|
1568
1626
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1569
1627
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1570
|
-
<button class="ghost" type="button" data-join-confirm="${
|
|
1628
|
+
<button class="ghost" type="button" data-join-confirm="${v(S.id)}">Follow</button>
|
|
1571
1629
|
</div>` : ""}
|
|
1572
1630
|
`).join("")}
|
|
1573
|
-
${
|
|
1631
|
+
${x ? `<p class="err">${v(x)}</p>` : ""}`;
|
|
1574
1632
|
}
|
|
1575
|
-
function
|
|
1576
|
-
const
|
|
1577
|
-
return `${
|
|
1633
|
+
function k(S) {
|
|
1634
|
+
const q = S.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", E = S.affectedCount === 0 ? "" : ` · ${S.affectedCount} ${S.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
|
|
1635
|
+
return `${q} · reported ${ne(S.since)}${E}`;
|
|
1578
1636
|
}
|
|
1579
|
-
|
|
1580
|
-
var
|
|
1581
|
-
const
|
|
1582
|
-
if (!
|
|
1583
|
-
const
|
|
1584
|
-
|
|
1585
|
-
const
|
|
1586
|
-
if (!
|
|
1587
|
-
|
|
1637
|
+
b.addEventListener("click", async (S) => {
|
|
1638
|
+
var a, s, u, r, o;
|
|
1639
|
+
const q = S.target.closest("[data-join]"), E = S.target.closest("[data-join-confirm]");
|
|
1640
|
+
if (!q && !E) return;
|
|
1641
|
+
const n = (E || q).getAttribute(E ? "data-join-confirm" : "data-join");
|
|
1642
|
+
x = "";
|
|
1643
|
+
const p = ((s = (a = b.querySelector(".join-email")) == null ? void 0 : a.value) == null ? void 0 : s.trim()) || ((u = t.signedInAs()) == null ? void 0 : u.email) || ((r = t.config.user) == null ? void 0 : r.email);
|
|
1644
|
+
if (!p) {
|
|
1645
|
+
g = n, y(), (o = b.querySelector(".join-email")) == null || o.focus();
|
|
1588
1646
|
return;
|
|
1589
1647
|
}
|
|
1590
1648
|
try {
|
|
1591
|
-
const
|
|
1592
|
-
|
|
1593
|
-
} catch (
|
|
1594
|
-
|
|
1649
|
+
const f = await t.meToo(n, { email: p });
|
|
1650
|
+
g = null, T = T.map(($) => $.id === n ? { ...$, joined: !0, affectedCount: f.affectedCount ?? $.affectedCount } : $), y();
|
|
1651
|
+
} catch (f) {
|
|
1652
|
+
x = f.message.replace("[BugCatch] ", ""), y();
|
|
1595
1653
|
}
|
|
1596
|
-
}),
|
|
1654
|
+
}), l(), w.addEventListener("input", () => L(w.value));
|
|
1597
1655
|
}
|
|
1598
|
-
function
|
|
1656
|
+
function st(e) {
|
|
1599
1657
|
const {
|
|
1600
1658
|
client: t,
|
|
1601
|
-
cfg:
|
|
1602
|
-
titleInput:
|
|
1603
|
-
descInput:
|
|
1659
|
+
cfg: i,
|
|
1660
|
+
titleInput: w,
|
|
1661
|
+
descInput: b,
|
|
1604
1662
|
picks: T
|
|
1605
1663
|
} = e;
|
|
1606
|
-
let
|
|
1607
|
-
function
|
|
1608
|
-
if (!
|
|
1664
|
+
let x = [], g = null;
|
|
1665
|
+
function m() {
|
|
1666
|
+
if (!x.length) {
|
|
1609
1667
|
T.hidden = !0, T.innerHTML = "";
|
|
1610
1668
|
return;
|
|
1611
1669
|
}
|
|
1612
1670
|
T.hidden = !1, T.innerHTML = `
|
|
1613
1671
|
<p class="picks-h">Get an answer right away</p>
|
|
1614
1672
|
<div class="picks-grid" role="group" aria-label="Common questions">
|
|
1615
|
-
${
|
|
1616
|
-
<button type="button" class="pick" data-pick="${
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1673
|
+
${x.map((l, d) => `
|
|
1674
|
+
<button type="button" class="pick" data-pick="${v(l.key)}"
|
|
1675
|
+
${l.hint ? `title="${v(l.hint)}" aria-describedby="bc-pick-h${d}"` : ""}
|
|
1676
|
+
aria-pressed="${(g == null ? void 0 : g.key) === l.key}">
|
|
1677
|
+
<span class="t">${v(l.title)}</span>
|
|
1678
|
+
${l.hint ? `<span class="h sr-only" id="bc-pick-h${d}">${v(l.hint)}</span>` : ""}
|
|
1620
1679
|
</button>`).join("")}
|
|
1621
1680
|
</div>
|
|
1622
|
-
${
|
|
1681
|
+
${g ? `<p class="picks-note">${F}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>` : ""}`;
|
|
1623
1682
|
}
|
|
1624
|
-
T.addEventListener("click", (
|
|
1625
|
-
const
|
|
1626
|
-
if (!
|
|
1627
|
-
const
|
|
1628
|
-
if (!
|
|
1629
|
-
const
|
|
1630
|
-
(
|
|
1631
|
-
}),
|
|
1632
|
-
|
|
1683
|
+
T.addEventListener("click", (l) => {
|
|
1684
|
+
const d = l.target.closest("[data-pick]");
|
|
1685
|
+
if (!d) return;
|
|
1686
|
+
const L = x.find((k) => k.key === d.dataset.pick);
|
|
1687
|
+
if (!L) return;
|
|
1688
|
+
const y = g && w.value.trim() === g.title;
|
|
1689
|
+
(g == null ? void 0 : g.key) === L.key ? (g = null, y && (w.value = "")) : (g = L, (!w.value.trim() || y) && (w.value = L.title)), w.dispatchEvent(new Event("input", { bubbles: !0 })), m(), g && b.focus();
|
|
1690
|
+
}), i.agentIssues !== !1 && typeof t.agentIssues == "function" && t.agentIssues().then((l) => {
|
|
1691
|
+
x = l, m();
|
|
1633
1692
|
}).catch(() => {
|
|
1634
|
-
}), e.pickedIssue = () =>
|
|
1693
|
+
}), e.pickedIssue = () => g;
|
|
1635
1694
|
}
|
|
1636
|
-
function
|
|
1695
|
+
function lt(e) {
|
|
1637
1696
|
const {
|
|
1638
1697
|
client: t,
|
|
1639
|
-
scrim:
|
|
1640
|
-
say:
|
|
1641
|
-
callBtn:
|
|
1698
|
+
scrim: i,
|
|
1699
|
+
say: w,
|
|
1700
|
+
callBtn: b,
|
|
1642
1701
|
close: T
|
|
1643
1702
|
} = e;
|
|
1644
|
-
let
|
|
1645
|
-
function
|
|
1646
|
-
t.callKind().then((
|
|
1647
|
-
|
|
1703
|
+
let x = !1;
|
|
1704
|
+
function g() {
|
|
1705
|
+
t.callKind().then((d) => {
|
|
1706
|
+
d && (x = !0, e.preloadCall(), b.hidden = e.mustSignIn());
|
|
1648
1707
|
}).catch(() => {
|
|
1649
1708
|
});
|
|
1650
1709
|
}
|
|
1651
|
-
|
|
1652
|
-
e.sending = !0,
|
|
1710
|
+
g(), b.addEventListener("click", async () => {
|
|
1711
|
+
e.sending = !0, w(""), e.refreshSendState(), b.disabled = !0, b.innerHTML = '<span class="spinner"></span>Ringing…';
|
|
1653
1712
|
try {
|
|
1654
|
-
const
|
|
1655
|
-
|
|
1656
|
-
} catch (
|
|
1657
|
-
e.sending = !1,
|
|
1713
|
+
const d = await t.startCall();
|
|
1714
|
+
m(d);
|
|
1715
|
+
} catch (d) {
|
|
1716
|
+
e.sending = !1, b.disabled = !1, b.innerHTML = `${ae}Talk to the team`, e.refreshSendState(), d.filed ? e.succeed(d.filed, { callFailed: d.reason || "The call could not be started." }) : (w(d.message.replace("[BugCatch] ", "")), e.recheckSignIn());
|
|
1658
1717
|
}
|
|
1659
1718
|
});
|
|
1660
|
-
function
|
|
1661
|
-
const
|
|
1662
|
-
|
|
1719
|
+
function m(d) {
|
|
1720
|
+
const L = i.querySelector(".panel"), y = d != null && d.bugId ? String(d.bugId).slice(0, 8) : null;
|
|
1721
|
+
L.innerHTML = `
|
|
1663
1722
|
<div class="call">
|
|
1664
1723
|
<div class="call-head">
|
|
1665
1724
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1666
1725
|
<strong class="call-state">Ringing…</strong>
|
|
1667
1726
|
</div>
|
|
1668
1727
|
<p class="call-note">
|
|
1669
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1728
|
+
We're ringing the team now. Someone will pick up if they're free — your report${y ? ` <code>${v(y)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
|
|
1670
1729
|
</p>
|
|
1671
1730
|
<div class="foot">
|
|
1672
1731
|
<span class="spacer"></span>
|
|
1673
1732
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1674
1733
|
</div>
|
|
1675
1734
|
</div>`;
|
|
1676
|
-
const
|
|
1735
|
+
const k = L.querySelector(".call-state"), S = L.querySelector(".call-dot"), q = {
|
|
1677
1736
|
ringing: "Ringing the team…",
|
|
1678
1737
|
connecting: "Someone answered — connecting…",
|
|
1679
1738
|
connected: "Connected",
|
|
1680
1739
|
missed: "Nobody was free",
|
|
1681
1740
|
ended: "Call ended",
|
|
1682
1741
|
failed: "The call dropped"
|
|
1683
|
-
},
|
|
1684
|
-
if (
|
|
1685
|
-
const
|
|
1686
|
-
|
|
1742
|
+
}, E = ["ended", "failed", "missed"], n = t.on("call", ({ state: p }) => {
|
|
1743
|
+
if (k.textContent = q[p] || p, S.classList.toggle("off", E.includes(p)), E.includes(p) && (L.querySelector('[data-act="hangup"]').textContent = "Close", p === "missed")) {
|
|
1744
|
+
const a = L.querySelector(".call-note");
|
|
1745
|
+
a && (a.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
|
|
1687
1746
|
}
|
|
1688
1747
|
});
|
|
1689
|
-
|
|
1690
|
-
|
|
1748
|
+
L.querySelector('[data-act="hangup"]').addEventListener("click", () => {
|
|
1749
|
+
n(), t.endCall(), T();
|
|
1691
1750
|
});
|
|
1692
1751
|
}
|
|
1693
|
-
function
|
|
1694
|
-
const
|
|
1695
|
-
|
|
1752
|
+
function l(d, L, y) {
|
|
1753
|
+
const k = document.createElement("div");
|
|
1754
|
+
k.className = "livecall", k.innerHTML = `
|
|
1696
1755
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1697
1756
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1698
1757
|
<span class="secs" hidden></span>
|
|
1699
|
-
${
|
|
1758
|
+
${y != null && y.recorded ? '<span class="call-kept">This call is recorded.</span>' : ""}
|
|
1700
1759
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
1701
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1702
|
-
const
|
|
1703
|
-
let
|
|
1704
|
-
const
|
|
1705
|
-
|
|
1706
|
-
},
|
|
1707
|
-
|
|
1708
|
-
},
|
|
1709
|
-
if (
|
|
1710
|
-
|
|
1711
|
-
const
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
}, 1e3),
|
|
1760
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`, d.insertBefore(k, L);
|
|
1761
|
+
const S = k.querySelector(".who"), q = k.querySelector(".secs"), E = k.querySelector(".call-dot"), n = k.querySelector('[data-act="mute"]'), p = k.querySelector('[data-act="hangup"]');
|
|
1762
|
+
let a = null;
|
|
1763
|
+
const s = () => {
|
|
1764
|
+
a && (clearInterval(a), a = null);
|
|
1765
|
+
}, u = (o) => {
|
|
1766
|
+
s(), E.classList.add("off"), k.classList.add("over"), S.textContent = o, q.hidden = !0, n.hidden = !0, p.textContent = "Dismiss", p.classList.remove("danger");
|
|
1767
|
+
}, r = t.on("call", ({ state: o }) => {
|
|
1768
|
+
if (o === "ringing" && (S.textContent = "Calling the team…"), o === "connecting" && (S.textContent = "Someone answered — connecting…"), o === "connected") {
|
|
1769
|
+
S.textContent = "You're on a call with the team", n.hidden = !1, q.hidden = !1;
|
|
1770
|
+
const f = Date.now();
|
|
1771
|
+
s(), a = setInterval(() => {
|
|
1772
|
+
q.textContent = ee(Math.floor((Date.now() - f) / 1e3));
|
|
1773
|
+
}, 1e3), q.textContent = "0s";
|
|
1715
1774
|
}
|
|
1716
|
-
|
|
1775
|
+
o === "missed" && u("Nobody was free. Send a message instead and the team will pick it up."), o === "ended" && u("Call ended."), o === "failed" && u("The call dropped.");
|
|
1717
1776
|
});
|
|
1718
|
-
|
|
1719
|
-
const
|
|
1720
|
-
|
|
1721
|
-
}),
|
|
1722
|
-
|
|
1777
|
+
n.addEventListener("click", () => {
|
|
1778
|
+
const o = y.setMuted(!y.isMuted());
|
|
1779
|
+
n.textContent = o ? "Unmute" : "Mute", S.textContent = o ? "You're muted" : "You're on a call with the team";
|
|
1780
|
+
}), p.addEventListener("click", () => {
|
|
1781
|
+
r(), s(), t.endCall(), k.remove(), e.refreshThread(e.openReportId());
|
|
1723
1782
|
});
|
|
1724
1783
|
}
|
|
1725
|
-
e.offerCall =
|
|
1784
|
+
e.offerCall = g, e.callOffered = () => x, e.showLiveCall = l;
|
|
1726
1785
|
}
|
|
1727
|
-
function
|
|
1728
|
-
var
|
|
1786
|
+
function ct(e) {
|
|
1787
|
+
var r;
|
|
1729
1788
|
const {
|
|
1730
1789
|
client: t,
|
|
1731
|
-
say:
|
|
1732
|
-
compose:
|
|
1733
|
-
sendBtn:
|
|
1790
|
+
say: i,
|
|
1791
|
+
compose: w,
|
|
1792
|
+
sendBtn: b,
|
|
1734
1793
|
historyBtn: T,
|
|
1735
|
-
callBtn:
|
|
1736
|
-
whoami:
|
|
1794
|
+
callBtn: x,
|
|
1795
|
+
whoami: g
|
|
1737
1796
|
} = e;
|
|
1738
|
-
let
|
|
1739
|
-
const
|
|
1740
|
-
function
|
|
1741
|
-
const
|
|
1742
|
-
|
|
1797
|
+
let m = { mode: t.lastLoginMode || "off", signedIn: null }, l = "idle", d = ((r = t.config.user) == null ? void 0 : r.email) || "", L = "", y = !1, k = "";
|
|
1798
|
+
const S = () => m.mode === "required" && !m.signedIn;
|
|
1799
|
+
function q() {
|
|
1800
|
+
const o = S();
|
|
1801
|
+
w.hidden = o, b.hidden = o, T && (T.hidden = o), o ? x.hidden = !0 : e.callOffered() && (x.hidden = !1);
|
|
1743
1802
|
}
|
|
1744
|
-
function
|
|
1745
|
-
var
|
|
1746
|
-
if (
|
|
1747
|
-
|
|
1803
|
+
function E() {
|
|
1804
|
+
var f;
|
|
1805
|
+
if (m.mode === "off") {
|
|
1806
|
+
g.hidden = !0, g.innerHTML = "";
|
|
1748
1807
|
return;
|
|
1749
1808
|
}
|
|
1750
|
-
|
|
1751
|
-
const
|
|
1752
|
-
if (
|
|
1753
|
-
if (
|
|
1754
|
-
|
|
1809
|
+
g.hidden = !1, g.classList.toggle("asking", l !== "idle");
|
|
1810
|
+
const o = k ? `<div class="after err">${v(k)}</div>` : "";
|
|
1811
|
+
if (l === "idle") {
|
|
1812
|
+
if (m.signedIn) {
|
|
1813
|
+
g.innerHTML = `<span class="who">Signed in as <strong>${v(m.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
|
|
1755
1814
|
return;
|
|
1756
1815
|
}
|
|
1757
|
-
const
|
|
1758
|
-
|
|
1816
|
+
const $ = (f = t.config.user) == null ? void 0 : f.email;
|
|
1817
|
+
g.innerHTML = `<span class="who">${m.mode === "required" ? "Sign in to report a bug here." : $ ? `Reporting as <strong>${v($)}</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>`;
|
|
1759
1818
|
return;
|
|
1760
1819
|
}
|
|
1761
|
-
if (
|
|
1762
|
-
|
|
1820
|
+
if (l === "email") {
|
|
1821
|
+
g.innerHTML = `
|
|
1763
1822
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
1764
|
-
It's how you hear back about this report${
|
|
1823
|
+
It's how you hear back about this report${m.mode === "required" ? ", and this project asks for it" : ""}.</p>
|
|
1765
1824
|
<div class="row">
|
|
1766
|
-
<input type="email" data-fld="email" value="${
|
|
1825
|
+
<input type="email" data-fld="email" value="${v(d)}"
|
|
1767
1826
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1768
|
-
aria-label="Your email address" ${
|
|
1769
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1770
|
-
${
|
|
1827
|
+
aria-label="Your email address" ${y ? "disabled" : ""} />
|
|
1828
|
+
<button type="button" class="primary" data-act="code" ${y ? "disabled" : ""}>
|
|
1829
|
+
${y ? "Sending…" : "Send code"}
|
|
1771
1830
|
</button>
|
|
1772
1831
|
</div>
|
|
1773
|
-
${
|
|
1774
|
-
${
|
|
1832
|
+
${o}
|
|
1833
|
+
${m.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
|
|
1775
1834
|
return;
|
|
1776
1835
|
}
|
|
1777
|
-
|
|
1778
|
-
<p class="why">We sent a code to <strong>${
|
|
1836
|
+
g.innerHTML = `
|
|
1837
|
+
<p class="why">We sent a code to <strong>${v(d)}</strong>. It expires in ten minutes.</p>
|
|
1779
1838
|
<div class="row">
|
|
1780
|
-
<input type="text" class="code" data-fld="code" value="${
|
|
1839
|
+
<input type="text" class="code" data-fld="code" value="${v(L)}"
|
|
1781
1840
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
1782
|
-
maxlength="8" aria-label="The code we emailed you" ${
|
|
1783
|
-
<button type="button" class="primary" data-act="confirm" ${
|
|
1784
|
-
${
|
|
1841
|
+
maxlength="8" aria-label="The code we emailed you" ${y ? "disabled" : ""} />
|
|
1842
|
+
<button type="button" class="primary" data-act="confirm" ${y ? "disabled" : ""}>
|
|
1843
|
+
${y ? "Checking…" : "Sign in"}
|
|
1785
1844
|
</button>
|
|
1786
1845
|
</div>
|
|
1787
|
-
${
|
|
1846
|
+
${o}
|
|
1788
1847
|
<div class="after">
|
|
1789
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1790
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1848
|
+
<button type="button" class="link" data-act="resend" ${y ? "disabled" : ""}>Send it again</button>
|
|
1849
|
+
<button type="button" class="link" data-act="signin-back" ${y ? "disabled" : ""}>Use another address</button>
|
|
1791
1850
|
</div>`;
|
|
1792
1851
|
}
|
|
1793
|
-
function
|
|
1794
|
-
var
|
|
1795
|
-
if (
|
|
1796
|
-
const
|
|
1797
|
-
|
|
1852
|
+
function n({ focus: o = !1 } = {}) {
|
|
1853
|
+
var $;
|
|
1854
|
+
if (E(), q(), !o || y) return;
|
|
1855
|
+
const f = g.querySelector("[data-fld]");
|
|
1856
|
+
f && (f.focus(), ($ = f.setSelectionRange) == null || $.call(f, f.value.length, f.value.length));
|
|
1798
1857
|
}
|
|
1799
|
-
|
|
1800
|
-
const
|
|
1801
|
-
|
|
1802
|
-
}),
|
|
1803
|
-
|
|
1858
|
+
g.addEventListener("input", (o) => {
|
|
1859
|
+
const f = o.target.closest("[data-fld]");
|
|
1860
|
+
f && (f.dataset.fld === "email" ? d = f.value : L = f.value);
|
|
1861
|
+
}), g.addEventListener("keydown", (o) => {
|
|
1862
|
+
o.key !== "Enter" || !o.target.closest("[data-fld]") || (o.preventDefault(), l === "email" ? p() : a());
|
|
1804
1863
|
});
|
|
1805
|
-
async function
|
|
1806
|
-
const
|
|
1807
|
-
if (!
|
|
1808
|
-
|
|
1864
|
+
async function p({ resent: o = !1 } = {}) {
|
|
1865
|
+
const f = d.trim();
|
|
1866
|
+
if (!f) {
|
|
1867
|
+
k = "Enter the address to send the code to.", n({ focus: !0 });
|
|
1809
1868
|
return;
|
|
1810
1869
|
}
|
|
1811
|
-
|
|
1870
|
+
y = !0, k = "", n();
|
|
1812
1871
|
try {
|
|
1813
|
-
await t.signIn(
|
|
1814
|
-
} catch (
|
|
1815
|
-
|
|
1872
|
+
await t.signIn(f), d = f, o || (L = ""), l = "code";
|
|
1873
|
+
} catch ($) {
|
|
1874
|
+
k = $.message;
|
|
1816
1875
|
} finally {
|
|
1817
|
-
|
|
1876
|
+
y = !1, n({ focus: !0 });
|
|
1818
1877
|
}
|
|
1819
1878
|
}
|
|
1820
|
-
async function
|
|
1821
|
-
const
|
|
1822
|
-
if (!
|
|
1823
|
-
|
|
1879
|
+
async function a() {
|
|
1880
|
+
const o = L.trim();
|
|
1881
|
+
if (!o) {
|
|
1882
|
+
k = "Enter the code we emailed you.", n({ focus: !0 });
|
|
1824
1883
|
return;
|
|
1825
1884
|
}
|
|
1826
|
-
|
|
1885
|
+
y = !0, k = "", n();
|
|
1827
1886
|
try {
|
|
1828
|
-
const
|
|
1829
|
-
|
|
1830
|
-
} catch (
|
|
1831
|
-
|
|
1887
|
+
const f = await t.confirmSignIn(d.trim(), o);
|
|
1888
|
+
m.signedIn = f, l = "idle", L = "", i(""), e.offerCall();
|
|
1889
|
+
} catch (f) {
|
|
1890
|
+
k = f.message;
|
|
1832
1891
|
} finally {
|
|
1833
|
-
|
|
1892
|
+
y = !1, n({ focus: l !== "idle" });
|
|
1834
1893
|
}
|
|
1835
1894
|
}
|
|
1836
|
-
|
|
1837
|
-
const
|
|
1838
|
-
if (!
|
|
1839
|
-
const
|
|
1840
|
-
if (
|
|
1841
|
-
|
|
1895
|
+
g.addEventListener("click", async (o) => {
|
|
1896
|
+
const f = o.target.closest("button[data-act]");
|
|
1897
|
+
if (!f) return;
|
|
1898
|
+
const $ = f.dataset.act;
|
|
1899
|
+
if ($ === "signin") {
|
|
1900
|
+
l = "email", k = "", n({ focus: !0 });
|
|
1842
1901
|
return;
|
|
1843
1902
|
}
|
|
1844
|
-
if (
|
|
1845
|
-
|
|
1903
|
+
if ($ === "skip") {
|
|
1904
|
+
l = "idle", k = "", n();
|
|
1846
1905
|
return;
|
|
1847
1906
|
}
|
|
1848
|
-
if (
|
|
1849
|
-
|
|
1907
|
+
if ($ === "signin-back") {
|
|
1908
|
+
l = "email", k = "", L = "", n({ focus: !0 });
|
|
1850
1909
|
return;
|
|
1851
1910
|
}
|
|
1852
|
-
if (
|
|
1853
|
-
|
|
1911
|
+
if ($ === "code") {
|
|
1912
|
+
p();
|
|
1854
1913
|
return;
|
|
1855
1914
|
}
|
|
1856
|
-
if (
|
|
1857
|
-
|
|
1915
|
+
if ($ === "resend") {
|
|
1916
|
+
p({ resent: !0 });
|
|
1858
1917
|
return;
|
|
1859
1918
|
}
|
|
1860
|
-
if (
|
|
1861
|
-
|
|
1919
|
+
if ($ === "confirm") {
|
|
1920
|
+
a();
|
|
1862
1921
|
return;
|
|
1863
1922
|
}
|
|
1864
|
-
if (
|
|
1865
|
-
|
|
1923
|
+
if ($ === "signout") {
|
|
1924
|
+
y = !0, n();
|
|
1866
1925
|
try {
|
|
1867
1926
|
await t.signOut();
|
|
1868
1927
|
} finally {
|
|
1869
|
-
|
|
1928
|
+
m.signedIn = null, y = !1, l = m.mode === "required" ? "email" : "idle", n({ focus: l !== "idle" });
|
|
1870
1929
|
}
|
|
1871
1930
|
}
|
|
1872
1931
|
});
|
|
1873
|
-
async function
|
|
1874
|
-
const
|
|
1875
|
-
|
|
1932
|
+
async function s({ announce: o = !1 } = {}) {
|
|
1933
|
+
const f = await t.loginState();
|
|
1934
|
+
m = { mode: f.mode, signedIn: f.signedIn }, t.lastLoginMode = f.mode, S() && l === "idle" && (l = "email"), m.signedIn && (l = "idle"), o && f.signedOutReason && i(f.signedOutReason, "info"), n();
|
|
1876
1935
|
}
|
|
1877
|
-
|
|
1936
|
+
s({ announce: !0 }).catch(() => {
|
|
1878
1937
|
});
|
|
1879
|
-
function
|
|
1880
|
-
|
|
1938
|
+
function u() {
|
|
1939
|
+
m.mode !== "off" && s().catch(() => {
|
|
1881
1940
|
});
|
|
1882
1941
|
}
|
|
1883
|
-
e.mustSignIn =
|
|
1942
|
+
e.mustSignIn = S, e.recheckSignIn = u;
|
|
1884
1943
|
}
|
|
1885
|
-
function
|
|
1944
|
+
function ue(e) {
|
|
1886
1945
|
const t = e || [];
|
|
1887
1946
|
if (!t.length) return "";
|
|
1888
|
-
let
|
|
1889
|
-
return t.map((
|
|
1890
|
-
var
|
|
1891
|
-
const T = Z(
|
|
1892
|
-
if (
|
|
1893
|
-
return
|
|
1894
|
-
const
|
|
1895
|
-
from:
|
|
1896
|
-
author: (
|
|
1897
|
-
automated: (
|
|
1898
|
-
body: (
|
|
1899
|
-
at:
|
|
1900
|
-
attachments: (
|
|
1901
|
-
},
|
|
1902
|
-
return
|
|
1947
|
+
let i = null, w = null;
|
|
1948
|
+
return t.map((b) => {
|
|
1949
|
+
var d, L, y, k;
|
|
1950
|
+
const T = Z(b.at), x = T && T !== i ? `<div class="day-sep" role="separator">${v(_e(b.at))}</div>` : "";
|
|
1951
|
+
if (x && (i = T, w = null), !b.from)
|
|
1952
|
+
return w = null, x + pt(b);
|
|
1953
|
+
const g = {
|
|
1954
|
+
from: b.from,
|
|
1955
|
+
author: (d = b.reply) == null ? void 0 : d.author,
|
|
1956
|
+
automated: (L = b.reply) == null ? void 0 : L.automated,
|
|
1957
|
+
body: (y = b.reply) == null ? void 0 : y.body,
|
|
1958
|
+
at: b.at,
|
|
1959
|
+
attachments: (k = b.reply) == null ? void 0 : k.attachments
|
|
1960
|
+
}, m = dt(g), l = w && w.who === m && Math.abs(new Date(b.at).getTime() - new Date(w.at).getTime()) < 5 * 6e4;
|
|
1961
|
+
return w = { who: m, at: b.at }, x + we(g, l ? "cont" : "");
|
|
1903
1962
|
}).join("");
|
|
1904
1963
|
}
|
|
1905
|
-
function
|
|
1964
|
+
function dt(e) {
|
|
1906
1965
|
return e.from === "reporter" ? "me" : e.automated ? "assistant" : `team:${e.author || ""}`;
|
|
1907
1966
|
}
|
|
1908
|
-
function
|
|
1909
|
-
const t =
|
|
1967
|
+
function pt(e) {
|
|
1968
|
+
const t = ve(e.at);
|
|
1910
1969
|
return `
|
|
1911
|
-
<div class="sys k-${
|
|
1912
|
-
<span class="dot" aria-hidden="true"></span>${
|
|
1913
|
-
<span class="t">· ${
|
|
1970
|
+
<div class="sys k-${v(e.kind)}">
|
|
1971
|
+
<span class="dot" aria-hidden="true"></span>${v(e.summary || "")}${t ? `
|
|
1972
|
+
<span class="t">· ${v(t)}</span>` : ""}
|
|
1914
1973
|
</div>`;
|
|
1915
1974
|
}
|
|
1916
|
-
function
|
|
1917
|
-
const
|
|
1918
|
-
let
|
|
1975
|
+
function we(e, t = "") {
|
|
1976
|
+
const i = e.from === "reporter", w = e.body || "", b = e.attachments || [], T = !i && !!e.automated, x = w ? `<span class="msg-text">${v(w)}</span>` : "", g = b.length ? `<div class="att">${b.map(ht).join("")}</div>` : "";
|
|
1977
|
+
let m = "", l = "";
|
|
1919
1978
|
if (T)
|
|
1920
|
-
|
|
1921
|
-
else if (!
|
|
1922
|
-
const
|
|
1923
|
-
|
|
1979
|
+
m = '<span class="msg-who auto">Assistant <span class="tag">AI</span></span>', l = '<span class="av bot orb" aria-hidden="true"></span>';
|
|
1980
|
+
else if (!i) {
|
|
1981
|
+
const L = e.author || "Support team";
|
|
1982
|
+
m = `<span class="msg-who">${v(L)}</span>`, l = `<span class="av" aria-hidden="true">${v(Ze(L))}</span>`;
|
|
1924
1983
|
}
|
|
1925
|
-
t.includes("cont") && (
|
|
1926
|
-
const
|
|
1927
|
-
<button type="button" data-quick="Yes, this is the problem">${
|
|
1984
|
+
t.includes("cont") && (m = "");
|
|
1985
|
+
const d = T && /it goes to the same person/i.test(w) ? `<div class="quick" role="group" aria-label="Answer">
|
|
1986
|
+
<button type="button" data-quick="Yes, this is the problem">${F}That's right</button>
|
|
1928
1987
|
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
1929
|
-
</div>` : T &&
|
|
1930
|
-
<button type="button" data-quick="Yes, that answers it">${
|
|
1988
|
+
</div>` : T && He.test(w) ? `<div class="quick" role="group" aria-label="Did this answer your question?">
|
|
1989
|
+
<button type="button" data-quick="Yes, that answers it">${F}Yes, that answers it</button>
|
|
1931
1990
|
<button type="button" data-quick="No, I still need help">No, I still need help</button>
|
|
1932
1991
|
</div>` : "";
|
|
1933
1992
|
return `
|
|
1934
|
-
<div class="msg-row ${
|
|
1935
|
-
${
|
|
1936
|
-
${
|
|
1937
|
-
<div class="bubble ${
|
|
1938
|
-
${
|
|
1939
|
-
<span class="msg-when">${
|
|
1993
|
+
<div class="msg-row ${i ? "mine" : "theirs"} ${T ? "auto" : ""} ${t}">
|
|
1994
|
+
${l}
|
|
1995
|
+
${m}
|
|
1996
|
+
<div class="bubble ${w ? "" : "silent"}">${x}${g}</div>
|
|
1997
|
+
${d}
|
|
1998
|
+
<span class="msg-when">${v(ve(e.at) || ne(e.at))}</span>
|
|
1940
1999
|
</div>`;
|
|
1941
2000
|
}
|
|
1942
|
-
function
|
|
2001
|
+
function ut() {
|
|
1943
2002
|
return `
|
|
1944
2003
|
<div class="typing-row">
|
|
1945
|
-
<span class="av bot" aria-hidden="true"
|
|
2004
|
+
<span class="av bot orb" aria-hidden="true"></span>
|
|
1946
2005
|
<span class="msg-who auto">Assistant <span class="tag">AI</span></span>
|
|
1947
2006
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
1948
2007
|
</div>`;
|
|
1949
2008
|
}
|
|
1950
|
-
function
|
|
1951
|
-
const t =
|
|
2009
|
+
function ht(e) {
|
|
2010
|
+
const t = v(e.name || "attachment");
|
|
1952
2011
|
if (!e.url) return `<span class="file"><span class="nm">${t}</span></span>`;
|
|
1953
|
-
const
|
|
1954
|
-
return e.type === "SCREENSHOT" ? `<a href="${
|
|
1955
|
-
<a class="file" href="${
|
|
2012
|
+
const i = v(e.url);
|
|
2013
|
+
return e.type === "SCREENSHOT" ? `<a href="${i}" target="_blank" rel="noopener noreferrer"><img src="${i}" alt="${t}" loading="lazy"></a>` : e.type === "AUDIO" ? `<audio controls preload="metadata" src="${i}"></audio>` : e.type === "VIDEO" ? `<video controls preload="metadata" src="${i}"></video>` : `
|
|
2014
|
+
<a class="file" href="${i}" target="_blank" rel="noopener noreferrer" download>
|
|
1956
2015
|
<span class="nm">${t}</span>
|
|
1957
|
-
${e.size ? `<span class="sz">${
|
|
2016
|
+
${e.size ? `<span class="sz">${v(P(e.size))}</span>` : ""}
|
|
1958
2017
|
</a>`;
|
|
1959
2018
|
}
|
|
1960
|
-
function
|
|
1961
|
-
var
|
|
1962
|
-
const { client:
|
|
1963
|
-
|
|
2019
|
+
function bt(e, t, i, w) {
|
|
2020
|
+
var u;
|
|
2021
|
+
const { client: b, cfg: T } = e, x = document.createElement("div");
|
|
2022
|
+
x.className = "composer", x.innerHTML = `
|
|
1964
2023
|
<div class="staged" hidden></div>
|
|
1965
2024
|
<div class="row">
|
|
1966
2025
|
<div class="tools">
|
|
1967
2026
|
${T.attachments === !1 ? "" : `
|
|
1968
2027
|
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${fe}</button>
|
|
1969
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
1970
|
-
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${
|
|
2028
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${de}</button>`}
|
|
2029
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${ae}</button>
|
|
1971
2030
|
</div>
|
|
1972
2031
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
1973
2032
|
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${ge}</button>
|
|
1974
2033
|
</div>
|
|
1975
2034
|
<div class="note" hidden></div>
|
|
1976
|
-
<input type="file" hidden multiple accept="${
|
|
1977
|
-
const
|
|
1978
|
-
let
|
|
1979
|
-
function
|
|
1980
|
-
|
|
2035
|
+
<input type="file" hidden multiple accept="${Ae.join(",")}">`, t.appendChild(x);
|
|
2036
|
+
const g = x.querySelector(".staged"), m = x.querySelector("textarea"), l = x.querySelector('[data-act="send"]'), d = x.querySelector('[data-act="voice"]'), L = x.querySelector('[data-act="livecall"]'), y = x.querySelector("input[type=file]"), k = x.querySelector(".note"), S = [];
|
|
2037
|
+
let q = null, E = !1;
|
|
2038
|
+
function n(r, o = "") {
|
|
2039
|
+
k.hidden = !r, k.className = `note ${o}`, k.textContent = r || "";
|
|
1981
2040
|
}
|
|
1982
|
-
function
|
|
1983
|
-
const
|
|
1984
|
-
|
|
1985
|
-
<span class="chip ${
|
|
1986
|
-
<span class="nm">${
|
|
1987
|
-
<span class="sz">${
|
|
1988
|
-
<button type="button" data-drop="${
|
|
2041
|
+
function p() {
|
|
2042
|
+
const r = S.filter((o) => o.storageKey);
|
|
2043
|
+
l.disabled = E || !m.value.trim() && !r.length, g.hidden = !S.length, g.innerHTML = S.map((o, f) => `
|
|
2044
|
+
<span class="chip ${o.storageKey ? "" : "uploading"}">
|
|
2045
|
+
<span class="nm">${v(o.name)}</span>
|
|
2046
|
+
<span class="sz">${o.storageKey ? P(o.size) : "sending…"}</span>
|
|
2047
|
+
<button type="button" data-drop="${f}" aria-label="Remove ${v(o.name)}">${ce}</button>
|
|
1989
2048
|
</span>`).join("");
|
|
1990
|
-
for (const
|
|
1991
|
-
|
|
1992
|
-
|
|
2049
|
+
for (const o of g.querySelectorAll("[data-drop]"))
|
|
2050
|
+
o.addEventListener("click", () => {
|
|
2051
|
+
S.splice(Number(o.dataset.drop), 1), p();
|
|
1993
2052
|
});
|
|
1994
2053
|
}
|
|
1995
|
-
async function r
|
|
1996
|
-
const
|
|
1997
|
-
|
|
2054
|
+
async function a(r, o, f) {
|
|
2055
|
+
const $ = { name: f, size: r.size, storageKey: null };
|
|
2056
|
+
S.push($), p();
|
|
1998
2057
|
try {
|
|
1999
|
-
const { storageKey: A, mime:
|
|
2000
|
-
|
|
2058
|
+
const { storageKey: A, mime: j } = await b.uploadAttachment(r, o);
|
|
2059
|
+
$.storageKey = A, $.mime = j;
|
|
2001
2060
|
} catch (A) {
|
|
2002
|
-
|
|
2061
|
+
S.splice(S.indexOf($), 1), n(A.message || "That file could not be sent.", "err");
|
|
2003
2062
|
}
|
|
2004
|
-
|
|
2063
|
+
p();
|
|
2005
2064
|
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
}),
|
|
2009
|
-
|
|
2010
|
-
}), (
|
|
2011
|
-
|
|
2012
|
-
for (const
|
|
2013
|
-
if (
|
|
2014
|
-
|
|
2065
|
+
m.addEventListener("input", () => {
|
|
2066
|
+
m.style.height = "auto", m.style.height = `${Math.min(m.scrollHeight, 120)}px`, p();
|
|
2067
|
+
}), m.addEventListener("keydown", (r) => {
|
|
2068
|
+
r.key === "Enter" && !r.shiftKey && !r.isComposing && (r.preventDefault(), s());
|
|
2069
|
+
}), (u = x.querySelector('[data-act="attach"]')) == null || u.addEventListener("click", () => y.click()), y.addEventListener("change", () => {
|
|
2070
|
+
n("");
|
|
2071
|
+
for (const r of y.files) {
|
|
2072
|
+
if (r.size > b.config.maxAttachmentBytes) {
|
|
2073
|
+
n(`${r.name} is larger than ${P(b.config.maxAttachmentBytes)}.`, "err");
|
|
2015
2074
|
continue;
|
|
2016
2075
|
}
|
|
2017
|
-
r
|
|
2076
|
+
a(r, r.type, r.name);
|
|
2018
2077
|
}
|
|
2019
|
-
|
|
2020
|
-
}),
|
|
2021
|
-
if (
|
|
2022
|
-
const
|
|
2023
|
-
|
|
2024
|
-
const { blob:
|
|
2025
|
-
|
|
2078
|
+
y.value = "";
|
|
2079
|
+
}), d && !Ie() && (d.disabled = !0, d.title = "This browser cannot record audio"), d == null || d.addEventListener("click", async () => {
|
|
2080
|
+
if (q) {
|
|
2081
|
+
const r = q;
|
|
2082
|
+
q = null, d.classList.remove("recording"), d.innerHTML = de, n("");
|
|
2083
|
+
const { blob: o, mime: f } = await r.stop();
|
|
2084
|
+
o.size && a(o, f, "Voice note");
|
|
2026
2085
|
return;
|
|
2027
2086
|
}
|
|
2028
2087
|
try {
|
|
2029
|
-
|
|
2030
|
-
maxMs:
|
|
2031
|
-
onTick: (
|
|
2032
|
-
onAutoStop: () =>
|
|
2033
|
-
}),
|
|
2088
|
+
n(""), q = await Re({
|
|
2089
|
+
maxMs: b.config.maxRecordingMs,
|
|
2090
|
+
onTick: (r) => n(`Recording — ${ee(r)}. Tap the mic to stop.`),
|
|
2091
|
+
onAutoStop: () => d.click()
|
|
2092
|
+
}), d.classList.add("recording"), d.innerHTML = Oe;
|
|
2034
2093
|
} catch {
|
|
2035
|
-
|
|
2094
|
+
q = null, n("The microphone is not available — check the browser permission.", "err");
|
|
2036
2095
|
}
|
|
2037
|
-
}),
|
|
2038
|
-
|
|
2096
|
+
}), b.canCallTeam(w).then((r) => {
|
|
2097
|
+
r && (L.hidden = !1, e.preloadCall());
|
|
2039
2098
|
}).catch(() => {
|
|
2040
|
-
}),
|
|
2041
|
-
|
|
2099
|
+
}), L.addEventListener("click", async () => {
|
|
2100
|
+
L.disabled = !0, n("");
|
|
2042
2101
|
try {
|
|
2043
|
-
const
|
|
2044
|
-
e.showLiveCall(t,
|
|
2045
|
-
} catch (
|
|
2046
|
-
|
|
2102
|
+
const r = await b.startLiveCall(w);
|
|
2103
|
+
e.showLiveCall(t, i, r);
|
|
2104
|
+
} catch (r) {
|
|
2105
|
+
n(r.message.replace("[BugCatch] ", ""), "err");
|
|
2047
2106
|
} finally {
|
|
2048
|
-
|
|
2107
|
+
L.disabled = !1;
|
|
2049
2108
|
}
|
|
2050
|
-
}),
|
|
2051
|
-
var
|
|
2052
|
-
const
|
|
2053
|
-
!
|
|
2109
|
+
}), l.addEventListener("click", s), i.addEventListener("click", (r) => {
|
|
2110
|
+
var f, $;
|
|
2111
|
+
const o = ($ = (f = r.target).closest) == null ? void 0 : $.call(f, "[data-quick]");
|
|
2112
|
+
!o || E || (m.value = o.dataset.quick, s());
|
|
2054
2113
|
});
|
|
2055
|
-
async function
|
|
2056
|
-
var
|
|
2057
|
-
const
|
|
2058
|
-
if (!(
|
|
2059
|
-
|
|
2114
|
+
async function s() {
|
|
2115
|
+
var f;
|
|
2116
|
+
const r = m.value.trim(), o = S.filter(($) => $.storageKey);
|
|
2117
|
+
if (!(E || !r && !o.length)) {
|
|
2118
|
+
E = !0, p(), n(""), i.insertAdjacentHTML("beforeend", we({
|
|
2060
2119
|
from: "reporter",
|
|
2061
|
-
body:
|
|
2120
|
+
body: r,
|
|
2062
2121
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2063
|
-
attachments:
|
|
2064
|
-
}, "pending")), _(
|
|
2122
|
+
attachments: o.map(($) => ({ type: "FILE", name: $.name, size: $.size }))
|
|
2123
|
+
}, "pending")), _(i, { smooth: !0 });
|
|
2065
2124
|
try {
|
|
2066
|
-
await
|
|
2067
|
-
body:
|
|
2068
|
-
attachments:
|
|
2069
|
-
storageKey:
|
|
2070
|
-
mime:
|
|
2071
|
-
name:
|
|
2072
|
-
size:
|
|
2125
|
+
await b.replyToReport(w, {
|
|
2126
|
+
body: r,
|
|
2127
|
+
attachments: o.map(($) => ({
|
|
2128
|
+
storageKey: $.storageKey,
|
|
2129
|
+
mime: $.mime,
|
|
2130
|
+
name: $.name,
|
|
2131
|
+
size: $.size
|
|
2073
2132
|
}))
|
|
2074
|
-
}),
|
|
2075
|
-
} catch (
|
|
2076
|
-
(
|
|
2133
|
+
}), m.value = "", m.style.height = "auto", S.length = 0, await e.refreshThread(w);
|
|
2134
|
+
} catch ($) {
|
|
2135
|
+
(f = i.querySelector(".msg-row.pending")) == null || f.classList.replace("pending", "failed"), n($.message || "That could not be sent — try again.", "err");
|
|
2077
2136
|
} finally {
|
|
2078
|
-
|
|
2137
|
+
E = !1, p();
|
|
2079
2138
|
}
|
|
2080
2139
|
}
|
|
2081
2140
|
}
|
|
2082
|
-
|
|
2141
|
+
p();
|
|
2083
2142
|
}
|
|
2084
|
-
const
|
|
2085
|
-
function
|
|
2086
|
-
|
|
2143
|
+
const se = /* @__PURE__ */ new WeakMap();
|
|
2144
|
+
function he(e) {
|
|
2145
|
+
return JSON.stringify(e ? [e.score, e.current, e.comment || null] : null);
|
|
2146
|
+
}
|
|
2147
|
+
function ft(e) {
|
|
2148
|
+
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
|
+
}
|
|
2150
|
+
function gt(e) {
|
|
2151
|
+
var E;
|
|
2087
2152
|
const {
|
|
2088
2153
|
client: t,
|
|
2089
|
-
scrim:
|
|
2090
|
-
close:
|
|
2154
|
+
scrim: i,
|
|
2155
|
+
close: w
|
|
2091
2156
|
} = e;
|
|
2092
|
-
let
|
|
2093
|
-
function T(
|
|
2094
|
-
if (
|
|
2095
|
-
|
|
2096
|
-
|
|
2157
|
+
let b = null;
|
|
2158
|
+
function T(n, { callFailed: p = null } = {}) {
|
|
2159
|
+
if (n != null && n.id && !p) {
|
|
2160
|
+
m(n.id, { fresh: !0 }).then((a) => {
|
|
2161
|
+
a || x(n, { callFailed: p });
|
|
2097
2162
|
});
|
|
2098
2163
|
return;
|
|
2099
2164
|
}
|
|
2100
|
-
|
|
2165
|
+
x(n, { callFailed: p });
|
|
2101
2166
|
}
|
|
2102
|
-
function
|
|
2103
|
-
var
|
|
2104
|
-
const
|
|
2105
|
-
|
|
2167
|
+
function x(n, { callFailed: p = null } = {}) {
|
|
2168
|
+
var r;
|
|
2169
|
+
const a = n != null && n.id ? String(n.id).slice(0, 8) : null, s = (r = n == null ? void 0 : n.estimate) != null && r.label ? String(n.estimate.label) : null, u = p ? `<p class="eta">${v(p)} Your report is filed, and the team will reply in the chat.</p>` : "";
|
|
2170
|
+
i.querySelector(".panel").innerHTML = `
|
|
2106
2171
|
<div class="done">
|
|
2107
|
-
<div class="tick">${
|
|
2172
|
+
<div class="tick">${F}</div>
|
|
2108
2173
|
<h3>Thanks — that's on its way.</h3>
|
|
2109
|
-
<p>${
|
|
2110
|
-
${
|
|
2111
|
-
${
|
|
2112
|
-
</div>`, setTimeout(
|
|
2174
|
+
<p>${a ? `Filed as <code>${v(a)}</code>.` : "The team has what they need to reproduce it."}</p>
|
|
2175
|
+
${u}
|
|
2176
|
+
${s ? `<p class="eta">Reports like this usually take <strong>${v(s)}</strong>. We'll let you know when it moves.</p>` : ""}
|
|
2177
|
+
</div>`, setTimeout(w, u ? 6e3 : s ? 4e3 : 2e3);
|
|
2113
2178
|
}
|
|
2114
|
-
async function
|
|
2115
|
-
const
|
|
2116
|
-
clearTimeout(
|
|
2117
|
-
${
|
|
2118
|
-
<div class="history" aria-busy="true">${
|
|
2119
|
-
let
|
|
2179
|
+
async function g() {
|
|
2180
|
+
const n = i.querySelector(".panel");
|
|
2181
|
+
clearTimeout(l), b = null, n.classList.remove("is-chat"), n.innerHTML = `
|
|
2182
|
+
${le({ title: "Your reports", sub: "Where each one has got to.", theme: e.themeLabel() })}
|
|
2183
|
+
<div class="history" aria-busy="true">${Ke(3)}</div>`, n.querySelector('[data-act="close"]').addEventListener("click", w);
|
|
2184
|
+
let p = [];
|
|
2120
2185
|
try {
|
|
2121
|
-
({ reports:
|
|
2186
|
+
({ reports: p } = await t.myReports());
|
|
2122
2187
|
} catch {
|
|
2123
|
-
const
|
|
2124
|
-
|
|
2188
|
+
const s = n.querySelector(".history");
|
|
2189
|
+
s && (s.innerHTML = re("Couldn't load your reports just now.", G));
|
|
2125
2190
|
return;
|
|
2126
2191
|
}
|
|
2127
|
-
const
|
|
2128
|
-
if (
|
|
2129
|
-
|
|
2130
|
-
<button class="row" type="button" data-report="${
|
|
2131
|
-
<span class="row-ico" aria-hidden="true">${
|
|
2192
|
+
const a = n.querySelector(".history");
|
|
2193
|
+
if (a) {
|
|
2194
|
+
a.removeAttribute("aria-busy"), a.innerHTML = p.length ? p.map((s, u) => `
|
|
2195
|
+
<button class="row" type="button" data-report="${v(s.id)}" style="animation-delay:${Math.min(u, 8) * 30}ms">
|
|
2196
|
+
<span class="row-ico" aria-hidden="true">${De}</span>
|
|
2132
2197
|
<span class="who">
|
|
2133
|
-
<span class="ttl">${
|
|
2134
|
-
<span class="sub">${
|
|
2198
|
+
<span class="ttl">${v(s.title)}</span>
|
|
2199
|
+
<span class="sub">${v(s.reference)} · ${v(ne(s.createdAt))}${ft(s)}</span>
|
|
2135
2200
|
</span>
|
|
2136
|
-
<span class="pill ${
|
|
2137
|
-
<span class="chev" aria-hidden="true">${
|
|
2138
|
-
</button>`).join("") :
|
|
2139
|
-
for (const
|
|
2140
|
-
|
|
2201
|
+
<span class="pill ${v(String(s.status).toLowerCase())}">${v(ie(s.status))}</span>
|
|
2202
|
+
<span class="chev" aria-hidden="true">${We}</span>
|
|
2203
|
+
</button>`).join("") : re("You haven't reported anything yet.", Ye);
|
|
2204
|
+
for (const s of a.querySelectorAll("[data-report]"))
|
|
2205
|
+
s.addEventListener("click", () => m(s.dataset.report));
|
|
2141
2206
|
}
|
|
2142
2207
|
}
|
|
2143
|
-
async function
|
|
2144
|
-
var
|
|
2145
|
-
const
|
|
2146
|
-
clearTimeout(
|
|
2147
|
-
${
|
|
2208
|
+
async function m(n, { fresh: p = !1 } = {}) {
|
|
2209
|
+
var f;
|
|
2210
|
+
const a = i.querySelector(".panel");
|
|
2211
|
+
clearTimeout(l), a.classList.add("is-chat"), a.innerHTML = `
|
|
2212
|
+
${le({
|
|
2148
2213
|
back: !0,
|
|
2149
|
-
title:
|
|
2150
|
-
sub:
|
|
2214
|
+
title: p ? "Looking into it" : "Your report",
|
|
2215
|
+
sub: p ? "It may ask you a question here." : "Updates, and a way to reply.",
|
|
2216
|
+
theme: e.themeLabel()
|
|
2151
2217
|
})}
|
|
2152
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
2153
|
-
let
|
|
2218
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${Ue()}</div></div>`, a.querySelector('[data-act="close"]').addEventListener("click", w), a.querySelector('[data-act="back"]').addEventListener("click", g);
|
|
2219
|
+
let s = null;
|
|
2154
2220
|
try {
|
|
2155
|
-
|
|
2221
|
+
s = await t.myReport(n);
|
|
2156
2222
|
} catch {
|
|
2157
|
-
|
|
2223
|
+
s = null;
|
|
2158
2224
|
}
|
|
2159
|
-
const
|
|
2160
|
-
if (!
|
|
2161
|
-
if (!
|
|
2162
|
-
return
|
|
2163
|
-
|
|
2164
|
-
const
|
|
2165
|
-
|
|
2225
|
+
const u = a.querySelector(".history");
|
|
2226
|
+
if (!u || !a.querySelector('[data-act="back"]')) return !1;
|
|
2227
|
+
if (!s)
|
|
2228
|
+
return p ? (a.classList.remove("is-chat"), !1) : (u.removeAttribute("aria-busy"), u.innerHTML = re("Couldn't load that report just now.", G), !1);
|
|
2229
|
+
b = n, t.markReportRead(n);
|
|
2230
|
+
const r = ue(s.timeline);
|
|
2231
|
+
u.classList.add("chatting"), u.removeAttribute("aria-busy"), u.innerHTML = `
|
|
2166
2232
|
<div class="report-head">
|
|
2167
|
-
<span class="ttl">${
|
|
2168
|
-
<span class="sub">${
|
|
2169
|
-
<span class="pill ${
|
|
2170
|
-
${(
|
|
2233
|
+
<span class="ttl">${v(s.title)}</span>
|
|
2234
|
+
<span class="sub">${v(s.reference)} · ${v(s.project || "")}</span>
|
|
2235
|
+
<span class="pill ${v(String(s.status).toLowerCase())}">${v(ie(s.status))}</span>
|
|
2236
|
+
${(f = s.estimate) != null && f.label ? `<span class="eta-line">Usually takes ${v(String(s.estimate.label))}</span>` : ""}
|
|
2171
2237
|
</div>
|
|
2172
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
2173
|
-
const
|
|
2174
|
-
return
|
|
2238
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${r}</div>`;
|
|
2239
|
+
const o = u.querySelector(".thread");
|
|
2240
|
+
return se.set(o, r), _(o), L(u, s), y(u, s), s.canReply && bt(e, u, o, n), d(u, s, n), _(o), !0;
|
|
2175
2241
|
}
|
|
2176
|
-
let
|
|
2177
|
-
function
|
|
2178
|
-
var
|
|
2179
|
-
clearTimeout(
|
|
2180
|
-
const
|
|
2181
|
-
let
|
|
2182
|
-
if (!
|
|
2183
|
-
|
|
2242
|
+
let l = null;
|
|
2243
|
+
function d(n, p, a) {
|
|
2244
|
+
var h, z, R;
|
|
2245
|
+
clearTimeout(l);
|
|
2246
|
+
const s = p.assistant, u = n.querySelector(".thread");
|
|
2247
|
+
let r = n.querySelector(".assistant");
|
|
2248
|
+
if (!s) {
|
|
2249
|
+
r == null || r.remove(), (h = u == null ? void 0 : u.querySelector(".typing-row")) == null || h.remove();
|
|
2184
2250
|
return;
|
|
2185
2251
|
}
|
|
2186
|
-
const
|
|
2187
|
-
|
|
2188
|
-
const
|
|
2189
|
-
<div class="as-body${
|
|
2252
|
+
const o = (r == null ? void 0 : r.dataset.phase) || null;
|
|
2253
|
+
r || (r = document.createElement("div"), r.setAttribute("role", "status"), r.setAttribute("aria-live", "polite"), (z = n.querySelector(".report-head")) == null || z.after(r)), r.className = `assistant ${v(s.phase)}`, r.dataset.phase = s.phase;
|
|
2254
|
+
const f = s.steps || [], $ = f.filter((H) => H.state === "done").length, A = f.some((H) => H.state === "active") ? 0.5 : 0, j = f.length ? Math.round(($ + A) / f.length * 100) : 0, B = `
|
|
2255
|
+
<div class="as-body${o && o !== s.phase ? " entering" : ""}">
|
|
2190
2256
|
<div class="as-top">
|
|
2191
|
-
<span class="as-orb
|
|
2257
|
+
<span class="as-orb${s.phase === "calling" || s.phase === "resolved" ? "" : " orb"}" aria-hidden="true">${s.phase === "calling" ? ae : s.phase === "resolved" ? F : ""}</span>
|
|
2192
2258
|
<div class="as-text">
|
|
2193
|
-
<div class="as-title">${
|
|
2194
|
-
<div class="as-detail">${
|
|
2259
|
+
<div class="as-title">${v(s.title)}</div>
|
|
2260
|
+
<div class="as-detail">${v(s.detail)}</div>
|
|
2195
2261
|
</div>
|
|
2196
2262
|
</div>
|
|
2197
2263
|
</div>
|
|
2198
|
-
${
|
|
2199
|
-
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${
|
|
2200
|
-
<ol class="as-steps">${
|
|
2201
|
-
if (
|
|
2202
|
-
const
|
|
2203
|
-
|
|
2204
|
-
const
|
|
2205
|
-
|
|
2206
|
-
|
|
2264
|
+
${f.length ? `
|
|
2265
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${j}"><i style="width:${j}%"></i></div>
|
|
2266
|
+
<ol class="as-steps">${f.map((H) => `<li class="${v(H.state)}"${H.state === "active" ? ' aria-current="step"' : ""}><span class="dot"></span><span class="lbl">${v(H.label)}</span></li>`).join("")}</ol>` : ""}`, N = JSON.stringify([s.phase, s.title, s.detail, f]);
|
|
2267
|
+
if (r.dataset.key !== N) {
|
|
2268
|
+
const H = r.querySelector(".as-progress i"), D = H == null ? void 0 : H.style.width;
|
|
2269
|
+
r.innerHTML = B, r.dataset.key = N;
|
|
2270
|
+
const O = r.querySelector(".as-progress i");
|
|
2271
|
+
O && D && (O.style.width = D, requestAnimationFrame(() => {
|
|
2272
|
+
O.style.width = `${j}%`;
|
|
2207
2273
|
}));
|
|
2208
2274
|
}
|
|
2209
|
-
if (
|
|
2210
|
-
const
|
|
2211
|
-
|
|
2275
|
+
if (u) {
|
|
2276
|
+
const H = pe(u), D = u.querySelector(".typing-row");
|
|
2277
|
+
s.phase !== "analyzing" ? D == null || D.remove() : (!D || D !== u.lastElementChild) && (D == null || D.remove(), u.insertAdjacentHTML("beforeend", ut()), H && _(u));
|
|
2212
2278
|
}
|
|
2213
|
-
|
|
2279
|
+
s.phase === "analyzing" ? l = setTimeout(() => S(a), 3e3) : s.phase === "calling" ? l = setTimeout(() => S(a), 1e4) : s.phase === "needs_info" && o !== "needs_info" && ((R = n.querySelector(".composer textarea")) == null || R.focus());
|
|
2214
2280
|
}
|
|
2215
|
-
function
|
|
2216
|
-
var
|
|
2217
|
-
if ((
|
|
2218
|
-
const
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2281
|
+
function L(n, p) {
|
|
2282
|
+
var s, u;
|
|
2283
|
+
if ((s = n.querySelector(".fix-verification")) == null || s.remove(), !p.resolvedAt || !["RESOLVED", "CLOSED"].includes(p.status)) return;
|
|
2284
|
+
const a = document.createElement("div");
|
|
2285
|
+
a.className = "fix-verification", p.verification ? a.textContent = p.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (a.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>', a.querySelectorAll("[data-result]").forEach((r) => {
|
|
2286
|
+
r.onclick = async () => {
|
|
2287
|
+
a.querySelectorAll("button").forEach((o) => {
|
|
2288
|
+
o.disabled = !0;
|
|
2223
2289
|
});
|
|
2224
2290
|
try {
|
|
2225
|
-
await t.verifyFix(
|
|
2226
|
-
} catch (
|
|
2227
|
-
|
|
2228
|
-
|
|
2291
|
+
await t.verifyFix(p.id, { result: r.dataset.result, resolvedAt: p.resolvedAt, note: a.querySelector("textarea").value }), await m(p.id);
|
|
2292
|
+
} catch (o) {
|
|
2293
|
+
a.querySelector(".feedback-status").textContent = o.message, a.querySelectorAll("button").forEach((f) => {
|
|
2294
|
+
f.disabled = !1;
|
|
2229
2295
|
});
|
|
2230
2296
|
}
|
|
2231
2297
|
};
|
|
2232
|
-
})), (
|
|
2298
|
+
})), (u = n.querySelector(".report-head")) == null || u.after(a);
|
|
2233
2299
|
}
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2300
|
+
function y(n, p) {
|
|
2301
|
+
var u;
|
|
2302
|
+
let a = n.querySelector(".fix-rating");
|
|
2303
|
+
if (!["RESOLVED", "CLOSED"].includes(p.status) || !p.ratingAsked) {
|
|
2304
|
+
a == null || a.remove();
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
a && a.dataset.key === he(p.rating) || (a || (a = document.createElement("div"), a.className = "fix-rating", (u = n.querySelector(".fix-verification") || n.querySelector(".report-head")) == null || u.after(a)), k(a, p, p.rating || null));
|
|
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
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
async function S(n) {
|
|
2354
|
+
const p = i.querySelector(".history.chatting"), a = p == null ? void 0 : p.querySelector(".thread");
|
|
2355
|
+
if (!a || b !== n) return;
|
|
2356
|
+
let s = null;
|
|
2238
2357
|
try {
|
|
2239
|
-
|
|
2358
|
+
s = await t.myReport(n);
|
|
2240
2359
|
} catch {
|
|
2241
2360
|
}
|
|
2242
|
-
if (e.closed || !
|
|
2243
|
-
|
|
2244
|
-
const
|
|
2245
|
-
|
|
2246
|
-
const
|
|
2247
|
-
|
|
2361
|
+
if (e.closed || !s || b !== n) return;
|
|
2362
|
+
L(p, s), y(p, s);
|
|
2363
|
+
const u = pe(a), r = ue(s.timeline);
|
|
2364
|
+
se.get(a) !== r && (a.innerHTML = r, se.set(a, r)), d(p, s, n), u && _(a);
|
|
2365
|
+
const o = p.querySelector(".report-head .pill");
|
|
2366
|
+
o && (o.className = `pill ${String(s.status).toLowerCase()}`, o.textContent = ie(s.status));
|
|
2248
2367
|
}
|
|
2249
|
-
const
|
|
2250
|
-
!
|
|
2368
|
+
const q = t.on("update", (n) => {
|
|
2369
|
+
!b || (n == null ? void 0 : n.bugId) !== b || (t.markReportRead(b), S(b));
|
|
2251
2370
|
});
|
|
2252
2371
|
e.onDestroy(() => {
|
|
2253
|
-
|
|
2254
|
-
}), (
|
|
2372
|
+
q(), clearTimeout(l);
|
|
2373
|
+
}), (E = i.querySelector('[data-act="history"]')) == null || E.addEventListener("click", g), e.succeed = T, e.refreshThread = S, e.openReportId = () => b;
|
|
2255
2374
|
}
|
|
2256
|
-
function
|
|
2375
|
+
function xt({
|
|
2257
2376
|
root: e,
|
|
2258
2377
|
host: t,
|
|
2259
|
-
dock:
|
|
2260
|
-
client:
|
|
2261
|
-
onClose:
|
|
2378
|
+
dock: i,
|
|
2379
|
+
client: w,
|
|
2380
|
+
onClose: b,
|
|
2262
2381
|
preloadCall: T = () => {
|
|
2263
|
-
}
|
|
2382
|
+
},
|
|
2383
|
+
themeControls: x = null
|
|
2264
2384
|
}) {
|
|
2265
|
-
|
|
2266
|
-
const
|
|
2267
|
-
|
|
2385
|
+
mt(e);
|
|
2386
|
+
const g = w.config, m = () => (x == null ? void 0 : x.label()) || "", l = document.createElement("div");
|
|
2387
|
+
l.className = `scrim ${i.classList.contains("at-left") ? "at-left" : "at-right"} ${i.classList.contains("at-top") ? "at-top" : "at-bottom"}`, l.style.setProperty("--bc-dock-h", `${Math.round(i.getBoundingClientRect().height)}px`), l.innerHTML = `
|
|
2268
2388
|
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
|
|
2269
|
-
${
|
|
2389
|
+
${le({
|
|
2270
2390
|
id: "bc-h",
|
|
2271
|
-
|
|
2272
|
-
|
|
2391
|
+
// Not "Tell us what went wrong": that is the first field's own label,
|
|
2392
|
+
// a few pixels below. The header names the errand the launcher named.
|
|
2393
|
+
title: "Report a bug",
|
|
2394
|
+
sub: "We attach the page details for you.",
|
|
2395
|
+
theme: m()
|
|
2273
2396
|
})}
|
|
2274
2397
|
<div class="body">
|
|
2275
2398
|
<div class="slot" role="alert"></div>
|
|
@@ -2281,51 +2404,52 @@ function bt({
|
|
|
2281
2404
|
close by itself. Drawn only when the project offers any. -->
|
|
2282
2405
|
<div class="picks" hidden></div>
|
|
2283
2406
|
<div class="known" hidden></div>
|
|
2284
|
-
${
|
|
2407
|
+
${tt(g)}
|
|
2285
2408
|
</div>
|
|
2286
2409
|
<div class="foot">
|
|
2287
2410
|
<span class="note" aria-live="polite"></span>
|
|
2288
|
-
${
|
|
2411
|
+
${w.hasReports() ? '<button class="quiet" type="button" data-act="history">Your reports</button>' : ""}
|
|
2289
2412
|
<span class="spacer"></span>
|
|
2290
2413
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
2291
2414
|
most cannot. Drawn here rather than as a second launcher because it
|
|
2292
2415
|
is the same errand as Send report — the difference is only whether
|
|
2293
2416
|
the reporter would rather say it than type it. -->
|
|
2294
|
-
<button class="ghost" type="button" data-act="call" hidden>${
|
|
2417
|
+
<button class="ghost" type="button" data-act="call" hidden>${ae}Talk to the team</button>
|
|
2295
2418
|
<button class="primary" type="button" data-act="send">Send report ${ge}</button>
|
|
2296
2419
|
</div>
|
|
2297
2420
|
<div class="powered">Powered by
|
|
2298
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
2421
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Pe}</a>
|
|
2299
2422
|
</div>
|
|
2300
2423
|
</div>`;
|
|
2301
|
-
const
|
|
2302
|
-
client:
|
|
2303
|
-
cfg:
|
|
2424
|
+
const d = (u) => l.querySelector(u), L = d(".slot"), y = [], k = {
|
|
2425
|
+
client: w,
|
|
2426
|
+
cfg: g,
|
|
2304
2427
|
root: e,
|
|
2305
2428
|
host: t,
|
|
2306
|
-
dock:
|
|
2307
|
-
scrim:
|
|
2308
|
-
$:
|
|
2309
|
-
titleInput:
|
|
2310
|
-
descInput:
|
|
2311
|
-
compose:
|
|
2312
|
-
sendBtn:
|
|
2313
|
-
callBtn:
|
|
2314
|
-
historyBtn:
|
|
2315
|
-
note:
|
|
2316
|
-
whoami:
|
|
2317
|
-
refsBox:
|
|
2318
|
-
notices:
|
|
2319
|
-
known:
|
|
2320
|
-
picks:
|
|
2429
|
+
dock: i,
|
|
2430
|
+
scrim: l,
|
|
2431
|
+
$: d,
|
|
2432
|
+
titleInput: d("#bc-title"),
|
|
2433
|
+
descInput: d("#bc-desc"),
|
|
2434
|
+
compose: d(".compose"),
|
|
2435
|
+
sendBtn: d('[data-act="send"]'),
|
|
2436
|
+
callBtn: d('[data-act="call"]'),
|
|
2437
|
+
historyBtn: d('[data-act="history"]'),
|
|
2438
|
+
note: d(".foot .note"),
|
|
2439
|
+
whoami: d(".whoami"),
|
|
2440
|
+
refsBox: d(".refs"),
|
|
2441
|
+
notices: d(".notices"),
|
|
2442
|
+
known: d(".known"),
|
|
2443
|
+
picks: d(".picks"),
|
|
2321
2444
|
// A report or a call is on its way. Escape and a click outside wait for it.
|
|
2322
2445
|
sending: !1,
|
|
2323
2446
|
closed: !1,
|
|
2324
|
-
say:
|
|
2325
|
-
close:
|
|
2447
|
+
say: s,
|
|
2448
|
+
close: p,
|
|
2326
2449
|
preloadCall: T,
|
|
2327
|
-
|
|
2328
|
-
|
|
2450
|
+
themeLabel: m,
|
|
2451
|
+
onDestroy: (u) => {
|
|
2452
|
+
y.push(u);
|
|
2329
2453
|
},
|
|
2330
2454
|
// compose.js
|
|
2331
2455
|
refreshSendState: null,
|
|
@@ -2348,55 +2472,60 @@ function bt({
|
|
|
2348
2472
|
refreshThread: null,
|
|
2349
2473
|
openReportId: null
|
|
2350
2474
|
};
|
|
2351
|
-
|
|
2352
|
-
const
|
|
2353
|
-
|
|
2354
|
-
function
|
|
2355
|
-
|
|
2475
|
+
at(k), nt(k), rt(k), it(k), st(k), lt(k), ct(k), gt(k);
|
|
2476
|
+
const S = document.activeElement, q = document.documentElement.style, E = q.overflow;
|
|
2477
|
+
q.overflow = "hidden";
|
|
2478
|
+
function n() {
|
|
2479
|
+
k.closed || (y.forEach((u) => u()), k.closed = !0, q.overflow = E, document.removeEventListener("keydown", a, !0), l.remove(), i.hidden = !1, t.style.opacity = "", b == null || b());
|
|
2356
2480
|
}
|
|
2357
|
-
function
|
|
2358
|
-
var
|
|
2359
|
-
if (!
|
|
2360
|
-
|
|
2481
|
+
function p() {
|
|
2482
|
+
var u;
|
|
2483
|
+
if (!k.closed) {
|
|
2484
|
+
l.classList.add("closing"), setTimeout(n, 160);
|
|
2361
2485
|
try {
|
|
2362
|
-
(
|
|
2486
|
+
(u = S == null ? void 0 : S.focus) == null || u.call(S);
|
|
2363
2487
|
} catch {
|
|
2364
2488
|
}
|
|
2365
2489
|
}
|
|
2366
2490
|
}
|
|
2367
|
-
function
|
|
2368
|
-
if (
|
|
2369
|
-
if (
|
|
2370
|
-
|
|
2491
|
+
function a(u) {
|
|
2492
|
+
if (u.key === "Escape") {
|
|
2493
|
+
if (u.stopPropagation(), k.isRecording()) {
|
|
2494
|
+
k.stopRecording({ keep: !1 });
|
|
2371
2495
|
return;
|
|
2372
2496
|
}
|
|
2373
|
-
|
|
2497
|
+
k.sending || p();
|
|
2374
2498
|
return;
|
|
2375
2499
|
}
|
|
2376
|
-
if (
|
|
2377
|
-
const
|
|
2500
|
+
if (u.key !== "Tab" || k.isRecording()) return;
|
|
2501
|
+
const r = [...l.querySelectorAll(
|
|
2378
2502
|
"button:not(:disabled), input:not([hidden]), textarea, select, [href]"
|
|
2379
|
-
)].filter((
|
|
2380
|
-
if (
|
|
2381
|
-
const
|
|
2382
|
-
|
|
2503
|
+
)].filter((A) => A.offsetParent !== null || A === document.activeElement);
|
|
2504
|
+
if (!r.length) return;
|
|
2505
|
+
const o = r[0], f = r[r.length - 1], $ = l.getRootNode().activeElement;
|
|
2506
|
+
u.shiftKey && $ === o ? (u.preventDefault(), f.focus()) : !u.shiftKey && $ === f && (u.preventDefault(), o.focus());
|
|
2383
2507
|
}
|
|
2384
|
-
document.addEventListener("keydown",
|
|
2385
|
-
|
|
2386
|
-
}),
|
|
2387
|
-
|
|
2388
|
-
|
|
2508
|
+
document.addEventListener("keydown", a, !0), l.addEventListener("click", (u) => {
|
|
2509
|
+
u.target === l && !k.sending && p();
|
|
2510
|
+
}), d('[data-act="close"]').addEventListener("click", p), l.addEventListener("click", (u) => {
|
|
2511
|
+
const r = u.target.closest('[data-act="theme"]');
|
|
2512
|
+
if (!r || !x) return;
|
|
2513
|
+
const o = x.cycle();
|
|
2514
|
+
r.title = `Theme: ${o.label}`, r.setAttribute("aria-label", `Theme: ${o.label}. Change theme`);
|
|
2515
|
+
});
|
|
2516
|
+
function s(u, r = "err") {
|
|
2517
|
+
L.innerHTML = u ? `<div class="msg ${r}">${r === "err" ? G : ""}<span>${v(u)}</span></div>` : "";
|
|
2389
2518
|
}
|
|
2390
|
-
return e.appendChild(
|
|
2519
|
+
return e.appendChild(l), k.refreshSendState(), k.titleInput.focus(), { destroy: n, close: p };
|
|
2391
2520
|
}
|
|
2392
|
-
function
|
|
2521
|
+
function mt(e) {
|
|
2393
2522
|
if (e.querySelector("style[data-panel]")) return;
|
|
2394
2523
|
const t = document.createElement("style");
|
|
2395
|
-
t.setAttribute("data-panel", ""), t.textContent =
|
|
2396
|
-
const
|
|
2397
|
-
|
|
2524
|
+
t.setAttribute("data-panel", ""), t.textContent = Fe;
|
|
2525
|
+
const i = e.querySelector("style");
|
|
2526
|
+
i ? i.after(t) : e.prepend(t);
|
|
2398
2527
|
}
|
|
2399
2528
|
export {
|
|
2400
|
-
|
|
2529
|
+
xt as openPanel
|
|
2401
2530
|
};
|
|
2402
2531
|
//# sourceMappingURL=bugcatch-panel.es.js.map
|