From 84807d53b5798c5281b1e06044293a8638d55e68 Mon Sep 17 00:00:00 2001 From: fatadel Date: Fri, 24 Jul 2026 10:49:18 +0200 Subject: [PATCH 1/2] Improve discoverability of downloading a local profile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Downloading a profile was only reachable from inside the single "Upload Local Profile" menu, so users looking to save a profile to disk had no way to discover it from the toolbar. Replace that single menu with two buttons, "Download…" and "Share…", each with its own icon. Both open the same options panel; only the heading and the action button differ, so Download saves the profile to a file and Share uploads it for a shareable link. Closes #3620 --- locales/en-US/app.ftl | 15 +- src/components/app/MenuButtons/Publish.css | 35 +++- src/components/app/MenuButtons/Publish.tsx | 110 +++++++--- src/components/app/MenuButtons/index.tsx | 75 ++++--- src/test/components/MenuButtons.test.tsx | 43 +++- .../__snapshots__/MenuButtons.test.tsx.snap | 195 ++++++++++++++---- 6 files changed, 343 insertions(+), 130 deletions(-) diff --git a/locales/en-US/app.ftl b/locales/en-US/app.ftl index ec443ae5d0..91c30908bb 100644 --- a/locales/en-US/app.ftl +++ b/locales/en-US/app.ftl @@ -576,11 +576,14 @@ MenuButtons--index--metaInfo-button = MenuButtons--index--full-view = Full View MenuButtons--index--cancel-upload = Cancel Upload -MenuButtons--index--share-upload = - .label = Upload Local Profile +MenuButtons--index--download = + .label = Download… -MenuButtons--index--share-re-upload = - .label = Re-upload +MenuButtons--index--share = + .label = Share… + +MenuButtons--index--reshare = + .label = Re-share… MenuButtons--index--share-error-uploading = .label = Error uploading @@ -758,9 +761,11 @@ MenuButtons--publish--renderCheckbox-label-private-browsing-warning-image = MenuButtons--publish--renderCheckbox-label-argument-values = Include JavaScript execution tracing function argument values MenuButtons--publish--renderCheckbox-label-argument-values-warning-image = .title = This profile contains function argument values recorded from the page, which may include personal data -MenuButtons--publish--reupload-performance-profile = Re-upload Performance Profile MenuButtons--publish--share-performance-profile = Share Performance Profile +MenuButtons--publish--reshare-performance-profile = Re-share Performance Profile +MenuButtons--publish--download-performance-profile = Download Performance Profile MenuButtons--publish--info-description = Upload your profile and make it accessible to anyone with the link. +MenuButtons--publish--download-info-description = Save this profile as a file on your computer. MenuButtons--publish--info-description-default = By default, your personal data is removed. MenuButtons--publish--info-description-firefox-nightly2 = This profile is from { -firefox-nightly-brand-name }, so by default most information is included. MenuButtons--publish--include-additional-data = Include additional data that may be identifiable diff --git a/src/components/app/MenuButtons/Publish.css b/src/components/app/MenuButtons/Publish.css index 35048455a9..4d6d4ca9b1 100644 --- a/src/components/app/MenuButtons/Publish.css +++ b/src/components/app/MenuButtons/Publish.css @@ -17,6 +17,13 @@ background-image: var(--internal-uploading-icon); } +.menuButtonsDownloadButton::before { + background-image: url(../../../../res/img/svg/download.svg); + + /* download.svg is 14x20, so size by height to fit the square icon slot. */ + background-size: auto 12px; +} + .menuButtonsShareButtonError { --internal-error-foreground-color: white; --internal-error-background-color: var(--red-60); @@ -58,6 +65,10 @@ --internal-uploading-icon: url(../../../../res/img/svg/sharing-animated-dark-12.svg); } + .menuButtonsDownloadButton::before { + background-image: url(../../../../res/img/svg/download-light.svg); + } + .menuButtonsShareButtonError { --internal-error-foreground-color: var(--grey-20); } @@ -75,22 +86,22 @@ .publishPanelContent { position: relative; - /* This aligns all content, except the big icon. */ - padding-left: 70px; + /* Reserve space on the left for the title icon. */ + padding-left: 34px; } .publishPanelTitle { - /* "60px" This is the value to put the background image at the right location. - * This background image is 44x44, so this puts it 16px left of the text. */ - padding-left: 60px; - margin: 0 0 0 -60px; + padding-left: 28px; + + /* Negative margin pulls the 18px icon back into the gutter, 10px before the text. */ + margin: 0 0 6px -28px; background: var(--internal-info-icon) left center no-repeat; - line-height: 44px; /* This is the height of the background image */ + background-size: 18px 18px; + line-height: 28px; } .publishPanelInfoDescription { - flex: 1; - margin-bottom: 1em; + margin: 0 0 12px; line-height: 1.5; } @@ -111,7 +122,7 @@ .publishPanelButtons { display: flex; justify-content: right; - margin-top: 20px; + margin-top: 16px; } .publishPanelButton { @@ -155,6 +166,10 @@ background: var(--internal-download-icon) center center no-repeat; } +.publishPanelButtonsDownloadPrimary .publishPanelButtonsSvgDownload { + background-image: url(../../../../res/img/svg/download-light.svg); +} + .menuButtonsDownloadSize { display: inline-block; margin: 0 4px; diff --git a/src/components/app/MenuButtons/Publish.tsx b/src/components/app/MenuButtons/Publish.tsx index 32a37d37af..38fd2275cc 100644 --- a/src/components/app/MenuButtons/Publish.tsx +++ b/src/components/app/MenuButtons/Publish.tsx @@ -51,6 +51,7 @@ import './Publish.css'; import { Localized } from '@fluent/react'; type OwnProps = { + readonly mode: 'download' | 'share'; readonly isRepublish?: boolean; }; @@ -101,7 +102,9 @@ class PublishPanelImpl extends React.PureComponent { labelL10nId: string, additionalContent?: React.ReactNode ) { - const { checkedSharingOptions } = this.props; + const { checkedSharingOptions, uploadPhase } = this.props; + const isUploading = + uploadPhase === 'uploading' || uploadPhase === 'compressing'; return (