-
Notifications
You must be signed in to change notification settings - Fork 0
/
.eslintcache
1 lines (1 loc) · 56.7 KB
/
.eslintcache
1
[{"D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\index.js":"1","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\reportWebVitals.js":"2","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\App.js":"3","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\buttonList.js":"4","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\recommendationPage.js":"5","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\useGridCanvas.js":"6","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\useCanvas.js":"7","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\useProgressCanvas.js":"8","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\axios.js":"9","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\customButtonStyle.js":"10"},{"size":517,"mtime":1609951679434,"results":"11","hashOfConfig":"12"},{"size":375,"mtime":1609951679435,"results":"13","hashOfConfig":"12"},{"size":17569,"mtime":1611145307504,"results":"14","hashOfConfig":"12"},{"size":2947,"mtime":1611144840259,"results":"15","hashOfConfig":"12"},{"size":14712,"mtime":1611135424783,"results":"16","hashOfConfig":"12"},{"size":2579,"mtime":1627055643301,"results":"17","hashOfConfig":"12"},{"size":2773,"mtime":1611133824063,"results":"18","hashOfConfig":"12"},{"size":2176,"mtime":1611134420936,"results":"19","hashOfConfig":"12"},{"size":2380,"mtime":1611072363676,"results":"20","hashOfConfig":"12"},{"size":313,"mtime":1611063940153,"results":"21","hashOfConfig":"12"},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},"n52dqg",{"filePath":"25","messages":"26","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"27","messages":"28","errorCount":0,"warningCount":22,"fixableErrorCount":0,"fixableWarningCount":0,"source":"29","usedDeprecatedRules":"24"},{"filePath":"30","messages":"31","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"32","usedDeprecatedRules":"24"},{"filePath":"33","messages":"34","errorCount":0,"warningCount":11,"fixableErrorCount":0,"fixableWarningCount":0,"source":"35","usedDeprecatedRules":"24"},{"filePath":"36","messages":"37","errorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"38","messages":"39","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"40","usedDeprecatedRules":"24"},{"filePath":"41","messages":"42","errorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"43","usedDeprecatedRules":"24"},{"filePath":"44","messages":"45","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"46","messages":"47","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},"D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\index.js",[],["48","49"],"D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\reportWebVitals.js",[],"D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\App.js",["50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71"],"import Soundfont from 'soundfont-player'\r\nimport './App.css'\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport ButtonList from './buttonList.js'\r\nimport RecPage from './recommendationPage.js'\r\nimport { \r\n getInitPiece, \r\n composeRequest,\r\n downloadSongRequest,\r\n rateSongRequest,\r\n getRecommendationsRequest\r\n} from './axios'\r\nimport { useCanvas, Canvas, myDraw } from './useCanvas.js';\r\nimport { useGridCanvas, GridCanvas } from './useGridCanvas.js';\r\nimport { useProgressCanvas, ProgressCanvas, progressDraw, stopProgress } from './useProgressCanvas.js';\r\n\r\nimport 'antd/dist/antd.css';\r\nimport {\r\n PlayCircleFilled,\r\n PauseCircleFilled,\r\n SlidersFilled,\r\n RedoOutlined,\r\n ArrowRightOutlined,\r\n ArrowLeftOutlined,\r\n LoadingOutlined,\r\n DownloadOutlined,\r\n LikeOutlined,\r\n LikeFilled,\r\n DislikeOutlined,\r\n DislikeFilled,\r\n CommentOutlined,\r\n StarFilled,\r\n SearchOutlined\r\n} from '@ant-design/icons';\r\nimport { Space, Divider, Typography, Spin } from 'antd';\r\n// import { Button } from '@material-ui/core';\r\n// import { ActionButton } from './customButtonStyle.js'\r\nimport { \r\n PlayArrowRounded,\r\n StopRounded,\r\n ArrowBackRounded,\r\n MusicNoteRounded\r\n} from '@material-ui/icons'\r\n\r\nconst { Title, Text } = Typography;\r\n\r\n\r\nlet ac, pianoPlayer, timeOutButt, timeOutButt2=[], timeOutButt3=[];\r\nfunction App() {\r\n /***** Result Page *****/\r\n const [originPage, setOriginPage] = useState(true)\r\n const [recommendationPage, setRecommendationPage] = useState(false)\r\n const [recommandProps, setRecommendationProps] = useState()\r\n\r\n const requestRecommendations = async()=>{\r\n let result = await getRecommendationsRequest(refId, composedId);\r\n //console.log(result.n_results, result.composed_id, result.recommended_songs)\r\n setRecommendationProps(result)\r\n setRecommendationPage(true)\r\n }\r\n\r\n /***** Audio Playing *****/\r\n const [initNotes, setInitNotes] = useState([])\r\n const [composedNotes, setComposedNotes] = useState([])\r\n const [isPlayingInit, setIsPlayingInit] = useState(false)\r\n const [isPlayingComposed, setIsPlayingComposed] = useState(false)\r\n\r\n const tick2Sec = (tic, tpb = 480) => {\r\n return parseFloat(60*tic/tempo/tpb);\r\n }\r\n \r\n const midi2Play = e => {\r\n return {\r\n time: tick2Sec(e.start_tick),\r\n note: e.key,\r\n gain: 5*e.velocity/128,\r\n duration: tick2Sec(e.duration)\r\n }\r\n }\r\n\r\n const midi2Progress = e => {\r\n return {\r\n //for clock\r\n time: tick2Sec(e.start_tick),\r\n duration: tick2Sec(e.duration),\r\n \r\n key: e.key - 20, // [myRef]\r\n gain: e.velocity/128,\r\n //for draw\r\n start: Math.floor(e.start_tick/120),\r\n end: Math.floor(e.duration/120)\r\n }\r\n }\r\n\r\n const myPlayer = (player, notes, setFunc) => {\r\n return new Promise((resolve) => {\r\n const noteSched = notes.map(midi2Play)\r\n const noteProgress = notes.map(midi2Progress)\r\n const timeoutSec = 1000 * (noteSched[ noteSched.length - 1 ].time + noteSched[ noteSched.length - 1 ].duration);\r\n\r\n player.schedule(ac.currentTime, noteSched)\r\n progressDraw(noteProgress, timeOutButt2, timeOutButt3);\r\n \r\n timeOutButt = setTimeout(() => {\r\n setFunc(false)\r\n progressClear()\r\n resolve()\r\n }, timeoutSec)\r\n })\r\n }\r\n\r\n const playButton = (tag) => {\r\n return async() => {\r\n const isPlaying = (tag === \"i\")? isPlayingInit : isPlayingComposed\r\n const notes = (tag === \"i\")? initNotes : composedNotes\r\n const setFunc = (tag === \"i\")?\r\n ele => {setIsPlayingInit(ele)} :\r\n ele => {setIsPlayingComposed(ele)}\r\n\r\n if(isPlaying){\r\n pianoPlayer.stop()\r\n setFunc(false)\r\n\r\n clearTimeout(timeOutButt)\r\n timeOutButt2.forEach(e=>{clearTimeout(e)})\r\n timeOutButt3.forEach(e=>{clearTimeout(e)})\r\n progressClear()\r\n }\r\n else{\r\n setFunc(true)\r\n await myPlayer(pianoPlayer, notes, setFunc)\r\n }\r\n }\r\n }\r\n\r\n useEffect( async () => {\r\n ac = new window.AudioContext();\r\n pianoPlayer = await Soundfont.instrument(ac, 'acoustic_grand_piano', { soundfont: 'MusyngKite' });\r\n }, [])\r\n\r\n /***** Button List React *****/\r\n const [polyph, setPolyph] = useState([0, 0, 0, 0, 0, 0, 0, 0])\r\n const [rhythm, setRhythm] = useState([0, 0, 0, 0, 0, 0, 0, 0])\r\n const [composedPolyph, setComposedPolyph] = useState([0, 0, 0, 0, 0, 0, 0, 0])\r\n const [composedRhythm, setComposedRhythm] = useState([0, 0, 0, 0, 0, 0, 0, 0])\r\n const [defaultPR, setDefaultPR] = useState([])\r\n const [pLock, setPLock] = useState(true)\r\n const [rLock, setRLock] = useState(true)\r\n const [isLike, setIsLike] = useState(false)\r\n const [isDisLike, setIsDisLike] = useState(false)\r\n const [likeCount, setLikeCount] = useState(0)\r\n const [disLikeCount, setDisLikeCount] = useState(0)\r\n\r\n const pressLikeButt = async(flag)=>{\r\n let deltaLike = 0, deltaDisLike = 0;\r\n if(flag){//press like button\r\n deltaLike = isLike? -1 : 1;\r\n deltaDisLike = isDisLike? -1 : 0;\r\n setIsLike(!isLike)\r\n setIsDisLike(false)\r\n }\r\n else{\r\n deltaLike = isLike? -1 : 0;\r\n deltaDisLike = isDisLike? -1 : 1;\r\n setIsDisLike(!isDisLike)\r\n setIsLike(false)\r\n }\r\n //console.log(composedId, deltaLike, deltaDisLike)\r\n let result = await rateSongRequest(composedId, deltaLike, deltaDisLike)\r\n //console.log(result);\r\n setLikeCount(result.likes)\r\n setDisLikeCount(result.dislikes)\r\n }\r\n\r\n const defaultToggleFunc = () => {\r\n setPolyph(defaultPR[0])\r\n setRhythm(defaultPR[1])\r\n }\r\n\r\n const toggleFunc = (index, op, typ) => {\r\n return (() => {\r\n (typ === \"polyph\")?\r\n pLock?\r\n setPolyph(polyph.map(ele => (ele + op))) :\r\n setPolyph(polyph.map((ele, ind) => ((ind === index)? ele + op : ele)))\r\n :\r\n rLock?\r\n setRhythm(rhythm.map(ele => (ele + op))) :\r\n setRhythm(rhythm.map((ele, ind) => ((ind === index)? ele + op : ele)))\r\n })\r\n }\r\n\r\n const pLockFunc = () => {\r\n if(pLock){\r\n setPolyph(polyph.map(ele => Math.max(Math.min(ele, 7), 0)))\r\n }\r\n setPLock(!pLock) \r\n }\r\n\r\n const rLockFunc = () => {\r\n if(rLock){\r\n setRhythm(rhythm.map(ele => Math.max(Math.min(ele, 7), 0)))\r\n }\r\n setRLock(!rLock)\r\n }\r\n\r\n /***** Webserver requests *****/\r\n const [hasRequested, setHasRequested] = useState(false)\r\n const [refId, setRefId] = useState(-1)\r\n const [requestId, setRequestId] = useState(-1)\r\n const [composedId, setComposedId] = useState('');\r\n const [tempo, setTempo] = useState(119)\r\n const [isComposing, setIsComposing] = useState(false)\r\n const [hasComposed, setHasComposed] = useState(false)\r\n\r\n useEffect( async () => {\r\n if(!hasRequested){\r\n ac = new window.AudioContext();\r\n pianoPlayer = await Soundfont.instrument(ac, 'acoustic_grand_piano', { soundfont: 'MusyngKite' });\r\n //console.log('before calling getinit', requestId)\r\n let initPiece = await getInitPiece(requestId);\r\n setTempo(initPiece.tempo);\r\n setRefId(initPiece.ref_id);\r\n setRequestId(initPiece.ref_id);\r\n setInitNotes(initPiece.notes);\r\n setPolyph(initPiece.attr_cls.polyph);\r\n setRhythm(initPiece.attr_cls.rhythm);\r\n setDefaultPR([initPiece.attr_cls.polyph, initPiece.attr_cls.rhythm])\r\n setHasRequested(true);\r\n }\r\n }, [hasRequested])\r\n\r\n const composeFunc = async () => {\r\n setIsComposing(true);\r\n let composedPiece = await composeRequest(\r\n refId, tempo, {\r\n polyph: polyph.map(e=>Math.max(Math.min(e, 7), 0)),\r\n rhythm: rhythm.map(e=>Math.max(Math.min(e, 7), 0))\r\n }\r\n );\r\n setComposedNotes(composedPiece.notes);\r\n setComposedRhythm(composedPiece.rhythm);\r\n setComposedPolyph(composedPiece.polyph);\r\n setComposedId(composedPiece.composed_id);\r\n setIsComposing(false);\r\n setHasComposed(true);\r\n setIsLike(false)\r\n setIsDisLike(false)\r\n }\r\n\r\n /***** Canvas render *****/\r\n const [ canvasRef, canvasWidth, canvasHeight, gridSize, nGrids, nPitch, n_bars, n_grids_per_bar, window_width, window_height] = useCanvas();\r\n const [ gridCanvasRef ] = useGridCanvas(recommendationPage);\r\n const [ progressCanvasRef, progressDraw, progressClear] = useProgressCanvas();\r\n\r\n const midi2Show = e => {\r\n return {\r\n start: Math.floor(e.start_tick/120),\r\n key: e.key - 20, // [myRef]\r\n gain: e.velocity/128,\r\n duration: Math.floor(e.duration/120)\r\n }\r\n }\r\n\r\n useEffect( async () => {\r\n if(originPage){\r\n const canvas = canvasRef.current;\r\n const ctx = canvas.getContext('2d');\r\n let notes = initNotes.map(midi2Show);\r\n myDraw(canvasHeight, nGrids, nPitch, gridSize, notes, ctx);\r\n }\r\n else if(!recommendationPage){\r\n const canvas = canvasRef.current;\r\n const ctx = canvas.getContext('2d');\r\n let notes = composedNotes.map(midi2Show);\r\n myDraw(canvasHeight, nGrids, nPitch, gridSize, notes, ctx);\r\n }\r\n }, [initNotes, canvasHeight, canvasWidth, originPage])\r\n\r\n const passedRhythm = (originPage)? rhythm : composedRhythm;\r\n const passedPolyph = (originPage)? polyph : composedPolyph;\r\n\r\n const initEverything = (flag)=>{\r\n if(flag){\r\n setRequestId(-1)\r\n }\r\n setInitNotes([])\r\n setRefId(-1)\r\n setPolyph(polyph.map(e=>0))\r\n setRhythm(rhythm.map(e=>0))\r\n setTempo(119)\r\n setHasComposed(false)\r\n setIsLike(false)\r\n setIsDisLike(false)\r\n setOriginPage(true)\r\n setHasRequested(false)\r\n setRecommendationPage(false)\r\n }\r\n\r\n\r\n useEffect( () => {\r\n if(requestId!==refId){\r\n let req = parseInt(requestId, 10)\r\n if(Number.isInteger(req) && req>=0 && req<=99){\r\n setRequestId(req)\r\n initEverything(false)\r\n }\r\n else{\r\n setRequestId(refId)\r\n }\r\n }\r\n }, [requestId])\r\n\r\n\r\n const buttonSize = Math.max(Math.min(Math.floor(canvasHeight*0.12), 50), 16)\r\n \r\n return (\r\n <div className=\"App\">\r\n <body className=\"App-header\">\r\n {recommendationPage?\r\n <RecPage\r\n id={recommandProps.composed_id}\r\n recommendations={recommandProps.recommended_songs}\r\n composedSong={{\r\n tempo:tempo, notes:composedNotes, composed_id:recommandProps.composed_id,\r\n dislikes:disLikeCount, likes:likeCount, downloads:0, ranking:-1\r\n }}\r\n n_results={recommandProps.n_results}\r\n goback={()=>initEverything(true)}\r\n likeStatus={isLike}\r\n />\r\n :\r\n <>\r\n <div style={{position: \"relative\", width:window_width, height:(canvasHeight+0.1*window_height)}}>\r\n {originPage?\r\n <div id=\"info-container\" style={{width:0.8 * (window_width - canvasWidth), height:canvasHeight}}>\r\n <div className='id-container'>\r\n <Text strong style={{fontSize:buttonSize*0.6, color:'cornflowerblue'}}>Original</Text>\r\n <br/> \r\n <Text strong style={{fontSize:buttonSize*0.45, color:'LightBlue'}}\r\n editable={\r\n ((refId===-1)||isPlayingInit)? {editing:false, icon:<div/>} : \r\n {onChange:setRequestId, tooltip:'Enter 0~99 to pick a song', icon:<SearchOutlined/>}\r\n }\r\n > {(refId === -1)? 'Song' : `Song #${refId}`} </Text>\r\n </div>\r\n {hasRequested?\r\n <>\r\n <div id=\"play\">\r\n <button className=\"my-button1\" style={{fontSize: buttonSize ,color: isPlayingInit? 'lightpink':'aquamarine'}} \r\n onClick={playButton(\"i\")} disabled={!hasRequested}>\r\n {isPlayingInit? \r\n <PauseCircleFilled title=\"Pause\"/> : \r\n <PlayCircleFilled title=\"Play\"/>}\r\n </button>\r\n </div>\r\n <div id=\"back2default\">\r\n <button className=\"my-button1 color3\" style={{fontSize: buttonSize}} onClick={defaultToggleFunc} disabled={!hasRequested}>\r\n <RedoOutlined title=\"Set Tuners to Default\"/>\r\n </button>\r\n </div>\r\n <div id=\"request\">\r\n <button \r\n className={isComposing ? \"my-button1 color1 spinner\" : \"my-button1 color1\"}\r\n style={{fontSize: buttonSize}}\r\n onClick={composeFunc} \r\n disabled={isComposing||!hasRequested}>\r\n <MusicNoteRounded style={{fontSize: buttonSize}} titleAccess={isComposing? \"Composing...\" : hasComposed? \"Recompose\" : \"Compose\"}/>\r\n </button>\r\n </div>\r\n </>\r\n :\r\n <>\r\n <div style={{height:buttonSize}}/>\r\n <Spin tip=\"Loading...\"/>\r\n </>}\r\n \r\n { hasComposed && !isComposing &&\r\n <div id=\"nextpage\">\r\n <button className=\"my-button1 color2\"\r\n onClick={()=>setOriginPage(false)}\r\n style={{fontSize: buttonSize}}\r\n disabled={isPlayingInit}>\r\n <ArrowRightOutlined title=\"See My Song\"/>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n :\r\n <div id=\"info-container\" style={{width:0.8 * (window_width - canvasWidth), height:canvasHeight}}>\r\n <div className='id-container'>\r\n <Text strong style={{fontSize:buttonSize*0.6, color:'CornflowerBlue'}}>Yours</Text>\r\n <br/>\r\n <Text strong style={{fontSize:buttonSize*0.45, color:'LightBlue'}}>Song {(refId == -1)? '' : `#${refId}`}</Text>\r\n </div>\r\n <div id=\"play\">\r\n <button className=\"my-button1\" style={{fontSize: buttonSize, color: isPlayingComposed? 'lightpink':'aquamarine'}} onClick={playButton(\"c\")}>\r\n {(isPlayingComposed)? \r\n <PauseCircleFilled title=\"Pause\"/> : \r\n <PlayCircleFilled title=\"Play\"/>}\r\n </button>\r\n </div>\r\n <Space>\r\n <button \r\n className=\"my-button1 color3\" \r\n style={{fontSize: buttonSize, color: isLike? 'greenyellow' : 'grey'}}\r\n onClick={() => pressLikeButt(true)}>\r\n {isLike? <LikeFilled title='Cancel Like'/> : <LikeOutlined title='Like'/>}\r\n </button>\r\n <button \r\n className=\"my-button1 color3\"\r\n style={{fontSize: buttonSize, color: isDisLike? 'red' : 'grey'}}\r\n onClick={() => pressLikeButt(false)}>\r\n {isDisLike? <DislikeFilled title='Cancel Dislike'/> : <DislikeOutlined title='Dislike'/>}\r\n </button>\r\n </Space>\r\n <div id=\"recommand\">\r\n <button \r\n className=\"my-button1 color1\"\r\n style={{fontSize: buttonSize}}\r\n onClick={() => requestRecommendations()}\r\n disabled={!(isLike||isDisLike) || isPlayingComposed}>\r\n <StarFilled title={(isLike||isDisLike)?\"Recommendations\":\"Like or dislike to get recommendations :)\"}/>\r\n </button>\r\n </div>\r\n <div id=\"prevpage\">\r\n <button \r\n className=\"my-button1 color2\"\r\n style={{fontSize: buttonSize}}\r\n onClick={()=>setOriginPage(true)}\r\n disabled={isPlayingComposed}\r\n >\r\n <ArrowLeftOutlined title=\"See Original Song\"/>\r\n </button>\r\n </div>\r\n </div> \r\n }\r\n <Canvas\r\n forwardedRef={canvasRef}\r\n width={canvasWidth}\r\n height={canvasHeight}\r\n />\r\n <GridCanvas\r\n forwardedRef={gridCanvasRef}\r\n width={canvasWidth}\r\n height={canvasHeight}\r\n />\r\n <ProgressCanvas\r\n forwardedRef={progressCanvasRef}\r\n width={canvasWidth}\r\n height={canvasHeight}\r\n />\r\n </div>\r\n <Space direction='vertical' style={{width:window_width}}>\r\n <ButtonList \r\n toggleFunc={toggleFunc} lockFunc={rLockFunc} \r\n locked={rLock} attrData={passedRhythm}\r\n windowWidth={window_width} canvasWidth={canvasWidth}\r\n nowAPage={originPage} buttonSize={Math.floor(buttonSize*0.6)}\r\n attrType=\"rhythm\"/>\r\n <ButtonList \r\n toggleFunc={toggleFunc} lockFunc={pLockFunc}\r\n locked={pLock} attrData={passedPolyph}\r\n windowWidth={window_width} canvasWidth={canvasWidth}\r\n nowAPage={originPage} buttonSize={Math.floor(buttonSize*0.6)}\r\n attrType=\"polyph\"/>\r\n </Space>\r\n </>\r\n }\r\n </body>\r\n </div>\r\n );\r\n}\r\n\r\nexport default App;","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\buttonList.js",["72","73","74"],"import 'antd/dist/antd.css';\r\nimport { Button, Switch, Typography, Space, Divider } from 'antd';\r\nimport {\r\n UnlockOutlined,\r\n LockOutlined,\r\n RightCircleOutlined,\r\n LeftCircleOutlined,\r\n QuestionCircleOutlined\r\n} from '@ant-design/icons';\r\nconst { Text } = Typography;\r\n\r\nfunction ButtonList(props){\r\n return(\r\n <div style={{display:'flex'}}>\r\n <div style={{ width: 0.8*(props.windowWidth-props.canvasWidth) }}>\r\n <Text style={{ fontSize:props.buttonSize}}\r\n editable={{icon:<QuestionCircleOutlined/>, editing:false, \r\n tooltip:(props.attrType === 'rhythm') ? \r\n 'Controls the \"intensity\" of rhythm in each bar':\r\n 'Controls the \"fullness\" of harmony in each bar'}}/>\r\n {props.attrType === 'rhythm'?\r\n <Text keyboard strong \r\n style={{ fontSize:props.buttonSize, color:'mediumvioletred'}}\r\n >Rhythm</Text>\r\n :\r\n <Text keyboard strong \r\n style={{ fontSize:props.buttonSize, color:'MediumSeaGreen'}}\r\n >Polyph</Text>\r\n }\r\n <Switch\r\n size=\"small\"\r\n checkedChildren={<UnlockOutlined \r\n title={(props.attrType === 'rhythm') ? \r\n 'Unlock all Rhythm tuners':'Unlock all Polyph tuners'}/>}\r\n unCheckedChildren={<LockOutlined \r\n title={(props.attrType === 'rhythm') ? \r\n 'Lock Rhythm tuners 2~8 (change according to first tuner)':\r\n 'Lock Polyph tuners 2~8 (change according to first tuner)'}/>}\r\n defaultChecked={props.locked} \r\n onClick={props.lockFunc}\r\n disabled={(!props.nowAPage)}/>\r\n </div>\r\n <div className=\"button-list\" style={{ width: props.canvasWidth}}>\r\n {props.attrData.map((elem, index) => (\r\n <div key={`${props.attrType[0]}_${index}`}>\r\n <button \r\n className=\"my-button2\" style={{fontSize:props.buttonSize}}\r\n onClick={props.toggleFunc(index, -1, props.attrType)}\r\n disabled={(!props.nowAPage) || (elem <= 0) || (props.locked && index !== 0)}>\r\n <LeftCircleOutlined title=\"Down\"/>\r\n </button>\r\n <Text strong code style={{fontSize:props.buttonSize}}\r\n type={\r\n elem>5?\r\n \"danger\":elem<2?\r\n \"success\":\"warning\"\r\n }\r\n >{Math.max(Math.min(elem, 7), 0)}</Text>\r\n <button\r\n className=\"my-button2\" style={{fontSize:props.buttonSize}}\r\n onClick={props.toggleFunc(index, +1, props.attrType)}\r\n disabled={(!props.nowAPage) || (elem >= 7) || (props.locked && index !== 0)}>\r\n <RightCircleOutlined title=\"Up\"/>\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n </div> \r\n )\r\n}\r\n\r\nexport default ButtonList","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\recommendationPage.js",["75","76","77","78","79","80","81","82","83","84","85"],"import Soundfont from 'soundfont-player'\r\nimport './App.css'\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { \r\n downloadSongRequest,\r\n rateSongRequest\r\n} from './axios'\r\nimport { useCanvas, Canvas, myDraw } from './useCanvas.js';\r\n\r\nimport 'antd/dist/antd.css';\r\nimport {\r\n PlayCircleFilled,\r\n PauseCircleFilled,\r\n DownloadOutlined,\r\n LikeOutlined,\r\n LikeFilled,\r\n DislikeOutlined,\r\n DislikeFilled,\r\n HomeOutlined\r\n} from '@ant-design/icons';\r\nimport { Space, Divider, Typography, Spin } from 'antd';\r\nimport { Button } from '@material-ui/core';\r\nimport HomeRoundedIcon from '@material-ui/icons/HomeRounded';\r\nimport { ActionButton } from './customButtonStyle'\r\n\r\nconst { Title, Text } = Typography;\r\n\r\nlet ac, pianoPlayer, timeOutButt;\r\nfunction RecPage(props) {\r\n /***** Audio playing *****/\r\n const [isPlaying, setIsPlaying] = useState(new Array(props.n_results+1).fill(false))\r\n const [isAnyonePlaying, setIsAnyonePlaying] = useState(false)\r\n \r\n const midi2Play = (tempo)=>{\r\n const tick2Sec = (tic, tpb = 480) => {\r\n return parseFloat(60*tic/tempo/tpb);\r\n }\r\n \r\n return (e => {\r\n return {\r\n time: tick2Sec(e.start_tick),\r\n note: e.key,\r\n gain: 5*e.velocity/128,\r\n duration: tick2Sec(e.duration)\r\n }\r\n })\r\n }\r\n\r\n const myPlayer = (player, notes, tempo, index) => {\r\n return new Promise((resolve) => {\r\n const noteSched = notes.map(midi2Play(tempo))\r\n const timeoutSec = 1000 * (noteSched[ noteSched.length - 1 ].time + noteSched[ noteSched.length - 1 ].duration);\r\n\r\n player.schedule(ac.currentTime, noteSched)\r\n \r\n timeOutButt = setTimeout(() => {\r\n setIsPlaying(isPlaying.map((ele, ind)=>(ind === index? false : ele)))\r\n setIsAnyonePlaying(false)\r\n resolve()\r\n }, timeoutSec)\r\n })\r\n }\r\n\r\n const play = async(index)=>{\r\n const notes = (index === 0)? props.composedSong.notes : props.recommendations[index-1].notes\r\n const setFunc = ()=>{setIsPlaying(isPlaying.map((ele, ind)=>(ind === index? !ele : ele)))}\r\n\r\n if(isPlaying[index]){\r\n pianoPlayer.stop()\r\n setFunc()\r\n setIsAnyonePlaying(false)\r\n clearTimeout(timeOutButt)\r\n }\r\n else{\r\n setFunc()\r\n setIsAnyonePlaying(true)\r\n await myPlayer(pianoPlayer, notes, index===0? props.composedSong.tempo : props.recommendations[index-1].tempo, index)\r\n }\r\n }\r\n\r\n useEffect( async () => {\r\n ac = new window.AudioContext();\r\n pianoPlayer = await Soundfont.instrument(ac, 'acoustic_grand_piano', { soundfont: 'MusyngKite' });\r\n }, [])\r\n\r\n /***** Webserver request *****/\r\n const [isDownloading, setIsDownloading] = useState(new Array(props.n_results+1).fill(false))\r\n const [isLike, setIsLike] = useState(new Array(props.n_results).fill(false))\r\n const [isDisLike, setIsDisLike] = useState(new Array(props.n_results).fill(false))\r\n const [likeCount, setLikeCount] = useState(props.recommendations.map(e=>(e.likes)))\r\n const [disLikeCount, setDisLikeCount] = useState(props.recommendations.map(e=>(e.dislikes)))\r\n const [downloadCount, setDownloadCount] = useState(props.recommendations.map(e=>(e.downloads)))\r\n\r\n const downloadFunc = async (index) => {\r\n setIsDownloading(isDownloading.map((ele, ind)=>(\r\n (ind === index)? true: ele\r\n )))\r\n const id = index===0? props.id : props.recommendations[index-1].composed_id;\r\n const songData = await downloadSongRequest(id, index)\r\n setIsDownloading(isDownloading.map((ele, ind)=>(\r\n (ind === index)? false: ele\r\n )))\r\n if(index!==0){\r\n setDownloadCount(downloadCount.map((ele, ind)=>(\r\n (ind === index-1)? ele+1: ele\r\n )))\r\n }\r\n }\r\n\r\n const pressLikeButt = async(ind, flag)=>{\r\n let deltaLike = 0, deltaDisLike = 0;\r\n if(flag){//press like button\r\n deltaLike = isLike[ind]? -1 : 1;\r\n deltaDisLike = isDisLike[ind]? -1 : 0;\r\n setIsLike(isLike.map((e, i)=>(i===ind? !e:e)))\r\n setIsDisLike(isDisLike.map((e, i)=>(i===ind? false:e)))\r\n }\r\n else{\r\n deltaLike = isLike[ind]? -1 : 0;\r\n deltaDisLike = isDisLike[ind]? -1 : 1;\r\n setIsDisLike(isDisLike.map((e, i)=>(i===ind? !e:e)))\r\n setIsLike(isLike.map((e, i)=>(i===ind? false:e)))\r\n }\r\n\r\n let result = await rateSongRequest(props.recommendations[ind].composed_id, deltaLike, deltaDisLike)\r\n //console.log(result)\r\n setLikeCount(likeCount.map((e, i)=>(i===ind? result.likes:e)))\r\n setDisLikeCount(disLikeCount.map((e, i)=>(i===ind? result.dislikes:e)))\r\n }\r\n\r\n /***** Canvas render *****/\r\n const [ myImg, setMyImg ] = useState([])\r\n const [ canvasRef, canvasWidth, canvasHeight, gridSize, nGrids, nPitch ] = useCanvas(true);\r\n\r\n const midi2Show = e => {\r\n return {\r\n start: Math.floor(e.start_tick/120),\r\n key: e.key - 20, // [myRef]\r\n gain: e.velocity/128,\r\n duration: Math.floor(e.duration/120)\r\n }\r\n }\r\n\r\n useEffect( async () => {\r\n if(myImg.length === 0){\r\n let newImageArray = [];\r\n const canvas = canvasRef.current;\r\n const ctx = canvas.getContext('2d');\r\n \r\n for(let i = 0; i < props.n_results+1; i++){\r\n let notes = (i===0)? props.composedSong.notes.map(midi2Show) : props.recommendations[i-1].notes.map(midi2Show);\r\n myDraw(canvasHeight, nGrids, nPitch, gridSize, notes, ctx, true);\r\n let img = canvas.toDataURL('image/png')\r\n newImageArray[i] = img;\r\n }\r\n\r\n setMyImg(newImageArray)\r\n }\r\n })\r\n\r\n return (\r\n <Space direction='vertical' size={'large'}>\r\n <Canvas\r\n forwardedRef={canvasRef}\r\n width={canvasWidth}\r\n height={canvasHeight}\r\n unDisplay\r\n />\r\n <div>\r\n <div className='name-tag'>\r\n Your Composition\r\n </div>\r\n <Space className='unit-container'\r\n direction='horizontal' split={<Divider type='vertical'/>}>\r\n <div id='play'>\r\n <button className='my-button1' onClick={()=>play(0)}\r\n style={{color: isAnyonePlaying&&!isPlaying[0]? 'grey' : isPlaying[0]? 'lightpink':'aquamarine'}}\r\n disabled={isAnyonePlaying&&!isPlaying[0]}>\r\n {isPlaying[0]?\r\n <PauseCircleFilled title=\"Pause\"/> : \r\n <PlayCircleFilled title=\"Play\"/>}\r\n </button>\r\n </div>\r\n <div className='image-container' id='song-image'>\r\n <img src={`${myImg[0]}`} style={{height:160, width:canvasWidth}}/>\r\n </div>\r\n <div>\r\n <div style={{height:'36px'}}/>\r\n <div id='like-status' className=\"my-button1\" \r\n style={{ width: '80px', color: props.likeStatus?'greenyellow':'red'}}>\r\n {props.likeStatus? <LikeFilled/> : <DislikeFilled/>}\r\n </div>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'12px', color:'azure'}}>\r\n {props.likeStatus? <>You<br/>Liked It</> : <>You<br/>Disliked It</>}\r\n </Title>\r\n </div>\r\n </div>\r\n <div id=\"download\">\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className={(isDownloading[0]) ? \"my-button1 button-move color1\" : \"my-button1 color1\"} \r\n onClick={() => downloadFunc(0)}>\r\n <DownloadOutlined/>\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'12px', color:'azure'}}>Get<br/>Audio</Title>\r\n </div>\r\n </div>\r\n </Space>\r\n </div>\r\n \r\n <Space direction='vertical' className='recom-list'>\r\n {props.recommendations.map((ele, ind)=>(\r\n ind===0?\r\n <div>\r\n <div className='name-tag' style={{width:'36%'}}>\r\n Recommended to You\r\n </div>\r\n <Space className='unit-container' direction='horizontal' split={<Divider type='vertical'/>}>\r\n <div id='left'>\r\n <div style={{height:'36px'}}>\r\n <Text strong style={{color:'aliceblue'}} >#{ind+1}</Text>\r\n </div>\r\n <div id='play'>\r\n <button className='my-button1' onClick={()=>play(ind+1)}\r\n style={{color: isAnyonePlaying&&!isPlaying[ind+1]? 'grey' : isPlaying[ind+1]? 'lightpink':'aquamarine'}}\r\n disabled={isAnyonePlaying&&!isPlaying[ind+1]}>\r\n {isPlaying[ind+1]?\r\n <PauseCircleFilled title=\"Pause\"/> : \r\n <PlayCircleFilled title=\"Play\"/>}\r\n </button>\r\n </div>\r\n <div style={{height:'36px'}}/>\r\n </div>\r\n <div className='image-container' id='song-image'>\r\n <img src={`${myImg[ind+1]}`} style={{height:160, width:canvasWidth}}/>\r\n </div>\r\n <Space style={{ width: '80px'}}>\r\n <div>\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className=\"my-button1 color3\" \r\n style={{color: isLike[ind]? 'greenyellow':'grey'}}\r\n onClick={() => pressLikeButt(ind, true)}>\r\n {isLike[ind]? <LikeFilled title='Cancel Like'/> : <LikeOutlined title='Like'/>}\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'20px', color:'azure'}}>{likeCount[ind]}</Title>\r\n </div>\r\n </div>\r\n <div>\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className=\"my-button1 color3\"\r\n style={{color: isDisLike[ind]? 'red' : 'grey'}}\r\n onClick={() => pressLikeButt(ind, false)}>\r\n {isDisLike[ind]? <DislikeFilled title='Cancel Dislike'/> : <DislikeOutlined title='Dislike'/>}\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'20px', color:'azure'}}>{disLikeCount[ind]}</Title>\r\n </div>\r\n </div>\r\n </Space>\r\n <Space>\r\n <div id=\"download\">\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className={(isDownloading[ind+1]) ? \"my-button1 button-move color1\" : \"my-button1 color1\"} \r\n onClick={() => downloadFunc(ind+1)}\r\n disabled={!(isLike[ind]||isDisLike[ind])}>\r\n <DownloadOutlined title={!(isLike[ind]||isDisLike[ind])?'Rate to download':\"Download this song\"} />\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'20px', color:'azure'}}>{downloadCount[ind]}</Title>\r\n </div>\r\n </div>\r\n </Space>\r\n </Space>\r\n </div>\r\n :\r\n <Space className='unit-container1' direction='horizontal' split={<Divider type='vertical'/>}>\r\n <div id='left'>\r\n <div style={{height:'36px'}}>\r\n <Text strong style={{color:'aliceblue'}} >#{ind+1}</Text>\r\n </div>\r\n <div id='play'>\r\n <button className='my-button1' onClick={()=>play(ind+1)}\r\n style={{color: isAnyonePlaying&&!isPlaying[ind+1]? 'grey' : isPlaying[ind+1]? 'lightpink':'aquamarine'}}\r\n disabled={isAnyonePlaying&&!isPlaying[ind+1]}>\r\n {isPlaying[ind+1]?\r\n <PauseCircleFilled title=\"Pause\"/> : \r\n <PlayCircleFilled title=\"Play\"/>}\r\n </button>\r\n </div>\r\n <div style={{height:'36px'}}/>\r\n </div>\r\n <div className='image-container' id='song-image'>\r\n <img src={`${myImg[ind+1]}`} style={{height:160, width:canvasWidth}}/>\r\n </div>\r\n <Space style={{ width: '80px'}}>\r\n <div>\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className=\"my-button1 color3\" \r\n style={{color: isLike[ind]? 'greenyellow':'grey'}}\r\n onClick={() => pressLikeButt(ind, true)}>\r\n {isLike[ind]? <LikeFilled title='Cancel Like'/> : <LikeOutlined title='Like'/>}\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'20px', color:'azure'}}>{likeCount[ind]}</Title>\r\n </div>\r\n </div>\r\n <div>\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className=\"my-button1 color3\"\r\n style={{color: isDisLike[ind]? 'red' : 'grey'}}\r\n onClick={() => pressLikeButt(ind, false)}>\r\n {isDisLike[ind]? <DislikeFilled title='Cancel Dislike'/> : <DislikeOutlined title='Dislike'/>}\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'20px', color:'azure'}}>{disLikeCount[ind]}</Title>\r\n </div>\r\n </div>\r\n </Space>\r\n <Space>\r\n <div id=\"download\">\r\n <div style={{height:'36px'}}/>\r\n <button \r\n className={(isDownloading[ind+1]) ? \"my-button1 button-move color1\" : \"my-button1 color1\"} \r\n onClick={() => downloadFunc(ind+1)}\r\n disabled={!(isLike[ind]||isDisLike[ind])}>\r\n <DownloadOutlined title={!(isLike[ind]||isDisLike[ind])?'Rate to download':\"Download this song\"} />\r\n </button>\r\n <div style={{height:'36px'}}>\r\n <Title strong style={{fontSize:'20px', color:'azure'}}>{downloadCount[ind]}</Title>\r\n </div>\r\n </div>\r\n </Space>\r\n </Space>\r\n ))}\r\n </Space>\r\n <div className='home-button-container'>\r\n {/* <button className='my-button1' onClick={props.goback}>\r\n <HomeOutlined />\r\n </button>\r\n Home Page */}\r\n <ActionButton\r\n variant=\"contained\"\r\n color=\"default\"\r\n startIcon={<HomeRoundedIcon style={{fontSize: '30px'}}/>}\r\n size=\"large\"\r\n onClick={()=>{\r\n pianoPlayer.stop()\r\n setIsPlaying(isPlaying.map(e=>false))\r\n setIsAnyonePlaying(false)\r\n clearTimeout(timeOutButt)\r\n props.goback()\r\n }}\r\n >\r\n Back to Compose\r\n </ActionButton>\r\n </div>\r\n \r\n </Space>\r\n );\r\n}\r\n\r\nexport default RecPage;","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\useGridCanvas.js",["86","87","88","89","90"],"D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\useCanvas.js",["91","92"],"import React, { useState, useEffect, useRef, useLayoutEffect } from 'react';\r\n\r\n/* ========================================================================== */\r\nconst n_grids_per_bar = 16;\r\nconst n_bars = 8;\r\nconst n_grids = n_grids_per_bar * n_bars; // number of grids in horizontal direction\r\nconst n_pitch = 88; // number of grids in vertical direction\r\n/* ========================================================================== */\r\n\r\nconst colors = [\r\n 'aqua', 'cornflowerblue', 'lightblue', 'lightcyan',\r\n 'darksalmon', 'coral', 'lightsalmon', 'orange',\r\n 'orangered', 'tomato', 'sandybrown', 'peru'\r\n]\r\nconst colors1 = [\r\n 'mediumorchid', 'paleturqoise', 'salmon', 'mediumseagreen',\r\n 'navajowhite', 'hotpink', 'gold', 'turqoise',\r\n 'violet', 'palegreen', 'tomato', 'skyblue'\r\n]\r\n\r\n/* Change window size when resizing window */\r\nexport function useWindowSize() {\r\n const [size, setSize] = useState([0, 0]);\r\n useLayoutEffect(() => {\r\n function updateSize() {\r\n setSize([window.innerWidth, window.innerHeight]);\r\n }\r\n window.addEventListener('resize', updateSize);\r\n updateSize();\r\n return () => window.removeEventListener('resize', updateSize);\r\n }, []);\r\n return size;\r\n}\r\n\r\nexport function myDraw(canvasHeight, n_grids, nPitch, gridSize, notes, ctx, fullcolor) {\r\n const halfGridSize = Math.floor(gridSize/2);\r\n ctx.restore();\r\n ctx.beginPath();\r\n ctx.clearRect(0, 0, gridSize * n_grids, canvasHeight)\r\n\r\n for(let note of notes){\r\n if(note.key < 0 || note.key >= nPitch){\r\n continue;\r\n }\r\n ctx.restore();\r\n ctx.fillStyle = colors[note.key%12];\r\n ctx.globalAlpha = fullcolor? 0.8 : note.gain;\r\n ctx.fillRect(note.start * gridSize, canvasHeight - note.key * halfGridSize, (note.duration-0.5) * gridSize, halfGridSize);\r\n }\r\n\r\n ctx.closePath();\r\n}\r\n\r\nexport function useCanvas(flag = false){\r\n const canvasRef = useRef(null);\r\n let [window_width, window_height] = useWindowSize();\r\n if(flag){\r\n window_width = 800;\r\n window_height = 450;\r\n }\r\n const canvasWidth = 0.8*window_width - 0.8*window_width % n_grids;\r\n const canvasHeight = Math.floor(canvasWidth / n_grids) * n_pitch/2;\r\n const gridSize = Math.floor(canvasWidth / n_grids);\r\n //console.log(\"width, height, gridSize of drawCanvas:\", canvasWidth, canvasHeight, gridSize);\r\n return [canvasRef, canvasWidth, canvasHeight, gridSize, n_grids, n_pitch, n_bars, n_grids_per_bar, window_width, window_height];\r\n}\r\n\r\nexport function Canvas(props) {\r\n return (\r\n <canvas\r\n className=\"App-canvas my-canvas\"\r\n ref={props.forwardedRef}\r\n width={props.width}\r\n height={props.height}\r\n style={('unDisplay' in props)?\r\n {display: 'none'}\r\n :\r\n {}\r\n }\r\n />\r\n )\r\n}\r\n","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\useProgressCanvas.js",["93","94","95","96","97"],"import React, { useState, useEffect, useRef } from 'react';\r\nimport { useCanvas } from './useCanvas.js';\r\n\r\nexport function useProgressCanvas(){\r\n const canvasRef = useRef(null);\r\n const [ noneRef, canvasWidth, canvasHeight, gridSize, n_grids, nPitch] = useCanvas();\r\n \r\n function progressClear(){\r\n const canvas = canvasRef.current;\r\n const ctx = canvas.getContext('2d');\r\n ctx.restore();\r\n ctx.beginPath();\r\n ctx.clearRect(0, 0, canvasWidth, canvasHeight);\r\n ctx.closePath();\r\n }\r\n\r\n async function progressDraw(notes, timeOutButt, timeOutButt2) {\r\n const canvas = canvasRef.current;\r\n const ctx = canvas.getContext('2d');\r\n const halfGridSize = Math.floor(gridSize/2);\r\n const colors = [\r\n 'aqua', 'cornflowerblue', 'lightblue', 'lightcyan',\r\n 'darksalmon', 'coral', 'lightsalmon', 'orange',\r\n 'orangered', 'tomato', 'sandybrown', 'peru'\r\n ]\r\n ctx.restore();\r\n ctx.beginPath();\r\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\r\n \r\n const drawOneNote = (elem) => {\r\n ctx.restore();\r\n ctx.fillStyle = colors[elem.key%12];\r\n ctx.globalAlpha = 1;\r\n ctx.fillRect(elem.start * gridSize, canvasHeight - elem.key * halfGridSize, (elem.end-0.5) * gridSize, halfGridSize);\r\n }\r\n\r\n const clearOneNote = (elem) =>{\r\n ctx.restore();\r\n ctx.clearRect(elem.start * gridSize, canvasHeight - elem.key * halfGridSize, (elem.end-0.5) * gridSize, halfGridSize);\r\n }\r\n\r\n notes.forEach((elem, index)=>{\r\n timeOutButt[index] = setTimeout(()=>{\r\n drawOneNote(elem, 1);\r\n timeOutButt2[index] = setTimeout(()=>{\r\n //console.log('index = ', index, 'finish time = ', elem.time+elem.duration)\r\n clearOneNote(elem)\r\n },elem.duration*1000)\r\n }, elem.time*1000);\r\n })\r\n \r\n // ctx.clearRect(0, 0, gridSize * n_grids, halfGridSize * nPitch)\r\n ctx.closePath();\r\n }\r\n\r\n return [ canvasRef, progressDraw, progressClear ];\r\n}\r\n\r\nexport function ProgressCanvas(props) {\r\n return (\r\n <canvas\r\n className=\"grid-canvas my-canvas\"\r\n ref={props.forwardedRef}\r\n width={props.width}\r\n height={props.height}\r\n />\r\n )\r\n}","D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\axios.js",[],"D:\\NTU_Struggle\\109學年度\\網路服務程式設計\\finalProject\\webProgrammingFinalProject\\src\\customButtonStyle.js",[],{"ruleId":"98","replacedBy":"99"},{"ruleId":"100","replacedBy":"101"},{"ruleId":"102","severity":1,"message":"103","line":3,"column":21,"nodeType":"104","messageId":"105","endLine":3,"endColumn":27},{"ruleId":"102","severity":1,"message":"106","line":9,"column":3,"nodeType":"104","messageId":"105","endLine":9,"endColumn":22},{"ruleId":"102","severity":1,"message":"107","line":15,"column":45,"nodeType":"104","messageId":"105","endLine":15,"endColumn":57},{"ruleId":"102","severity":1,"message":"108","line":15,"column":59,"nodeType":"104","messageId":"105","endLine":15,"endColumn":71},{"ruleId":"102","severity":1,"message":"109","line":21,"column":3,"nodeType":"104","messageId":"105","endLine":21,"endColumn":16},{"ruleId":"102","severity":1,"message":"110","line":25,"column":3,"nodeType":"104","messageId":"105","endLine":25,"endColumn":18},{"ruleId":"102","severity":1,"message":"111","line":26,"column":3,"nodeType":"104","messageId":"105","endLine":26,"endColumn":19},{"ruleId":"102","severity":1,"message":"112","line":31,"column":3,"nodeType":"104","messageId":"105","endLine":31,"endColumn":18},{"ruleId":"102","severity":1,"message":"113","line":35,"column":17,"nodeType":"104","messageId":"105","endLine":35,"endColumn":24},{"ruleId":"102","severity":1,"message":"114","line":39,"column":3,"nodeType":"104","messageId":"105","endLine":39,"endColumn":19},{"ruleId":"102","severity":1,"message":"115","line":40,"column":3,"nodeType":"104","messageId":"105","endLine":40,"endColumn":14},{"ruleId":"102","severity":1,"message":"116","line":41,"column":3,"nodeType":"104","messageId":"105","endLine":41,"endColumn":19},{"ruleId":"102","severity":1,"message":"117","line":45,"column":9,"nodeType":"104","messageId":"105","endLine":45,"endColumn":14},{"ruleId":"118","severity":1,"message":"119","line":136,"column":14,"nodeType":"120","endLine":139,"endColumn":4},{"ruleId":"118","severity":1,"message":"119","line":216,"column":14,"nodeType":"120","endLine":231,"endColumn":4},{"ruleId":"118","severity":1,"message":"121","line":231,"column":6,"nodeType":"122","endLine":231,"endColumn":20,"suggestions":"123"},{"ruleId":"102","severity":1,"message":"124","line":252,"column":75,"nodeType":"104","messageId":"105","endLine":252,"endColumn":81},{"ruleId":"102","severity":1,"message":"125","line":252,"column":83,"nodeType":"104","messageId":"105","endLine":252,"endColumn":98},{"ruleId":"118","severity":1,"message":"119","line":265,"column":14,"nodeType":"120","endLine":278,"endColumn":4},{"ruleId":"118","severity":1,"message":"126","line":278,"column":6,"nodeType":"122","endLine":278,"endColumn":56,"suggestions":"127"},{"ruleId":"118","severity":1,"message":"128","line":312,"column":6,"nodeType":"122","endLine":312,"endColumn":17,"suggestions":"129"},{"ruleId":"130","severity":1,"message":"131","line":394,"column":107,"nodeType":"132","messageId":"133","endLine":394,"endColumn":109},{"ruleId":"102","severity":1,"message":"134","line":2,"column":10,"nodeType":"104","messageId":"105","endLine":2,"endColumn":16},{"ruleId":"102","severity":1,"message":"135","line":2,"column":38,"nodeType":"104","messageId":"105","endLine":2,"endColumn":43},{"ruleId":"102","severity":1,"message":"113","line":2,"column":45,"nodeType":"104","messageId":"105","endLine":2,"endColumn":52},{"ruleId":"102","severity":1,"message":"103","line":3,"column":21,"nodeType":"104","messageId":"105","endLine":3,"endColumn":27},{"ruleId":"102","severity":1,"message":"136","line":19,"column":3,"nodeType":"104","messageId":"105","endLine":19,"endColumn":15},{"ruleId":"102","severity":1,"message":"137","line":21,"column":38,"nodeType":"104","messageId":"105","endLine":21,"endColumn":42},{"ruleId":"102","severity":1,"message":"134","line":22,"column":10,"nodeType":"104","messageId":"105","endLine":22,"endColumn":16},{"ruleId":"118","severity":1,"message":"119","line":81,"column":14,"nodeType":"120","endLine":84,"endColumn":4},{"ruleId":"102","severity":1,"message":"138","line":99,"column":11,"nodeType":"104","messageId":"105","endLine":99,"endColumn":19},{"ruleId":"118","severity":1,"message":"139","line":144,"column":3,"nodeType":"104","endLine":144,"endColumn":12,"suggestions":"140"},{"ruleId":"118","severity":1,"message":"119","line":144,"column":14,"nodeType":"120","endLine":159,"endColumn":4},{"ruleId":"141","severity":1,"message":"142","line":185,"column":13,"nodeType":"143","endLine":185,"endColumn":79},{"ruleId":"141","severity":1,"message":"142","line":237,"column":17,"nodeType":"143","endLine":237,"endColumn":87},{"ruleId":"141","severity":1,"message":"142","line":299,"column":15,"nodeType":"143","endLine":299,"endColumn":85},{"ruleId":"102","severity":1,"message":"144","line":58,"column":12,"nodeType":"104","messageId":"105","endLine":58,"endColumn":19},{"ruleId":"102","severity":1,"message":"145","line":58,"column":58,"nodeType":"104","messageId":"105","endLine":58,"endColumn":65},{"ruleId":"102","severity":1,"message":"146","line":58,"column":67,"nodeType":"104","messageId":"105","endLine":58,"endColumn":74},{"ruleId":"102","severity":1,"message":"124","line":58,"column":76,"nodeType":"104","messageId":"105","endLine":58,"endColumn":82},{"ruleId":"118","severity":1,"message":"147","line":68,"column":8,"nodeType":"122","endLine":68,"endColumn":54,"suggestions":"148"},{"ruleId":"102","severity":1,"message":"149","line":1,"column":27,"nodeType":"104","messageId":"105","endLine":1,"endColumn":36},{"ruleId":"102","severity":1,"message":"150","line":15,"column":7,"nodeType":"104","messageId":"105","endLine":15,"endColumn":14},{"ruleId":"102","severity":1,"message":"151","line":1,"column":17,"nodeType":"104","messageId":"105","endLine":1,"endColumn":25},{"ruleId":"102","severity":1,"message":"149","line":1,"column":27,"nodeType":"104","messageId":"105","endLine":1,"endColumn":36},{"ruleId":"102","severity":1,"message":"152","line":6,"column":11,"nodeType":"104","messageId":"105","endLine":6,"endColumn":18},{"ruleId":"102","severity":1,"message":"145","line":6,"column":57,"nodeType":"104","messageId":"105","endLine":6,"endColumn":64},{"ruleId":"102","severity":1,"message":"153","line":6,"column":66,"nodeType":"104","messageId":"105","endLine":6,"endColumn":72},"no-native-reassign",["154"],"no-negated-in-lhs",["155"],"no-unused-vars","'useRef' is defined but never used.","Identifier","unusedVar","'downloadSongRequest' is defined but never used.","'progressDraw' is defined but never used.","'stopProgress' is defined but never used.","'SlidersFilled' is defined but never used.","'LoadingOutlined' is defined but never used.","'DownloadOutlined' is defined but never used.","'CommentOutlined' is defined but never used.","'Divider' is defined but never used.","'PlayArrowRounded' is defined but never used.","'StopRounded' is defined but never used.","'ArrowBackRounded' is defined but never used.","'Title' is assigned a value but never used.","react-hooks/exhaustive-deps","Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n async function fetchData() {\n // You can await here\n const response = await MyAPI.getData(someId);\n // ...\n }\n fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching","ArrowFunctionExpression","React Hook useEffect has a missing dependency: 'requestId'. Either include it or remove the dependency array.","ArrayExpression",["156"],"'n_bars' is assigned a value but never used.","'n_grids_per_bar' is assigned a value but never used.","React Hook useEffect has missing dependencies: 'canvasRef', 'composedNotes', 'gridSize', 'nGrids', 'nPitch', and 'recommendationPage'. Either include them or remove the dependency array.",["157"],"React Hook useEffect has missing dependencies: 'initEverything' and 'refId'. Either include them or remove the dependency array. You can also replace multiple useState variables with useReducer if 'setRequestId' needs the current value of 'refId'.",["158"],"eqeqeq","Expected '===' and instead saw '=='.","BinaryExpression","unexpected","'Button' is defined but never used.","'Space' is defined but never used.","'HomeOutlined' is defined but never used.","'Spin' is defined but never used.","'songData' is assigned a value but never used.","React Hook useEffect contains a call to 'setMyImg'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass [myImg.length, canvasRef, props.n_results, props.composedSong.notes, props.recommendations, canvasHeight, nGrids, nPitch, gridSize] as a second argument to the useEffect Hook.",["159"],"jsx-a11y/alt-text","img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.","JSXOpeningElement","'nullref' is assigned a value but never used.","'n_grids' is assigned a value but never used.","'n_pitch' is assigned a value but never used.","React Hook useEffect has a missing dependency: 'n_grids_per_bar'. Either include it or remove the dependency array.",["160"],"'useEffect' is defined but never used.","'colors1' is assigned a value but never used.","'useState' is defined but never used.","'noneRef' is assigned a value but never used.","'nPitch' is assigned a value but never used.","no-global-assign","no-unsafe-negation",{"desc":"161","fix":"162"},{"desc":"163","fix":"164"},{"desc":"165","fix":"166"},{"desc":"167","fix":"168"},{"desc":"169","fix":"170"},"Update the dependencies array to be: [hasRequested, requestId]",{"range":"171","text":"172"},"Update the dependencies array to be: [initNotes, canvasHeight, canvasWidth, originPage, recommendationPage, canvasRef, nGrids, nPitch, gridSize, composedNotes]",{"range":"173","text":"174"},"Update the dependencies array to be: [initEverything, refId, requestId]",{"range":"175","text":"176"},"Add dependencies array: [myImg.length, canvasRef, props.n_results, props.composedSong.notes, props.recommendations, canvasHeight, nGrids, nPitch, gridSize]",{"range":"177","text":"178"},"Update the dependencies array to be: [canvasWidth, canvasHeight, gridSize, recPage, n_grids_per_bar]",{"range":"179","text":"180"},[7347,7361],"[hasRequested, requestId]",[8962,9012],"[initNotes, canvasHeight, canvasWidth, originPage, recommendationPage, canvasRef, nGrids, nPitch, gridSize, composedNotes]",[9798,9809],"[initEverything, refId, requestId]",[5472,5472],", [myImg.length, canvasRef, props.n_results, props.composedSong.notes, props.recommendations, canvasHeight, nGrids, nPitch, gridSize]",[2286,2332],"[canvasWidth, canvasHeight, gridSize, recPage, n_grids_per_bar]"]