1+ import ShareIcon from '@mui/icons-material/Share' ;
2+ import SaveIcon from '@mui/icons-material/Save' ;
3+ import ContentCopyIcon from '@mui/icons-material/ContentCopy' ;
4+ import { ReactNode , useContext , useState } from "react"
5+ import { IconButtonTooltip } from "../../SceneEdition/IconButtonTooltip"
6+ import { Snackbar , Stack , Tooltip } from "@mui/material"
7+ import { CreatorContext } from '../../CreatorContext' ;
8+ import { LocalStorage } from '../../../../../localStorage' ;
9+ import { PilasBloquesApi } from '../../../../../pbApi' ;
10+ import { CreatorActionButton } from '../CreatorActionButton' ;
11+ import { DialogSnackbar } from '../../../../dialogSnackbar/DialogSnackbar' ;
12+ import { useTranslation } from 'react-i18next' ;
13+ import { SerializedChallenge } from '../../../../serializedChallenge' ;
14+ import { DownloadButton } from '../DownloadButton' ;
15+
16+ export const CopyToClipboardButton = ( { textToCopy } : { textToCopy : string } ) => {
17+
18+ const [ openSnackbar , setOpenSnackbar ] = useState ( false )
19+
20+ const { t } = useTranslation ( 'creator' ) ;
21+
22+ const handleClick = ( ) => {
23+ setOpenSnackbar ( true )
24+ navigator . clipboard . writeText ( textToCopy )
25+ }
26+
27+ return < >
28+ < IconButtonTooltip icon = { < ContentCopyIcon /> } onClick = { handleClick } tooltip = { t ( 'editor.buttons.copyToClipboard' ) } />
29+ < Snackbar
30+ open = { openSnackbar }
31+ onClose = { ( ) => setOpenSnackbar ( false ) }
32+ autoHideDuration = { 2000 }
33+ message = { t ( 'editor.buttons.copiedToClipboard' ) }
34+ />
35+ </ >
36+ }
37+
38+ export const ShareButtons = ( ) => {
39+ const { sharedId } = useContext ( CreatorContext )
40+
41+ return < >
42+ < Stack direction = "row" justifyContent = "space-between" alignItems = 'center' >
43+ { // If the challenge has already been saved, show Save, else show Share, which saves for the first time.
44+ sharedId ? < SaveButton /> : < ShareUrlButton />
45+ }
46+ < DownloadButton />
47+ </ Stack >
48+ </ >
49+ }
50+
51+ const ShareUrlButton = ( ) =>
52+ < ChallengeUpsertButton Icon = { < ShareIcon /> } nametag = "shareUrl" challengeUpsert = { PilasBloquesApi . shareChallenge } />
53+
54+ const SaveButton = ( ) =>
55+ < ChallengeUpsertButton Icon = { < SaveIcon /> } nametag = "save" challengeUpsert = { PilasBloquesApi . saveChallenge } />
56+
57+ export const ChallengeUpsertButton = ( { Icon, challengeUpsert, nametag } : { Icon : ReactNode , nametag : string , challengeUpsert : ( challenge : SerializedChallenge ) => Promise < SerializedChallenge > } ) => {
58+
59+ const { setSharedId } = useContext ( CreatorContext )
60+ const userLoggedIn = ! ! LocalStorage . getUser ( )
61+ const [ serverError , setServerError ] = useState < boolean > ( false )
62+ const { t } = useTranslation ( 'creator' ) ;
63+ const [ savedSnackbar , setSavedSnackbarOpen ] = useState ( false )
64+
65+ const handleClick = async ( ) => {
66+ try {
67+ const savedChallenge = await challengeUpsert ( LocalStorage . getCreatorChallenge ( ) ! )
68+ setSharedId ( savedChallenge . sharedId ! )
69+ setSavedSnackbarOpen ( true )
70+ }
71+ catch ( error ) {
72+ setServerError ( true )
73+ }
74+ }
75+
76+ return < >
77+ < Snackbar
78+ open = { savedSnackbar }
79+ onClose = { ( ) => setSavedSnackbarOpen ( false ) }
80+ autoHideDuration = { 2000 }
81+ message = { t ( 'editor.buttons.savedCorrectly' ) }
82+ />
83+ < Tooltip title = { ! userLoggedIn ? t ( 'editor.loginWarning' ) : '' } followCursor >
84+ < div >
85+ < CreatorActionButton data-testid = "upsertButton" onClick = { handleClick } disabled = { ! userLoggedIn } startIcon = { Icon } variant = 'contained' nametag = { nametag } />
86+ </ div >
87+ </ Tooltip >
88+ < DialogSnackbar open = { serverError } onClose = { ( ) => setServerError ( false ) } message = { t ( 'editor.serverError' ) } />
89+ </ >
90+ }
0 commit comments