Skip to content

Conversation

@emilysaffron
Copy link
Contributor

@emilysaffron emilysaffron commented Jan 20, 2026

Resolves JIRA: WS-1959

Summary

Following webcores pattern for a share button within the player:

Loads in a custom SMP plugin created by Webcore SFV to give access to the shadow-dom of the media player for a Video Overlay to be attached to.
Creates a React Portal for a VideoOverlay component with the share button in to render within.
Adds refs to new instances of the MediaLoader to prevent infinite reloads.

To be done

  • Have the button appear with the other controls on hover, not persistently on top of the player.
  • Update the button when the video changes folllowing a swipe/use of the next video button. This will be to do with the playlist i think?
  • Potential next step reach out to SFV team (Bill Thornton good first contact?) for guidance
  • Worth noting just putting our share button in the side controls (under the next and previous arrows) is super straightforward, but obvs only works for desktop so not ideal, but maybe a good stop gap if this is super super urgent.

Code changes

  • A bullet point list of key code changes that have been made.

Developer Checklist

  • UX
    • UX Criteria met (visual UX & screenreader UX)
  • Accessibility
    • Accessibility Acceptance Criteria met
    • Accessibility swarm completed
    • Component Health updated
    • P1 accessibility bugs resolved
    • P2/P3 accessibility bugs planned (if not resolved)
  • Security
    • Security issues addressed
    • Threat Model updated
  • Documentation
    • Docs updated (runbook, READMEs)
  • Testing
    • Feature tested on relevant environments
  • Comms
    • Relevant parties notified of changes

Testing

  • Manual Testing required?
    • Local (Ready-For-Test, Local)
    • Test (Ready-For-Test, Test)
    • Preview (Ready-For-Test, Preview)
    • Live (Ready-For-Test, Live)
  • Manual Testing complete?
    • Local
    • Test
    • Preview
    • Live

Additional Testing Steps

  1. List the steps required to test this PR.

Useful Links

@emilysaffron emilysaffron self-assigned this Jan 20, 2026
Comment on lines +132 to +140
if (!playerElementRef.current) return;

if (playerKeyRef.current === playerKey) {
console.log('Media Loader player ref already existsRETURN');
return;
}

playerKeyRef.current = playerKey;
console.log('Media Loader: INITIALISE PLAYER');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These refs are here to prevent infinite re-renders caused by this use effect and the plugin combined.

Cycle of what was happening:

  • hook to update videoOverlayContainer passed through to here from the carousel
  • the hook is passed to and called by the plugin below (L211)
  • this updates the state, and triggers a re-render of the carousel
  • this triggers this use effect to run, re calling the hook from the plugin
  • this updates the state , the loop continues forever 😢

playlistObject?: Playlist;
plugins?: {
toLoad: { html: string; playerOnly?: boolean }[];
toLoad: { html: string; playerOnly?: boolean; data?: any }[];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

things are set to any for right now whilst i was trying to debug and get something working - obvs not permanent!

@@ -0,0 +1,24 @@
/* eslint-disable import/no-extraneous-dependencies */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is copied over from the webcore implementation, would question whether we need it once we progress with this a bit more but have copied everything over as 1-1 as possible for now to help debugging and eliminate possible sources of things going wrong.

const SPACING_4 = '16px';
const SPACING_2 = '8px';
const SPACING_7 = '28px';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of this styling follows our conventions, but again same reasoning as above for copying webcore as 1-1 as possible for now.

Comment on lines +80 to +86
if (selectedVideoIndex !== null) {
console.log(
'blocks',
blocks?.[selectedVideoIndex]?.model?.video?.id.split(':'),
);
urn = blocks?.[selectedVideoIndex]?.model?.video?.id.split(':')[4];
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probs would be a good idea to do this in the BFF, we could pass through the full share url including the service name from there and it would be a bit cleaner.

const [shareUrl, setShareUrl] = useState();

useEffect(() => {
setShareUrl(`https://${service}/articles/${urn}`);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above about doing this work in the bff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants