Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Restructure the free-plan upgrade notice into a balanced Notice.Title heads-up line, a Notice.Description upsell pitch, and a concise "Upgrade" Notice.ActionButton, replacing the out-of-place dark button.
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ const UPGRADE_TRIGGER_FREE_PLAN_TEXT = __(
'The free plan includes one video upload.',
'jetpack-videopress-pkg'
);
const UPGRADE_TRIGGER_UNLOCK_TEXT = __(
'Unlock unlimited videos, 1TB of storage, and more!',
'jetpack-videopress-pkg'
);

const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) => {
const { adminUri, siteSuffix } = window.jetpackVideoPressInitialState;
Expand Down Expand Up @@ -252,24 +256,20 @@ const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) =
// VIDP-245: keep the `Notice.Root` children shape invariant across the
// `hasUsedVideo` flip. base-ui@1.4.1's `useRenderElement` swaps between two
// different ref-merge hooks depending on subtree shape, so conditionally
// mounting `<Notice.Description>` (as this did before) misaligns its stored
// fork-ref and crashes on the next upload/delete. Always render the
// Description — mirroring the modern dashboard's `free-tier-notice.tsx` —
// varying only its text, with a non-empty fallback nudge before the first
// upload so we never render an empty styled row. The two strings are hoisted
// to module scope (above) to avoid the terser i18n ternary-fold.
const description = hasUsedVideo
? UPGRADE_TRIGGER_USED_VIDEO_TEXT
: UPGRADE_TRIGGER_FREE_PLAN_TEXT;

const cta = __(
'Upgrade now to unlock unlimited videos, 1TB of storage, and more!',
'jetpack-videopress-pkg'
);
// mounting/unmounting a `Notice` subcomponent across the flip misaligns its
// stored fork-ref and crashes on the next upload/delete. Therefore always
// render `Notice.Title`, `Notice.Description` and `Notice.Actions` — never
// wrap any of them in a `hasUsedVideo && (...)` conditional. Vary only the
// TEXT: the `title` line carries the contextual heads-up (non-empty in both
// states) while the Description holds the constant upsell pitch. The strings
// are hoisted to module scope (above) to avoid the terser i18n ternary-fold.
const title = hasUsedVideo ? UPGRADE_TRIGGER_USED_VIDEO_TEXT : UPGRADE_TRIGGER_FREE_PLAN_TEXT;
const cta = __( 'Upgrade', 'jetpack-videopress-pkg' );

return (
<Notice.Root intent="info" className={ styles[ 'upgrade-trigger' ] }>
<Notice.Description>{ description }</Notice.Description>
<Notice.Title>{ title }</Notice.Title>
<Notice.Description>{ UPGRADE_TRIGGER_UNLOCK_TEXT }</Notice.Description>
<Notice.Actions>
<Notice.ActionButton onClick={ onButtonClickHandler }>{ cta }</Notice.ActionButton>
</Notice.Actions>
Expand Down
Loading