├── public ├── favicon.ico ├── logo192.png ├── logo512.png ├── robots.txt ├── manifest.json └── index.html ├── src ├── App.css ├── components │ ├── CardDetails │ │ ├── LightsStatus.js │ │ ├── CardDetails.css │ │ ├── Credits.js │ │ ├── LightSettingsMenu.js │ │ └── CardDetails.js │ ├── DialogComponent │ │ ├── Grid │ │ │ ├── Grid.js │ │ │ └── GridItem.js │ │ └── DialogComponent.js │ ├── Player.js │ └── MainPage.js ├── index.js ├── custom-hooks │ └── useInterval.js ├── index.css ├── App.js └── Contexts │ └── MusicInfoContext.js ├── .gitignore ├── README.md └── package.json /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hvkb/insomnia-react-app/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hvkb/insomnia-react-app/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hvkb/insomnia-react-app/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | background-color: #0c0b0b; 4 | font-family: 'Poppins', sans-serif; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/components/CardDetails/LightsStatus.js: -------------------------------------------------------------------------------- 1 | const LightsStatus = { 2 | lightsOn: "lightsOn", 3 | lightsOff: "lightsOff", 4 | lightsGraduallyOff: "lightsGraduallyOff", 5 | }; 6 | 7 | export default LightsStatus 8 | 9 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ); 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/components/CardDetails/CardDetails.css: -------------------------------------------------------------------------------- 1 | .outerDiv { 2 | animation-name: reduce-brightness; 3 | animation-duration: 300s; 4 | background-repeat: no-repeat; 5 | animation-fill-mode: forwards; 6 | } 7 | 8 | @keyframes reduce-brightness { 9 | from { 10 | filter: brightness(100%); 11 | } 12 | to { 13 | filter: brightness(20%); 14 | } 15 | } 16 | 17 | .lightsOff { 18 | filter: brightness(20%); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/custom-hooks/useInterval.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export function useInterval(callback, delay) { 4 | const savedCallback = useRef(); 5 | 6 | useEffect(() => { 7 | savedCallback.current = callback; 8 | }, [callback]); 9 | 10 | useEffect(() => { 11 | function tick() { 12 | savedCallback.current(); 13 | } 14 | if (delay !== null) { 15 | let id = setInterval(tick, delay); 16 | return () => clearInterval(id); 17 | } 18 | }, [delay]); 19 | } 20 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "insomnia", 3 | "name": "insomnia app", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Gruppo&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;1,100;1,200;1,300;1,400&display=swap'); 2 | 3 | ::selection{ 4 | color: black; 5 | background: #D093C3; 6 | } 7 | 8 | ::-moz-selection 9 | { 10 | color: black; 11 | background: #D093C3; 12 | } 13 | 14 | ::-webkit-scrollbar { 15 | width: 0.5vmin; 16 | } 17 | 18 | 19 | ::-webkit-scrollbar-track { 20 | background: #0c0b0b; 21 | } 22 | 23 | ::-webkit-scrollbar-thumb { 24 | background: #555; 25 | } 26 | 27 | ::-webkit-scrollbar-thumb:hover { 28 | background: #888; 29 | } -------------------------------------------------------------------------------- /src/components/DialogComponent/Grid/Grid.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import Grid from "@mui/material/Grid"; 3 | import GridItem from "./GridItem"; 4 | import { MusicInfoContext } from "../../../Contexts/MusicInfoContext"; 5 | 6 | const GridOuter = ({ setIsOpen }) => { 7 | const music = useContext(MusicInfoContext); 8 | 9 | return ( 10 | 11 | {music.map((music) => ( 12 | 13 | 14 | 15 | ))} 16 | 17 | ); 18 | }; 19 | 20 | export default GridOuter; 21 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | insomnia 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # insomnia - a sleep inducer app 2 | An app that will help you relax and sleep better. 3 | #### Link: [https://hvkb.github.io/insomnia-react-app/](https://hvkb.github.io/insomnia-react-app/) 4 | 5 | ## How it works 6 | Once the user clicks on their choice of music/sounds, the lights will gradually start to dim and the volume will start to go down.
7 | In addition to this, the user can also set the volume and the brightness level of the screen. In the case of the user setting the volume, the volume will no longer gradually reduce but instead will remain constant. 8 | 9 | ## Screenshots 10 | ![Screenshot #1](https://user-images.githubusercontent.com/63035954/147726219-a1180881-acbf-4e2e-b561-9c8c39dd9183.png) 11 | ![Screenshot #2](https://user-images.githubusercontent.com/63035954/147726221-d1914ad7-3449-4b77-8c77-da8b57c35575.png) 12 | ![Screenshot #3](https://user-images.githubusercontent.com/63035954/147726224-52abe343-c615-44c1-8e90-8511b418011c.png) 13 | ![Screenshot #4](https://user-images.githubusercontent.com/63035954/147726231-4a98b0cd-7be4-4984-835b-57d4329390f3.png) 14 | 15 | 16 | 17 | ## Acknowledgements 18 | 1. [Mahil Jasani's blog](https://www.codementor.io/@mahil/10-web-app-ideas-you-can-build-as-side-projects-1bimcrdepx) - idea 19 | 2. [lofi.cafe](https://www.lofi.cafe/) - reference 20 | -------------------------------------------------------------------------------- /src/components/Player.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import ReactPlayer from "react-player"; 3 | 4 | export default function Player({ music, volume, setVolume }) { 5 | const playing = true; 6 | const muted = false; 7 | const controls = false; 8 | 9 | useEffect(() => { 10 | setVolume(1); 11 | }, [music.youtube]); 12 | 13 | const handleClick = (e) => { 14 | e.preventDefault(); 15 | setVolume(1); 16 | }; 17 | 18 | return ( 19 |
20 |
21 | 44 |
45 |
46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /src/components/DialogComponent/Grid/GridItem.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Card from "@mui/material/Card"; 3 | import CardActionArea from "@mui/material/CardActionArea"; 4 | import CardContent from "@mui/material/CardContent"; 5 | import CardMedia from "@mui/material/CardMedia"; 6 | import Typography from "@mui/material/Typography"; 7 | 8 | import { useNavigate } from "react-router-dom"; 9 | const GridItem = ({ music, setIsOpen }) => { 10 | const navigate = useNavigate(); 11 | 12 | const openCard = () => { 13 | setIsOpen(false); 14 | navigate(`/openCard/${music.id}`, { replace: true }); 15 | 16 | }; 17 | 18 | return ( 19 | 20 | 21 | 27 | 28 | 33 | {music.title} 34 | 35 | 36 | 37 | 38 | ); 39 | }; 40 | 41 | export default GridItem; 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://hvkb.github.io/insomnia-react-app", 3 | "name": "sleep-inducer", 4 | "version": "0.1.0", 5 | "private": true, 6 | "dependencies": { 7 | "@emotion/react": "^11.5.0", 8 | "@emotion/styled": "^11.3.0", 9 | "@mui/icons-material": "^5.1.0", 10 | "@mui/material": "^5.0.6", 11 | "@testing-library/jest-dom": "^5.14.1", 12 | "@testing-library/react": "^11.2.7", 13 | "@testing-library/user-event": "^12.8.3", 14 | "@u-wave/react-youtube": "^0.7.2", 15 | "axios": "^0.24.0", 16 | "react": "^17.0.2", 17 | "react-dom": "^17.0.2", 18 | "react-full-screen": "^1.1.0", 19 | "react-player": "^2.9.0", 20 | "react-router-dom": "^6.2.1", 21 | "react-scripts": "4.0.3", 22 | "react-youtube": "^7.13.1", 23 | "screenfull": "^5.2.0", 24 | "web-vitals": "^1.1.2" 25 | }, 26 | "scripts": { 27 | "predeploy": "npm run build", 28 | "deploy": "gh-pages -d build", 29 | "start": "react-scripts start", 30 | "build": "react-scripts build", 31 | "test": "react-scripts test", 32 | "eject": "react-scripts eject" 33 | }, 34 | "eslintConfig": { 35 | "extends": [ 36 | "react-app", 37 | "react-app/jest" 38 | ] 39 | }, 40 | "browserslist": { 41 | "production": [ 42 | ">0.2%", 43 | "not dead", 44 | "not op_mini all" 45 | ], 46 | "development": [ 47 | "last 1 chrome version", 48 | "last 1 firefox version", 49 | "last 1 safari version" 50 | ] 51 | }, 52 | "devDependencies": { 53 | "gh-pages": "^3.2.3" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/components/CardDetails/Credits.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Menu from "@mui/material/Menu"; 3 | import Box from "@mui/material/Box"; 4 | import Typography from "@mui/material/Typography"; 5 | 6 | export const Credits = ({ music, anchorElInfo, setAnchorElInfo }) => { 7 | const openMenuInfo = Boolean(anchorElInfo); 8 | const handleCloseInfo = () => { 9 | setAnchorElInfo(null); 10 | }; 11 | return ( 12 | 30 | 31 | 32 | Credits 33 | 34 | 35 | bgm:{" "} 36 | 37 | {music.title} 38 | 39 |
40 | bg image:{" "} 41 | 47 | source 48 | 49 |
50 |
51 |
52 | ); 53 | }; 54 | -------------------------------------------------------------------------------- /src/components/CardDetails/LightSettingsMenu.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Menu from "@mui/material/Menu"; 3 | import Typography from "@mui/material/Typography"; 4 | import LightsStatus from "./LightsStatus"; 5 | import MenuItem from "@mui/material/MenuItem"; 6 | 7 | const LightSettingsMenu = ({anchorEl, setAnchorEl, setLightsStatus}) => { 8 | const openMenu = Boolean(anchorEl); 9 | 10 | const handleSetLightsToLightsOn = () => { 11 | setLightsStatus(LightsStatus.lightsOn); 12 | handleClose(); 13 | }; 14 | 15 | const handleSetLightsToLightsOff = () => { 16 | setLightsStatus(LightsStatus.lightsOff); 17 | handleClose(); 18 | }; 19 | 20 | const handleSetToLightsGraduallyOff = () => { 21 | setLightsStatus(LightsStatus.lightsGraduallyOff); 22 | handleClose(); 23 | }; 24 | 25 | const handleClose = () => { 26 | setAnchorEl(null); 27 | }; 28 | return ( 29 | 47 | 48 | lights on 49 | 50 | 51 | lights off 52 | 53 | 54 | lights gradually off - default 55 | 56 | 57 | ) 58 | } 59 | 60 | export default LightSettingsMenu 61 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import MainPage from "./components/MainPage"; 3 | import { MusicInfoProvider } from "./Contexts/MusicInfoContext"; 4 | import { BrowserRouter, 5 | Routes, Route } from "react-router-dom"; 6 | import CardDetails from "./components/CardDetails/CardDetails.js"; 7 | import { createTheme, ThemeProvider } from "@mui/material/styles"; 8 | 9 | const theme = createTheme({ 10 | palette: { 11 | background: { 12 | default: "black", 13 | }, 14 | primary: { 15 | main: "#D093C3", 16 | }, 17 | secondary: { 18 | main: "#fff", 19 | }, 20 | }, 21 | typography: { 22 | fontFamily: "Poppins", 23 | fontWeightLight: 100, 24 | fontWeightRegular: 200, 25 | fontWeightMedium: 300, 26 | fontWeightBold: 400, 27 | }, 28 | props: { 29 | MuiIcon: { 30 | color: '#aa0011', 31 | } 32 | }, 33 | components: { 34 | MuiIcon:{ 35 | styleOverrides: { 36 | root: { 37 | primary: "#fff", 38 | } 39 | } 40 | }, 41 | MuiButton: { 42 | styleOverrides: { 43 | root: { 44 | border: "none", 45 | outline: "none", 46 | borderRadius: "100px", 47 | textTransform: "lowercase", 48 | "&:focus": { 49 | outline: "none", 50 | }, 51 | }, 52 | }, 53 | }, 54 | MuiDialogContent: { 55 | styleOverrides: { 56 | root: { 57 | backgroundColor: "#000", 58 | }, 59 | }, 60 | }, 61 | }, 62 | }); 63 | function App() { 64 | return ( 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | }/> 73 | 74 | } /> 75 | 76 | 77 | 78 | 79 | 80 | 81 | ); 82 | } 83 | 84 | export default App; 85 | -------------------------------------------------------------------------------- /src/components/DialogComponent/DialogComponent.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef } from "react"; 2 | import Dialog from "@mui/material/Dialog"; 3 | import DialogContent from "@mui/material/DialogContent"; 4 | import DialogContentText from "@mui/material/DialogContentText"; 5 | import GridOuter from "./Grid/Grid"; 6 | import { Typography, Button } from "@mui/material"; 7 | import { Box } from "@mui/system"; 8 | 9 | function DialogComponent({ isOpen, setIsOpen }) { 10 | const handleClose = () => { 11 | setIsOpen(false); 12 | }; 13 | 14 | const descriptionElementRef = useRef(null); 15 | useEffect(() => { 16 | if (isOpen) { 17 | const { current: descriptionElement } = descriptionElementRef; 18 | if (descriptionElement !== null) { 19 | descriptionElement.focus(); 20 | } 21 | } 22 | }, [isOpen]); 23 | 24 | return ( 25 | 33 | 37 | 47 | Select your sound 48 | 49 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ); 65 | } 66 | 67 | export default DialogComponent; 68 | -------------------------------------------------------------------------------- /src/components/MainPage.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import DialogComponent from "./DialogComponent/DialogComponent"; 3 | import Button from "@mui/material/Button"; 4 | import { AppBar, Toolbar, Typography } from "@mui/material"; 5 | import { Link } from "react-router-dom"; 6 | export default function MainPage() { 7 | const [isOpen, setIsOpen] = useState(false); 8 | const myStyle = { 9 | height: "100vh", 10 | justifyContent: "center", 11 | whiteSpace: "pre-line", 12 | display: "flex", 13 | alignItems: "center", 14 | flexDirection: "column", 15 | padding: "12vmin", 16 | }; 17 | 18 | const handleClick = () => { 19 | setIsOpen(true); 20 | }; 21 | return ( 22 |
23 | 27 | 28 | 32 | 33 | insomnia. 34 | 35 | 36 | 37 | 38 |
39 | 44 | insomnia. 45 | 46 | 51 | hi, welcome to insomnia! Built using React, insomnia will help you 52 | relax and sleep better. 53 |
54 | Click below to browse. 55 |
56 |
57 | 69 |
70 |
71 | 76 |
77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/Contexts/MusicInfoContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | export const MusicInfoContext = createContext(); 4 | 5 | export const MusicInfoProvider = (props) => { 6 | const music = [ 7 | { 8 | id: "1", 9 | image: "https://c.tenor.com/kuue1kTkjysAAAAC/rain-sailor.gif", 10 | imageCredit: "https://tenor.com/view/rain-sailor-moon-gif-20481725", 11 | title: "rain", 12 | youtube: 13 | "https://www.youtube.com/watch?v=q76bMs-NwRk", 14 | }, 15 | { 16 | id: "2", 17 | image: "https://media0.giphy.com/media/SWhsTrEYSrGd4CAhNC/giphy.gif?cid=ecf05e47p52d27fgwnp1fvyy4czk8c3qmldmekdm1mhs1j8k&rid=giphy.gif&ct=g", 18 | imageCredit: "https://giphy.com/gifs/animatr-anime-aesthetics-anime90s-waves-SWhsTrEYSrGd4CAhNC", 19 | title: "ocean", 20 | youtube: 21 | "https://www.youtube.com/watch?v=HCx_L2QwxX4", 22 | }, 23 | { 24 | id: "3", 25 | image: "https://c.tenor.com/2FIMeyZLsD8AAAAC/anime-1980s.gif", 26 | imageCredit: "https://tenor.com/view/anime-1980s-80s-city-night-gif-16335334", 27 | title: "traffic", 28 | youtube: 29 | "https://youtu.be/iA0Tgng9v9U", 30 | }, 31 | { 32 | id: "4", 33 | image: "https://c.tenor.com/L0-NTy43YZIAAAAC/anime-forest.gif", 34 | imageCredit: "https://tenor.com/view/anime-forest-scenery-sunrays-gif-5261536", 35 | title: "forest", 36 | youtube: "https://youtu.be/o-9ayXhpbyM", 37 | }, 38 | { 39 | id: "5", 40 | image: "https://media2.giphy.com/media/3o7WTQaaMsNunSUImY/giphy.gif?cid=ecf05e47drzybb2zf07xm2wd7kgn0zte2xqh57669hdjj394&rid=giphy.gif&ct=g", 41 | imageCredit: "https://giphy.com/gifs/animated-illustration-starry-night-3o7WTQaaMsNunSUImY", 42 | title: "silence", 43 | youtube: "", 44 | }, 45 | { 46 | id: "6", 47 | image: "https://c.tenor.com/9b3VtLqXRAYAAAAC/another-anime.gif", 48 | imageCredit: "https://tenor.com/view/another-anime-kouichi-sakakibara-blink-relaxing-gif-18544197", 49 | title: "white noise", 50 | youtube: 51 | "https://youtu.be/FdN1pnEaJs0", 52 | }, 53 | { 54 | id: "7", 55 | image: "https://c.tenor.com/HQHhPkADoWoAAAAC/medabots-metabee.gif", 56 | imageCredit: "https://tenor.com/view/medabots-metabee-calor-ventilador-hot-gif-18300475", 57 | title: "running fan", 58 | youtube: 59 | "https://youtu.be/_D6Zi9OlUVM", 60 | }, 61 | { 62 | id: "8", 63 | image: "https://media3.giphy.com/media/GQbAyoxyDzWQE/giphy.gif?cid=ecf05e47ojvbl3sf06xjs5a8wfwx9r6d7blquw01jzuvtd73&rid=giphy.gif&ct=g", 64 | imageCredit: "https://giphy.com/gifs/piano-anime-gif-GQbAyoxyDzWQE", 65 | title: "river flows in you - yiruma 이루마", 66 | youtube: 67 | "https://youtu.be/7maJOI3QMu0", 68 | }, 69 | { 70 | id: "9", 71 | image: "https://media2.giphy.com/media/PQaRWf6SOtCAU/giphy.gif?cid=790b7611d9d84a262a48592ae01bd6b35a1182cd9db077dd&rid=giphy.gif&ct=g", 72 | imageCredit: "https://giphy.com/gifs/maudit-kikis-delivery-service-PQaRWf6SOtCAU", 73 | title: "[bt21] koya's sleep music", 74 | youtube: "https://youtu.be/dkCW7cfrgBs", 75 | }, 76 | { 77 | id: "10", 78 | image: "https://media4.giphy.com/media/U43yQY2sEqdtgmWkIY/giphy.gif?cid=ecf05e47l1fkswff31pyr6g1sab7gccd441r7ribb5fni9oa&rid=giphy.gif&ct=g", 79 | imageCredit: "https://giphy.com/gifs/fireflies-larapaulussen-lara-paulussen-U43yQY2sEqdtgmWkIY", 80 | title: "different silence", 81 | youtube: "", 82 | }, 83 | { 84 | id: "11", 85 | image: "https://media1.giphy.com/media/DoIquD1MhDGMw/giphy.gif?cid=ecf05e479yii17y46b92bpnkkgc59ahqbo1caaihcpjfubt9&rid=giphy.gif&ct=g", 86 | imageCredit: "https://giphy.com/gifs/cat-kitten-DoIquD1MhDGMw", 87 | title: "cat purring", 88 | youtube: 89 | "https://youtu.be/DeTbhbu-1D8", 90 | }, 91 | { 92 | id: "12", 93 | image: "https://c.tenor.com/JzgronqM0nsAAAAd/dancing-steve.gif", 94 | title: "minecraft soundtrack", 95 | imageCredit: "https://tenor.com/view/dancing-steve-minecraft-moves-gif-16034488", 96 | youtube: 97 | "https://youtu.be/Dg0IjOzopYU", 98 | }, 99 | { 100 | id: "13", 101 | image: "https://c.tenor.com/04l8AnfK5ckAAAAC/charizard-pokemon-charizard.gif", 102 | imageCredit: "https://tenor.com/view/charizard-pokemon-charizard-flamethrower-angry-mad-gif-23766460", 103 | title: "dinosaur", 104 | youtube: 105 | "https://youtu.be/1vBsBa9KS2c", 106 | }, 107 | 108 | 109 | ]; 110 | 111 | return ( 112 | 113 | {props.children} 114 | 115 | ); 116 | }; 117 | -------------------------------------------------------------------------------- /src/components/CardDetails/CardDetails.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState, useEffect, useRef } from "react"; 2 | import { MusicInfoContext } from "../../Contexts/MusicInfoContext"; 3 | import { Credits } from "./Credits"; 4 | import LightSettingsMenu from "./LightSettingsMenu"; 5 | import LightsStatus from "./LightsStatus"; 6 | import Player from "../Player"; 7 | import { useInterval } from "../../custom-hooks/useInterval"; 8 | import { useParams, Link } from "react-router-dom"; 9 | import "./CardDetails.css"; 10 | import GridViewSharpIcon from "@mui/icons-material/GridViewSharp"; 11 | import WbIncandescentSharpIcon from "@mui/icons-material/WbIncandescentSharp"; 12 | import DialogComponent from "../DialogComponent/DialogComponent"; 13 | import Stack from "@mui/material/Stack"; 14 | import Slider from "@mui/material/Slider"; 15 | import Typography from "@mui/material/Typography"; 16 | import AppBar from "@mui/material/AppBar"; 17 | import Box from "@mui/material/Box"; 18 | import Toolbar from "@mui/material/Toolbar"; 19 | import VolumeDown from "@mui/icons-material/VolumeDown"; 20 | import VolumeUp from "@mui/icons-material/VolumeUp"; 21 | import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined"; 22 | 23 | const CardDetails = () => { 24 | const textInput = useRef(null); 25 | const [isOpen, setIsOpen] = useState(false); 26 | const [volume, setVolume] = useState(1); 27 | const [intervalVolume, setIntervalVolume] = useState(30000); 28 | const [lightsStatus, setLightsStatus] = useState(LightsStatus.lightsGraduallyOff); 29 | const className = lightsStatus === LightsStatus.lightsGraduallyOff ? "outerDiv" : lightsStatus === LightsStatus.lightsOn ? "lightsOn" : "lightsOff"; 30 | const [isHover, setIsHover] = useState(false); 31 | const appBarClassName = isHover ? "lightsOn" : "lightsOff"; 32 | const [anchorEl, setAnchorEl] = React.useState(null); 33 | const [anchorElInfo, setAnchorElInfo] = React.useState(null); 34 | const { id } = useParams(); 35 | const music = useContext(MusicInfoContext).find((element) => { return element.id === id }); 36 | 37 | const myStyle = { 38 | height: "100vh", 39 | width: "auto", 40 | justifyContent: "center", 41 | whiteSpace: "pre-line", 42 | backgroundImage: `url(${music.image})`, 43 | backgroundRepeat: "no-repeat", 44 | backgroundSize: "cover", 45 | }; 46 | 47 | const iconStyle = { 48 | cursor: "pointer", 49 | fontSize: "2em", 50 | }; 51 | 52 | const footerStyle = { 53 | position: "absolute", 54 | bottom: "20px", 55 | right: "10px", 56 | display: "flex", 57 | justifyContent: "flex-end", 58 | opacity: "0.6", 59 | } 60 | 61 | useEffect(() => { 62 | setLightsStatus(LightsStatus.lightsGraduallyOff); 63 | setIsHover(false); 64 | }, [useParams()]); 65 | 66 | useInterval( 67 | () => { 68 | setVolume(volume - 0.05); 69 | console.log(volume); 70 | }, 71 | volume > 0.2 ? intervalVolume : null 72 | ); 73 | 74 | const toggleAppbarHover = (num) => { 75 | if (num === 0) setIsHover(true); 76 | else setIsHover(false); 77 | }; 78 | 79 | const handleListIconClick = () => { 80 | setIsOpen(true); 81 | }; 82 | 83 | const handleClickMenu = (event) => { 84 | setAnchorEl(event.currentTarget); 85 | }; 86 | 87 | const handleShowInfo = (event) => { 88 | setAnchorElInfo(event.currentTarget); 89 | }; 90 | 91 | const handleSliderChange = (event, newValue) => { 92 | if (typeof newValue === "number") { 93 | setVolume(newValue / 100); 94 | setIntervalVolume(null); 95 | } 96 | }; 97 | 98 | return ( 99 |
100 | toggleAppbarHover(0)} 104 | onMouseLeave={() => toggleAppbarHover(1)} 105 | className={appBarClassName} 106 | > 107 | 108 | 116 | 117 | insomnia. 118 | 119 | 120 | 121 | 127 | 128 | 133 | 134 | 135 | 136 | 141 | 147 | 152 | 153 | 154 | 155 |
156 | 157 |
158 | 159 | 193 |
194 | ); 195 | }; 196 | 197 | export default CardDetails; 198 | --------------------------------------------------------------------------------