diff --git a/ui/analyse/src/study/studyShare.ts b/ui/analyse/src/study/studyShare.ts index 6c51a89326c2b..b84c2e0846bfb 100644 --- a/ui/analyse/src/study/studyShare.ts +++ b/ui/analyse/src/study/studyShare.ts @@ -83,6 +83,19 @@ export function ctrl( }; } +async function writePgnClipboard(url: string): Promise { + // Firefox does not support `ClipboardItem` + if (typeof ClipboardItem === 'undefined') { + const pgn = await xhrText(url); + return navigator.clipboard.writeText(pgn); + } else { + const clipboardItem = new ClipboardItem({ + 'text/plain': xhrText(url).then(pgn => new Blob([pgn])), + }); + return navigator.clipboard.write([clipboardItem]); + } +} + export function view(ctrl: StudyShareCtrl): VNode { const studyId = ctrl.studyId, chapter = ctrl.chapter(); @@ -150,10 +163,14 @@ export function view(ctrl: StudyShareCtrl): VNode { title: ctrl.trans.noarg('copyChapterPgnDescription'), }, hook: bind('click', async event => { - const pgn = await xhrText(`/study/${studyId}/${ctrl.chapter().id}.pgn`); - await navigator.clipboard.writeText(pgn); - (event.target as HTMLElement).setAttribute('data-icon', ''); - setTimeout(() => (event.target as HTMLElement).setAttribute('data-icon', ''), 1000); + const iconFeedback = (success: boolean) => { + (event.target as HTMLElement).setAttribute('data-icon', success ? '' : ''); + setTimeout(() => (event.target as HTMLElement).setAttribute('data-icon', ''), 1000); + }; + writePgnClipboard(`/study/${studyId}/${ctrl.chapter().id}.pgn`).then( + () => iconFeedback(true), + () => iconFeedback(false) + ); }), }, ctrl.trans.noarg('copyChapterPgn')