From 24742ab9fbea7382668a5cc0b4ba0117a21f5fda Mon Sep 17 00:00:00 2001 From: kraktus Date: Fri, 21 Apr 2023 08:24:47 +0200 Subject: [PATCH 1/2] better user feedback if copying the chapter PGN fails --- ui/analyse/src/study/studyShare.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/analyse/src/study/studyShare.ts b/ui/analyse/src/study/studyShare.ts index 6c51a89326c2b..71a6b196333c9 100644 --- a/ui/analyse/src/study/studyShare.ts +++ b/ui/analyse/src/study/studyShare.ts @@ -151,9 +151,14 @@ export function view(ctrl: StudyShareCtrl): VNode { }, 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); + }; + navigator.clipboard.writeText(pgn).then( + () => iconFeedback(true), + () => iconFeedback(false) + ); }), }, ctrl.trans.noarg('copyChapterPgn') From 88aeb125d684338249ccd49dd6f7d81321e8d1e9 Mon Sep 17 00:00:00 2001 From: kraktus Date: Fri, 21 Apr 2023 10:16:44 +0200 Subject: [PATCH 2/2] Study chapter: fix PGN to clipboard for Safari The issue was that we waited for the PGN http request to return before calling the clipboard API, and at that time it was already disabled back by the browser. Safari fix is a simplified version of https://developer.apple.com/forums/thread/691873. Unfortunately, Firefox does not support the `ClipboardItem` so made a workaround. Tested on Safari and Firefox. fix https://github.com/lichess-org/lila/issues/12461 --- ui/analyse/src/study/studyShare.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ui/analyse/src/study/studyShare.ts b/ui/analyse/src/study/studyShare.ts index 71a6b196333c9..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,12 +163,11 @@ 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`); const iconFeedback = (success: boolean) => { (event.target as HTMLElement).setAttribute('data-icon', success ? '' : ''); setTimeout(() => (event.target as HTMLElement).setAttribute('data-icon', ''), 1000); }; - navigator.clipboard.writeText(pgn).then( + writePgnClipboard(`/study/${studyId}/${ctrl.chapter().id}.pgn`).then( () => iconFeedback(true), () => iconFeedback(false) );