diff options
-rw-r--r-- | apps/Calculator/components/App.js | 109 | ||||
-rw-r--r-- | apps/Calculator/index.js | 3 | ||||
-rw-r--r-- | apps/Calculator/styles/Calculator.module.scss | 1 | ||||
-rw-r--r-- | apps/Calculator/styles/_calculator.scss | 92 | ||||
-rw-r--r-- | apps/index.js | 1 | ||||
-rw-r--r-- | configs/appList.js | 3 | ||||
-rw-r--r-- | configs/translations.js | 4 | ||||
-rw-r--r-- | public/icons/calculator.svg | 10 |
8 files changed, 222 insertions, 1 deletions
diff --git a/apps/Calculator/components/App.js b/apps/Calculator/components/App.js new file mode 100644 index 0000000..df46751 --- /dev/null +++ b/apps/Calculator/components/App.js @@ -0,0 +1,109 @@ +import { useState } from 'react'; +import styles from '../styles/Calculator.module.scss' + +const App = () => { + const [display, setDisplay] = useState('0') + const [memory, setMemory] = useState([]) + const [result, setResult] = useState([]) + + const onClear = () => { + setDisplay('0') + setMemory([]) + } + const onNumber = n => setDisplay(p => display === '0' ? n.toString() : p+n) + const onMath = m => { + if (display !== '0') { + if (!result) { + setMemory(p => [ + ...p, + { type: 'n', value: display }, + { type: 'm', value: m }, + ]); + } else { + setResult(false) + setMemory([ + { type: 'n', value: display }, + { type: 'm', value: m }, + ]); + } + setDisplay('0') + } else if (memory[memory.length - 1].type === 'm') { + setMemory(p => [...p.slice(0, -1), { type: 'm', value: m }]); + } + } + + const newVal = (prevVal, curVal) => { + if (!prevVal || !prevVal.m) return 0; + + if (prevVal.m === '+') { + return `${Number(prevVal.value) + Number(curVal.value)}` + } + if (prevVal.m === '-') { + return `${Number(prevVal.value) - Number(curVal.value)}` + } + if (prevVal.m === '*') { + return `${Number(prevVal.value) * Number(curVal.value)}` + } + if (prevVal.m === '/') { + return prevVal.value !== '0' && curVal.value !== '0' + ? `${Number(prevVal.value) / Number(curVal.value)}` + : '0' + } + } + + const onResult = () => { + if (memory.length > 2 || (memory.length > 1 && display !== '0')) { + const actions = display === 0 + ? memory + : [...memory, { type: 'n', value: display }] + const result = actions.reduce((prevVal, curVal) => { + return curVal.type === 'n' + ? ({ value: newVal(prevVal, curVal), m: null }) + : ({ value: prevVal.value, m: curVal.value }) + }) + setDisplay(result?.value || 0); + setResult(true) + if (display !== 0) { + setMemory(p => [...p, { type: 'n', value: display }]) + } + } + } + + return ( + <> + <div className='window__submenu'> + <div> + <div onClick={onClear}> + Clear + </div> + </div> + </div> + <div className={styles.calculator}> + <div className={styles.display}> + <div> + { memory.map(o => o.value).join(' ') } + </div> + <div> + {display} + </div> + </div> + <div className={styles.keys}> + <div> + { [...Array(10).keys()].map(k => ( + <div key={k} onClick={() => onNumber(k)}>{k}</div> + )) } + <div onClick={() => setDisplay(p => p+'.')}>.</div> + <div onClick={onResult}>=</div> + </div> + <div> + {['+','-','*','/'].map(m => ( + <div key={m} onClick={() => onMath(m)}>{m}</div> + ))} + </div> + </div> + </div> + </> + ) +} + +export default App diff --git a/apps/Calculator/index.js b/apps/Calculator/index.js new file mode 100644 index 0000000..4a7ef43 --- /dev/null +++ b/apps/Calculator/index.js @@ -0,0 +1,3 @@ +import Calculator from './components/App' + +export default Calculator diff --git a/apps/Calculator/styles/Calculator.module.scss b/apps/Calculator/styles/Calculator.module.scss new file mode 100644 index 0000000..2bc25fa --- /dev/null +++ b/apps/Calculator/styles/Calculator.module.scss @@ -0,0 +1 @@ +@import "calculator"; diff --git a/apps/Calculator/styles/_calculator.scss b/apps/Calculator/styles/_calculator.scss new file mode 100644 index 0000000..987a0ea --- /dev/null +++ b/apps/Calculator/styles/_calculator.scss @@ -0,0 +1,92 @@ +.calculator { + width: 100%; + height: 100%; + position: relative; + background-color: #000; + display: flex; + flex-direction: column; + background-color: var(--color-window-content); +} + +.display { + height: 20%; + background-color: var(--color-text); + color: var(--color-window-content); + display: flex; + flex-direction: column; + padding-right: 1em; + + > div:nth-child(1) { + font-size: 1em; + padding-top: .5em; + white-space: nowrap; + text-align: right; + } + + > div:nth-child(2) { + font-size: 2.5em; + flex-grow: 1; + display: flex; + align-items: center; + justify-content: flex-end; + } +} + +.keys { + height: 80%; + width: 100%; + display: flex; + + & > div { + height: 100%; + display: flex; + + & > div { + height: 25%; + display: flex; + justify-content: center; + align-items: center; + border: 1px solid var(--color-window-buttons); + transition: .3s background-color; + font-size: 2em; + } + + &:nth-of-type(1) { + width: 75%; + flex-wrap: wrap; + background-color: var(--color-window-popup); + + & > div { + width: 33.3%; + flex-grow: 1; + + &:hover { + background-color: var(--color-window-content); + } + + &:first-of-type { + order: 2; + } + + &:nth-of-type(12) { + order: 3; + } + } + } + + &:nth-of-type(2) { + width: 25%; + flex-direction: column; + + & > div { + width: 100%; + background-color: var(--color-window-menu-alt); + + &:hover { + background-color: var(--color-window-content); + } + } + } + } + +} diff --git a/apps/index.js b/apps/index.js index 465761b..eccedac 100644 --- a/apps/index.js +++ b/apps/index.js @@ -1,3 +1,4 @@ +export { default as Calculator } from './Calculator' export { default as Notes } from './Notes' export { default as Player } from './Player' export { default as Settings } from './Settings' diff --git a/configs/appList.js b/configs/appList.js index b5f1eac..83535a3 100644 --- a/configs/appList.js +++ b/configs/appList.js @@ -1,6 +1,7 @@ -import { Notes, Player, Settings, Youtube } from 'apps' +import { Calculator, Notes, Player, Settings, Youtube } from 'apps' const appList = { + Calculator: { component: Calculator, icon: true, buttons: ['min', 'close'], height: '40em', width: '30em' }, Notes: { component: Notes, icon: true, buttons: ['min', 'max', 'close'], height: '48em', width: '64em' }, Player: { component: Player, icon: true, buttons: ['min', 'max', 'close'], height: '48em', width: '64em' }, Settings: { component: Settings, icon: false, buttons: ['min'], height: '23em', width: '16em' }, diff --git a/configs/translations.js b/configs/translations.js index 11a5988..79fcf7d 100644 --- a/configs/translations.js +++ b/configs/translations.js @@ -33,6 +33,7 @@ const translations = { created: 'Created', modified: 'Modified', open_apps: 'Open apps:', + Calculator: 'Calculator', Notes: 'Notes', Player: 'Player', Settings: 'Settings', @@ -120,6 +121,7 @@ const translations = { created: 'Utworzono', modified: 'Zmodyfikowano', open_apps: 'Otwarte aplikacje:', + Calculator: 'Kalkulator', Notes: 'Notatki', Player: 'Odtwarzacz', Settings: 'Ustawienia', @@ -207,6 +209,7 @@ const translations = { created: 'Creado', modified: 'Modificado', open_apps: 'Aplicaciones abiertas:', + Calculator: '????????????????????????????????????????????????????/', Notes: 'Notas', Player: 'Jugador', Settings: 'Ajustes', @@ -294,6 +297,7 @@ const translations = { created: 'Erstellt', modified: 'Geändert', open_apps: 'Anwendungen öffnen:', + Calculator: '????????????????????????????????????????????????????/', Notes: 'Anmerkungen', Player: 'Spieler', Settings: 'Einstellungen', diff --git a/public/icons/calculator.svg b/public/icons/calculator.svg new file mode 100644 index 0000000..9429c59 --- /dev/null +++ b/public/icons/calculator.svg @@ -0,0 +1,10 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" version="1"> + <path style="opacity:0.2" d="M 10,5 C 6.676,5 4,7.676 4,11 v 14 14 c 0,3.324 2.676,6 6,6 h 14 14 c 3.324,0 6,-2.676 6,-6 V 25 11 C 44,7.676 41.324,5 38,5 H 24 Z"/> + <path style="fill:#e4e4e4" d="m 38,4 c 3.324,0 6,2.676 6,6 V 24 H 24 V 4 Z"/> + <path style="fill:#f2f2f2" d="M 10,4 C 6.676,4 4,6.676 4,10 V 24 H 24 V 4 Z"/> + <path style="fill:#e4e4e4" d="M 10,44 C 6.676,44 4,41.324 4,38 V 24 h 20 v 20 z"/> + <path style="fill:#f2f2f2" d="m 38,44 c 3.324,0 6,-2.676 6,-6 V 24 H 24 v 20 z"/> + <path style="opacity:0.2;fill:#ffffff" d="M 10 4 C 6.676 4 4 6.676 4 10 L 4 11 C 4 7.676 6.676 5 10 5 L 24 5 L 38 5 C 41.324 5 44 7.676 44 11 L 44 10 C 44 6.676 41.324 4 38 4 L 24 4 L 10 4 z"/> + <path style="opacity:0.1" d="m 13,10 v 4 H 9 v 2 h 4 v 4 h 2 v -4 h 4 v -2 h -4 v -4 z m 16,4 v 2 H 39 V 14 Z M 9,30 v 1.414062 L 12.585938,35 9,38.585938 V 40 h 1.414062 L 14,36.414062 17.585938,40 H 19 V 38.585938 L 15.414062,35 19,31.414062 V 30 H 17.585938 L 14,33.585938 10.414062,30 Z m 20,1 v 2 h 10 v -2 z m 0,5 v 2 h 10 v -2 z"/> + <path style="fill:#0078d7" d="M 13 9 L 13 13 L 9 13 L 9 15 L 13 15 L 13 19 L 15 19 L 15 15 L 19 15 L 19 13 L 15 13 L 15 9 L 13 9 z M 29 13 L 29 15 L 39 15 L 39 13 L 29 13 z M 9 29 L 9 30.414062 L 12.585938 34 L 9 37.585938 L 9 39 L 10.414062 39 L 14 35.414062 L 17.585938 39 L 19 39 L 19 37.585938 L 15.414062 34 L 19 30.414062 L 19 29 L 17.585938 29 L 14 32.585938 L 10.414062 29 L 9 29 z M 29 30 L 29 32 L 39 32 L 39 30 L 29 30 z M 29 35 L 29 37 L 39 37 L 39 35 L 29 35 z"/> +</svg> |