diff --git a/build/app/public/css/popup.css b/build/app/public/css/popup.css index 9c7a8c1e..edc625f9 100644 --- a/build/app/public/css/popup.css +++ b/build/app/public/css/popup.css @@ -1,3 +1,4 @@ +@charset "UTF-8"; /* Status icons */ /* Colors */ /* Dark theme */ @@ -3797,31 +3798,48 @@ body.environment--macos, body.environment--browser, body.environment--windows, b text-align: center; } -.button[data-variant=macos-standard] { - color: var(--Text-Primary, rgba(0, 0, 0, 0.84)); - text-align: center; +.button[data-size=small] { + line-height: 13px; + height: 20px; + padding: 0px 12px; border-radius: 5px; - border: 0.5px solid rgba(0, 0, 0, 0.1); - background: #fff; - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05); } -.button[data-variant=macos-standard]:active { - border: 0.5px solid rgba(0, 0, 0, 0.1); - background: #e7e7e7; - /* Mac/Button */ - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05); +.button[data-size=big] { + height: 50px; + padding: 0px 24px; + /* Button */ + font-size: 15px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 133.333% */ } -.body--theme-dark .button[data-variant=macos-standard] { - color: rgba(255, 255, 255, 0.84); - border: 0.5px solid rgba(0, 0, 0, 0); - background: rgba(255, 255, 255, 0.25); - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset; +.button[data-size=desktop-large] { + height: 29px; + padding: 0px 12px; +} +.button[data-variant=desktop-vibrancy] { + border-radius: 6px; + background: rgba(0, 0, 0, 0.1); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); +} +.button[data-variant=desktop-vibrancy]:active { + border-radius: 6px; + background: rgba(0, 0, 0, 0.2); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); +} +.body--theme-dark .button[data-variant=desktop-vibrancy] { + border-radius: 6px; + background: rgba(255, 255, 255, 0.28); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); } -.body--theme-dark .button[data-variant=macos-standard]:active { - border: 0.5px solid rgba(0, 0, 0, 0); +.body--theme-dark .button[data-variant=desktop-vibrancy]:active { + border-radius: 6px; background: rgba(255, 255, 255, 0.35); - /* Mac/Button (Dark) */ - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset; + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); } .button[data-variant=ios-secondary] { justify-content: center; @@ -3838,21 +3856,6 @@ body.environment--macos, body.environment--browser, body.environment--windows, b background: rgba(57, 105, 239, 0.2); color: var(--color-accent-blue-active); } -.button[data-size=small] { - line-height: 13px; - height: 20px; - padding: 0px 12px; - border-radius: 5px; -} -.button[data-size=big] { - height: 50px; - padding: 0px 24px; - /* Button */ - font-size: 15px; - font-style: normal; - font-weight: 600; - line-height: 20px; /* 133.333% */ -} .button-bar[data-layout=horizontal] { display: grid; @@ -3899,18 +3902,30 @@ body.environment--macos, body.environment--browser, body.environment--windows, b } .data-list { - padding-left: 18px; + list-style: none; } .data-list__item { word-wrap: anywhere; color: var(--color-text-secondary); line-height: 18px; + position: relative; + padding-left: 20px; } .data-list__item + .data-list__item { margin-top: 3px; } +.data-list__item::before { + content: "•"; + font-size: 12px; + position: absolute; + left: 8px; + top: 8px; + transform: translateY(-50%); + color: currentColor; +} + .ios-separator { padding-top: 16px; border-top: 1px solid var(--color-system-lines); @@ -3948,3 +3963,26 @@ body.environment--macos, body.environment--browser, body.environment--windows, b opacity: 1; visibility: visible; } + +.toggle-report__heading { + margin-bottom: 24px; +} + +.toggle-report__scroller { + margin-bottom: 16px; +} +.toggle-report__scroller .scrollable::-webkit-scrollbar { + width: 10px; +} +.toggle-report__scroller .scrollable::-webkit-scrollbar-track { + border-radius: 6px; +} +.toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { + border: 1px solid rgba(0, 0, 0, 0.1); + background: rgba(0, 0, 0, 0.1); + border-radius: 6px; +} +.body--theme-dark .toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { + border: 1px solid rgba(0, 0, 0, 0.1); + background: rgba(0, 0, 0, 0.3); +} diff --git a/build/app/public/js/base.js b/build/app/public/js/base.js index f44690c8..7a6319b8 100644 --- a/build/app/public/js/base.js +++ b/build/app/public/js/base.js @@ -15136,16 +15136,33 @@ return state; } function useConnectionCount() { - const [state, setCount] = h2(() => dc.lastValue().connection); + const [count, setCount] = h2(() => dc.lastValue().connection); p2(() => { const controller = new AbortController(); - dc.addEventListener("data", (evt) => { - setCount(evt.detail.connection); - }); - return controller.abort; + dc.addEventListener( + "data", + (evt) => { + setCount(evt.detail.connection); + }, + { signal: controller.signal } + ); + window.addEventListener( + useConnectionCount.PAUSE_EVENT, + () => { + controller.abort(); + }, + { signal: controller.signal } + ); + return () => { + controller.abort(); + }; }, []); - return state; + return { count }; } + useConnectionCount.PAUSE_EVENT = "ignore-reconnections"; + useConnectionCount.pause = () => { + window.dispatchEvent(new Event(useConnectionCount.PAUSE_EVENT)); + }; function useData() { const [state, setState] = h2(() => dc.lastValue()); p2(() => { @@ -16938,6 +16955,7 @@ }); }, [model]); function send() { + useConnectionCount.pause(); model.fetch(new SendToggleBreakageReport()); } function reject() { @@ -16970,8 +16988,8 @@ } // shared/js/ui/components/button.jsx - function Button({ children, btnSize, variant = "macos-standard", ...rest }) { - return /* @__PURE__ */ y("button", { type: "button", className: "button", ...rest, "data-variant": variant, "data-size": btnSize }, children); + function Button({ children, btnSize, variant = "desktop-vibrancy", ...rest }) { + return /* @__PURE__ */ y("button", { type: "button", className: "button token-body", ...rest, "data-variant": variant, "data-size": btnSize }, children); } function ButtonBar({ children, layout = "horizontal", ...rest }) { return /* @__PURE__ */ y("div", { className: "button-bar", "data-layout": layout, ...rest }, children); @@ -17192,7 +17210,6 @@ // shared/js/ui/components/toggle-report.jsx function ToggleReport() { - const innerGap = platform.name === "ios" ? "24px" : "16px"; const desktop = platform.name === "macos" || platform.name === "windows"; const extension = platform.name === "browser"; const { value, didClickSuccessScreen } = q2(ToggleReportContext); @@ -17202,10 +17219,10 @@ return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(ToggleReportSent, { onClick: didClickSuccessScreen })); } if (desktop || extension) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y("div", { className: "medium-icon-container hero-icon--toggle-report" }), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")), /* @__PURE__ */ y(DesktopRevealText, { state, toggle: () => dispatch("toggle") }))), state.value === "showing" && /* @__PURE__ */ y(Scrollable, null, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") })))); + return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y("div", { className: "toggle-report__heading" }, /* @__PURE__ */ y(Stack, { gap: "16px" }, /* @__PURE__ */ y("div", { className: "medium-icon-container hero-icon--toggle-report" }), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")), /* @__PURE__ */ y(DesktopRevealText, { state, toggle: () => dispatch("toggle") })))), state.value === "showing" && /* @__PURE__ */ y("div", { className: "toggle-report__scroller" }, /* @__PURE__ */ y(Scrollable, null, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data }))), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") }))); } if (platform.name === "ios") { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y("div", { className: "medium-icon-container hero-icon--toggle-report" }), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")))), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") }), state.value !== "showing" && /* @__PURE__ */ y(RevealText, { toggle: () => dispatch("toggle-ios") })), state.value === "showing" && /* @__PURE__ */ y("div", { className: "ios-separator" }, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })))); + return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y("div", { className: "medium-icon-container hero-icon--toggle-report" }), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")))), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") }), state.value !== "showing" && /* @__PURE__ */ y(RevealText, { toggle: () => dispatch("toggle-ios") })), state.value === "showing" && /* @__PURE__ */ y("div", { className: "ios-separator" }, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })))); } return /* @__PURE__ */ y("p", null, "unsupported platform: ", platform.name); } @@ -17232,9 +17249,9 @@ return null; } function ToggleReportButtons({ send, reject }) { - const buttonVariant = platform.name === "ios" ? "ios-secondary" : "macos-standard"; + const buttonVariant = platform.name === "ios" ? "ios-secondary" : "desktop-vibrancy"; const buttonLayout = platform.name === "ios" ? "vertical" : "horizontal"; - const buttonSize = platform.name === "ios" ? "big" : "small"; + const buttonSize = platform.name === "ios" ? "big" : "desktop-large"; return /* @__PURE__ */ y(ButtonBar, { layout: buttonLayout }, /* @__PURE__ */ y(Button, { variant: buttonVariant, btnSize: buttonSize, onClick: reject }, ns.toggleReport("dontSendReport.title")), /* @__PURE__ */ y(Button, { variant: buttonVariant, btnSize: buttonSize, onClick: send }, ns.report("sendReport.title"))); } function RevealText({ toggle }) { @@ -17249,8 +17266,8 @@ const fetcher = useFetcher(); const features = useFeatures(); const onClose = useClose(); - const connectionCount = useConnectionCount(); - const connectionId = `connection-${connectionCount}`; + const { count } = useConnectionCount(); + const connectionId = `connection-${count}`; p2(() => { document.body.dataset.screen = "toggleReport"; return () => { diff --git a/integration-tests/Extension.js b/integration-tests/Extension.js index 36d06615..25a7447a 100644 --- a/integration-tests/Extension.js +++ b/integration-tests/Extension.js @@ -35,4 +35,22 @@ export class Extension { const callCountAfter = await this.dash.mocks.outgoing({ names: ['getToggleReportOptions'] }) expect(callCountAfter).toHaveLength(2) } + + /** + * This test verifies that once the 'thank you' screen is showing, any + * reconnecting will not trigger any data fetching or changes. + */ + async reconnectsOnThankyouScreen() { + const { page } = this.dash + const callCountBefore = await this.dash.mocks.outgoing({ names: ['getToggleReportOptions'] }) + + await page.evaluate(() => { + window.__playwright.onDisconnect?.() + }) + + await page.waitForTimeout(1000) + + const callCountAfter = await this.dash.mocks.outgoing({ names: ['getToggleReportOptions'] }) + expect(callCountAfter).toHaveLength(callCountBefore.length) + } } diff --git a/integration-tests/browser.spec-int.js b/integration-tests/browser.spec-int.js index aa5e1d56..7e0bd626 100644 --- a/integration-tests/browser.spec-int.js +++ b/integration-tests/browser.spec-int.js @@ -48,6 +48,9 @@ test.describe('Protections toggle -> simple report screen', () => { await dash.mocks.calledForToggleAllowList() await dash.extension.triggersToggleReport() await dash.extension.reconnects() + + await dash.sendToggleReport() + await dash.extension.reconnectsOnThankyouScreen() }) test('shows toggle report + rejects it', async ({ page }) => { forwardConsole(page) diff --git a/integration-tests/ios.spec-int.js-snapshots/screen-toggle-report-show-ios-darwin.png b/integration-tests/ios.spec-int.js-snapshots/screen-toggle-report-show-ios-darwin.png index e59bfe3d..2076f2e3 100644 Binary files a/integration-tests/ios.spec-int.js-snapshots/screen-toggle-report-show-ios-darwin.png and b/integration-tests/ios.spec-int.js-snapshots/screen-toggle-report-show-ios-darwin.png differ diff --git a/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-dashboard-macos-darwin.png b/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-dashboard-macos-darwin.png index e22aafd7..3f2393de 100644 Binary files a/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-dashboard-macos-darwin.png and b/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-dashboard-macos-darwin.png differ diff --git a/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-menu-macos-darwin.png b/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-menu-macos-darwin.png index 8017baf5..42786272 100644 Binary files a/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-menu-macos-darwin.png and b/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-menu-macos-darwin.png differ diff --git a/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-show-macos-darwin.png b/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-show-macos-darwin.png index 320861dd..be42712d 100644 Binary files a/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-show-macos-darwin.png and b/integration-tests/macos.spec-int.js-snapshots/screen-toggle-report-show-macos-darwin.png differ diff --git a/shared/js/ui/components/_button.scss b/shared/js/ui/components/_button.scss index f7647c1f..9ed27352 100644 --- a/shared/js/ui/components/_button.scss +++ b/shared/js/ui/components/_button.scss @@ -1,37 +1,61 @@ .button { - &[data-variant='macos-standard'] { - color: var(--Text-Primary, rgba(0, 0, 0, 0.84)); - text-align: center; + &[data-size='small'] { + line-height: 13px; + height: 20px; + padding: 0px 12px; border-radius: 5px; - border: 0.5px solid rgba(0, 0, 0, 0.1); - background: #fff; - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05); + } + &[data-size='big'] { + height: 50px; + padding: 0px 24px; + /* Button */ + font-size: 15px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 133.333% */ + } + + &[data-size='desktop-large'] { + height: 29px; + padding: 0px 12px; + } + + &[data-variant='desktop-vibrancy'] { + border-radius: 6px; + background: rgba(0, 0, 0, 0.1); + + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, + 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); &:active { - border: 0.5px solid rgba(0, 0, 0, 0.1); - background: #e7e7e7; + border-radius: 6px; + background: rgba(0, 0, 0, 0.2); - /* Mac/Button */ - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, + 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); } .body--theme-dark & { - color: rgba(255, 255, 255, 0.84); - border: 0.5px solid rgba(0, 0, 0, 0); - background: rgba(255, 255, 255, 0.25); - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), - 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset; + border-radius: 6px; + background: rgba(255, 255, 255, 0.28); + + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, + 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); &:active { - border: 0.5px solid rgba(0, 0, 0, 0); + border-radius: 6px; background: rgba(255, 255, 255, 0.35); - /* Mac/Button (Dark) */ - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), - 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset; + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, + 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); } } } + &[data-variant='ios-secondary'] { justify-content: center; align-items: center; @@ -48,21 +72,6 @@ color: var(--color-accent-blue-active); } } - &[data-size='small'] { - line-height: 13px; - height: 20px; - padding: 0px 12px; - border-radius: 5px; - } - &[data-size='big'] { - height: 50px; - padding: 0px 24px; - /* Button */ - font-size: 15px; - font-style: normal; - font-weight: 600; - line-height: 20px; /* 133.333% */ - } } .button-bar { diff --git a/shared/js/ui/components/_stack.scss b/shared/js/ui/components/_stack.scss index e0cf869d..d8bf4aef 100644 --- a/shared/js/ui/components/_stack.scss +++ b/shared/js/ui/components/_stack.scss @@ -23,21 +23,52 @@ background: rgba(255, 255, 255, 0.03); border-color: rgba(255, 255, 255, 0.09); } + + //&::-webkit-scrollbar { + // width: 0.5em !important; + // scroll-behavior: smooth !important; + //} + // + //&::-webkit-scrollbar-track { + // -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3) !important; + //} + // + //&::-webkit-scrollbar-thumb { + // background-color: rgba(0, 0, 0, 0.01) !important; + // outline: 1px solid rgba(0, 0, 0, 0.1) !important; + // border-radius: 8px !important; + //} + // + //.body--theme-dark &::-webkit-scrollbar-thumb { + // background-color: red !important; + //} } .data-list { - padding-left: 18px; + list-style: none; } .data-list__item { word-wrap: anywhere; color: var(--color-text-secondary); line-height: 18px; + position: relative; + padding-left: 20px; + .data-list__item { margin-top: 3px; } } +.data-list__item::before { + content: '•'; + font-size: 12px; + position: absolute; + left: 8px; + top: 8px; + transform: translateY(-50%); + color: currentColor; +} + .ios-separator { padding-top: 16px; border-top: 1px solid var(--color-system-lines); diff --git a/shared/js/ui/components/button.jsx b/shared/js/ui/components/button.jsx index 36cdf217..d7a9423a 100644 --- a/shared/js/ui/components/button.jsx +++ b/shared/js/ui/components/button.jsx @@ -3,13 +3,13 @@ import { h } from 'preact' /** * @typedef {object} ComponentProps - * @property {"macos-standard" | "ios-secondary"} [variant] - * @property {"big" | "small"} [btnSize] + * @property {"desktop-vibrancy" | "ios-secondary"} [variant] + * @property {"big" | "desktop-large"} [btnSize] * @param {import("preact").ComponentProps<'button'> & ComponentProps} props */ -export function Button({ children, btnSize, variant = 'macos-standard', ...rest }) { +export function Button({ children, btnSize, variant = 'desktop-vibrancy', ...rest }) { return ( - ) diff --git a/shared/js/ui/components/toggle-report.jsx b/shared/js/ui/components/toggle-report.jsx index 72fd8f51..c513589b 100644 --- a/shared/js/ui/components/toggle-report.jsx +++ b/shared/js/ui/components/toggle-report.jsx @@ -16,7 +16,6 @@ import { ToggleReportTitle } from './toggle-report/toggle-report-title' import { getContentHeight, setupMutationObserverForExtensions } from '../../browser/common' export function ToggleReport() { - const innerGap = platform.name === 'ios' ? '24px' : '16px' const desktop = platform.name === 'macos' || platform.name === 'windows' const extension = platform.name === 'browser' @@ -43,24 +42,26 @@ export function ToggleReport() { return ( {extension && } - - - -
- {ns.toggleReport('siteNotWorkingTitle.title')} -
-

{ns.toggleReport('siteNotWorkingSubTitle.title')}

- dispatch('toggle')} /> -
-
- {state.value === 'showing' && ( - - - - )} - dispatch('send')} reject={() => dispatch('reject')} /> +
+ +
+ {ns.toggleReport('siteNotWorkingTitle.title')} +
+

{ns.toggleReport('siteNotWorkingSubTitle.title')}

+ dispatch('toggle')} /> +
- +
+ {state.value === 'showing' && ( +
+ + + +
+ )} +
+ dispatch('send')} reject={() => dispatch('reject')} /> +
) } @@ -70,7 +71,7 @@ export function ToggleReport() { - +
{ns.toggleReport('siteNotWorkingTitle.title')}
@@ -127,9 +128,9 @@ function SetAutoHeight() { } function ToggleReportButtons({ send, reject }) { - const buttonVariant = platform.name === 'ios' ? 'ios-secondary' : 'macos-standard' + const buttonVariant = platform.name === 'ios' ? 'ios-secondary' : 'desktop-vibrancy' const buttonLayout = platform.name === 'ios' ? 'vertical' : 'horizontal' - const buttonSize = platform.name === 'ios' ? 'big' : 'small' + const buttonSize = platform.name === 'ios' ? 'big' : 'desktop-large' return ( diff --git a/shared/js/ui/components/toggle-report/toggle-report-provider.jsx b/shared/js/ui/components/toggle-report/toggle-report-provider.jsx index 82d79a2e..9868ebea 100644 --- a/shared/js/ui/components/toggle-report/toggle-report-provider.jsx +++ b/shared/js/ui/components/toggle-report/toggle-report-provider.jsx @@ -9,6 +9,7 @@ import { SendToggleBreakageReport, } from '../../../browser/common' import { toggleReportScreenSchema } from '../../../../../schema/__generated__/schema.parsers.mjs' +import { useConnectionCount } from '../../../../../v2/data-provider' export const ToggleReportContext = createContext({ value: /** @type {import('../../../../../schema/__generated__/schema.types').ToggleReportScreen} */ ({}), @@ -62,6 +63,7 @@ export function ToggleReportProvider({ children, model, screen }) { }, [model]) function send() { + useConnectionCount.pause() model.fetch(new SendToggleBreakageReport()) } function reject() { diff --git a/shared/js/ui/components/toggle-report/toggle-report.scss b/shared/js/ui/components/toggle-report/toggle-report.scss index 7fc7109e..82fac61b 100644 --- a/shared/js/ui/components/toggle-report/toggle-report.scss +++ b/shared/js/ui/components/toggle-report/toggle-report.scss @@ -15,3 +15,33 @@ opacity: 1; visibility: visible; } + +.toggle-report__heading { + margin-bottom: 24px; +} +.toggle-report__scroller { + margin-bottom: 16px; + + .scrollable { + &::-webkit-scrollbar { + width: 10px; + } + + &::-webkit-scrollbar-track { + border-radius: 6px; + } + + &::-webkit-scrollbar-thumb { + border: 1px solid rgba(0, 0, 0, 0.1); + background: rgba(0, 0, 0, 0.1); + border-radius: 6px; + } + + .body--theme-dark &::-webkit-scrollbar-thumb { + border: 1px solid rgba(0, 0, 0, 0.1); + background: rgba(0, 0, 0, 0.3); + } + } +} +.toggle-report__footer { +} diff --git a/v2/data-provider.js b/v2/data-provider.js index 36bd0a66..7999bb30 100644 --- a/v2/data-provider.js +++ b/v2/data-provider.js @@ -315,18 +315,47 @@ function useInternalData() { } /** - * @return {number} + * @return {{ count: number }} */ export function useConnectionCount() { - const [state, setCount] = useState(() => dc.lastValue().connection) + const [count, setCount] = useState(() => dc.lastValue().connection) + useEffect(() => { const controller = new AbortController() - dc.addEventListener('data', (/** @type {any} */ evt) => { - setCount(evt.detail.connection) - }) - return controller.abort + dc.addEventListener( + 'data', + (/** @type {any} */ evt) => { + setCount(evt.detail.connection) + }, + { signal: controller.signal } + ) + + window.addEventListener( + useConnectionCount.PAUSE_EVENT, + () => { + controller.abort() + }, + { signal: controller.signal } + ) + + return () => { + controller.abort() + } }, []) - return state + + return { count } +} + +/** + * @type {string} + */ +useConnectionCount.PAUSE_EVENT = 'ignore-reconnections' + +/** + * Allow consumers to trigger the event without knowing any details + */ +useConnectionCount.pause = () => { + window.dispatchEvent(new Event(useConnectionCount.PAUSE_EVENT)) } /** diff --git a/v2/screens/toggle-report-screen.jsx b/v2/screens/toggle-report-screen.jsx index 324461ff..3d5d687b 100644 --- a/v2/screens/toggle-report-screen.jsx +++ b/v2/screens/toggle-report-screen.jsx @@ -11,8 +11,8 @@ export function ToggleReportScreen() { const fetcher = useFetcher() const features = useFeatures() const onClose = useClose() - const connectionCount = useConnectionCount() - const connectionId = `connection-${connectionCount}` + const { count } = useConnectionCount() + const connectionId = `connection-${count}` useEffect(() => { document.body.dataset.screen = 'toggleReport'