diff --git a/config.js b/config.js new file mode 100644 index 0000000..e3d79e1 --- /dev/null +++ b/config.js @@ -0,0 +1,5 @@ +config = { + prompt: 'user@browser $ ', + wallpaper: './src/img/background.jpg' +} + diff --git a/index.html b/index.html new file mode 100644 index 0000000..1b2cb7f --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ + + + + + Startpage + + + +
+
+
+ + +
+
+
+ + + + + + + diff --git a/src/css/style.css b/src/css/style.css new file mode 100644 index 0000000..eb32c86 --- /dev/null +++ b/src/css/style.css @@ -0,0 +1,50 @@ +@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap'); + +body { + margin: 0; + padding: 0; + font-family: 'Source Code Pro', monospace; + color: #e3e3e3; +} + +#main { + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background-size: cover; +} + +#terminal { + width: 40%; + height: 60%; + overflow-y: scroll; + cursor: text; + padding: 1em; + border: #237e99 3px solid; + border-radius: 1em; + background-color: #252625d1; + backdrop-filter: blur(8px); +} + +.line { + min-height: 1.5em; +} + +.red { + color: #c22f2f; +} + +#command-line input { + width: 70%; + background: none; + color: inherit; + font-family: inherit; + font-size: 1em; + border: none; +} + +#command-line input:focus { + outline: none; +} diff --git a/src/img/background.jpg b/src/img/background.jpg new file mode 100644 index 0000000..e33dcb2 Binary files /dev/null and b/src/img/background.jpg differ diff --git a/src/js/commands.js b/src/js/commands.js new file mode 100644 index 0000000..5303772 --- /dev/null +++ b/src/js/commands.js @@ -0,0 +1,49 @@ +const commands = { + go: (target) => { + if (target == '') { + _print('No target given!', color = 'red'); + } else { + if (!target.match(/^https?:\/\/.+/g)) { + target = 'http://' + target; + } + window.open(target, "_self"); + } + }, + google: (query) => { + if (query == '') { + window.open("https://google.com/", "_self"); + } else { + window.open("https://google.com/search?q=" + query, "_self"); + } + }, + reddit: (subreddit) => { + if (subreddit == '') { + window.open("https://reddit.com/", "_self"); + } else { + window.open("https://reddit.com/r/" + subreddit, "_self"); + } + }, + print: (string) => { + _print(string); + }, + clear: () => { + _clear(); + }, + date: () => { + _print('26/04/2022') + }, + clock: () => { + const date = new Date(); + const hours = date.getHours(); + const minutes = date.getMinutes(); + _print(hours + ':' + minutes); + }, + show_commands: () => { + let availableCommands = Object.keys(commands); + let output = ''; + availableCommands.forEach((cmd) => { + output += cmd + ' '; + }); + _print(output); + } +} diff --git a/src/js/terminal.js b/src/js/terminal.js new file mode 100644 index 0000000..f188843 --- /dev/null +++ b/src/js/terminal.js @@ -0,0 +1,25 @@ +const main = document.querySelector('#main'); +const terminal = document.querySelector('#terminal'); +const prompt = document.querySelector('#prompt'); +const commandInput = document.querySelector('#command-line input'); + +commandInput.addEventListener('keypress', (event) => { + if (event.keyCode === 13) { + event.preventDefault(); + rawEntry = commandInput.value; + _execute(rawEntry); + commandInput.value = ''; + }; +}); + + +// Set prompt text +prompt.innerText = config.prompt; + +// Set background +main.style.backgroundImage = `url('${config.wallpaper}')`; + +// Set events +terminal.addEventListener('click', focusToPrompt); +window.addEventListener('load', focusToPrompt); + diff --git a/src/js/utils.js b/src/js/utils.js new file mode 100644 index 0000000..0d838fa --- /dev/null +++ b/src/js/utils.js @@ -0,0 +1,40 @@ +const focusToPrompt = () => { + commandInput.focus(); +} + +const parseEntry = (entry) => { + entry = entry.trim().replace(/\s\s+/g, ' '); + command = entry.split(' ')[0]; + arg = entry.replace(command, '').trim(); + return {command, arg}; +} + +const _print = (arg, color = null) => { + let line = document.createElement('div'); + line.classList.add('line'); + if (color == 'red') { + line.classList.add('red'); + } + line.innerText += arg; + let commandInput = document.querySelector('#command-line'); + commandInput.parentNode.insertBefore(line, commandInput); +} + +const _clear = () => { + document.querySelectorAll('.line').forEach((elm) => { + elm.parentNode.removeChild(elm); + }); +} + +const _execute = (rawEntry) => { + let returns = null + _print(prompt.innerText + rawEntry); + parsed = parseEntry(rawEntry); + if (!(parsed.command in commands) && (parsed.command != '')) { + _print('Unknown command!', color = 'red'); + } else { + returns = commands[parsed.command](parsed.arg); + } + return returns; +} +