├── LICENSE ├── README.md ├── assets ├── bg.jpg └── favicon.png ├── docs └── screenshot.png ├── index.html ├── script.js └── styles.css /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tikaro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minimum Viable Startpage 2 | 3 | ![Screenshot](https://raw.githubusercontent.com/0-Tikaro/minimum-viable-startpage/master/docs/screenshot.png) 4 | 5 | This is a startpage I put together on one lazy afternoon. Cheers. :cat2: 6 | 7 | ## What is a startpage? 8 | A startpage is a small custom webpage that replaces the new tab page of your browser. It's usually done for the sake of aesthetics or to raise the efficiency of your day-to-day work with the Internet. (But mostly for aesthetics) 9 | 10 | ## Shortcuts 11 | MVS supports keyboard shortcuts, so you don't even have to use the mouse to get anywhere! By default shortcuts come in the Tab+KEY format. Tab in this case is the *shortcut starter* which tells the page to start listening for shortcuts. KEY is the actual shortcut unique to each item on the page. Both parts of a keyboard shortcut are customizable. 12 | 13 | Forgot which key led to which page? Simply pressing Tab will briefly flash all the shortcuts next to their relevant links. 14 | 15 | ## Customization 16 | To change the groups of links and keyboard shortcuts, change the `MASTER_MAP` object inside `script.js`. The syntax should be extremely intuitive. 17 | 18 | ## Installation 19 | To install this startpage and use it on your local machine, simply clone the repository and set your browser's new tab URL to the `index.html` filepath. 20 | 21 | (Note: Your browser may not support changing new tab's URL natively. I use [New Tab Redirect](https://chrome.google.com/webstore/detail/new-tab-redirect/icpgjfneehieebagbmdbhnlpiopdcmna) extension for Chrome.) 22 | 23 | ## Credits 24 | * [Wallpaper used for the background](https://wallpapercave.com/wp/VD8ldiL.jpg) 25 | 26 | ## License 27 | Distributed under the MIT license. See LICENSE for details. 28 | -------------------------------------------------------------------------------- /assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0-Tikaro/minimum-viable-startpage/a4fb4aea4474d635c4e4738f7d8c1a485d5d74c8/assets/bg.jpg -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0-Tikaro/minimum-viable-startpage/a4fb4aea4474d635c4e4738f7d8c1a485d5d74c8/assets/favicon.png -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0-Tikaro/minimum-viable-startpage/a4fb4aea4474d635c4e4738f7d8c1a485d5d74c8/docs/screenshot.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Home 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 |
23 | 24 |
25 |
26 | Made by Tikaro, avaialble on GitHub 27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const NAME = "John"; 2 | const WELCOME_MESSAGE_TEMPLATE = ["night", "morning", "afternoon", "evening"]; 3 | 4 | // All shortcuts are in a `SHORTCUT_STARTER+shortcutKey` format. 5 | // So, for example, pressing `tab+q` would redirect you to https://google.com/?q=q 6 | const SHORTCUT_STARTER = 'tab' 7 | 8 | // How much time (in milliseconds) you have to press shortcutKey after pressing SHORTCUT_STARTER. 9 | // Also change --SHORTCUT_TIMEOUT in styles.css if you change this option. 10 | const SHORTCUT_TIMEOUT = 1500; 11 | 12 | // The groups of links are generated from this object. Edit it to edit the page's contents. 13 | // shortcutKey must hold an all-lowercase single button. Theoretically should work with values like `esc` and `f1`, 14 | // but intended to be used with just regular latin letters. 15 | const MASTER_MAP = [ 16 | { 17 | "groupName": "Studies", 18 | "items":[ 19 | {"name": "Item A", "shortcutKey": "q", "url": "https://google.com/?q=q"}, 20 | {"name": "Item B", "shortcutKey": "w", "url": "https://google.com/?q=w"}, 21 | {"name": "Item C", "shortcutKey": "e", "url": "https://google.com/?q=e"} 22 | ] 23 | }, 24 | { 25 | "groupName": "Work", 26 | "items":[ 27 | {"name": "Item D", "shortcutKey": "a", "url": "https://google.com/?q=a"}, 28 | {"name": "Item E", "shortcutKey": "s", "url": "https://google.com/?q=s"}, 29 | {"name": "Item F", "shortcutKey": "d", "url": "https://google.com/?q=d"} 30 | ] 31 | }, 32 | { 33 | "groupName": "Personal", 34 | "items":[ 35 | {"name": "Item I", "shortcutKey": "z", "url": "https://google.com/?q=z"}, 36 | {"name": "Item J", "shortcutKey": "x", "url": "https://google.com/?q=x"}, 37 | {"name": "Item K", "shortcutKey": "c", "url": "https://google.com/?q=c"} 38 | ] 39 | } 40 | ] 41 | 42 | let $container = document.getElementById("content"); 43 | let getUrl = {}; 44 | 45 | let $shortcutDisplayList = document.getElementsByClassName("shortcut"); 46 | let listeningForShortcut = false; 47 | let listenerTimeout; 48 | 49 | function setupWelcomeMessage(){ 50 | let curHours = new Date().getHours(); 51 | curHours = Math.floor(curHours/6); // Simply dividing current hours by 6 proves to be a good enough aproximation. 52 | if (curHours == 4) curHours = 3; 53 | let welcome = "Good " + WELCOME_MESSAGE_TEMPLATE[curHours] + ", " + NAME; 54 | document.getElementById("welcome-string").innerHTML = welcome; 55 | } 56 | 57 | function setupGroups(){ 58 | for (let i = 0; i < MASTER_MAP.length; i++){ 59 | let curGroupData = MASTER_MAP[i]; 60 | 61 | let group = document.createElement("div"); 62 | group.className = "group"; 63 | $container.appendChild(group); 64 | 65 | let header = document.createElement("h1"); 66 | header.innerHTML = curGroupData.groupName; 67 | group.appendChild(header); 68 | 69 | for (let j = 0; j < curGroupData.items.length; j++){ 70 | let curItemData = curGroupData.items[j]; 71 | 72 | let pContainer = document.createElement("p"); 73 | group.appendChild(pContainer); 74 | 75 | let link = document.createElement("a"); 76 | link.innerHTML = curItemData.name; 77 | link.setAttribute("href", curItemData.url); 78 | pContainer.appendChild(link); 79 | 80 | let shortcutDisplay = document.createElement("span"); 81 | shortcutDisplay.innerHTML = curItemData.shortcutKey; 82 | shortcutDisplay.className = "shortcut"; 83 | shortcutDisplay.style.animation = "none"; 84 | pContainer.appendChild(shortcutDisplay); 85 | 86 | getUrl[curItemData.shortcutKey] = curItemData.url 87 | } 88 | } 89 | } 90 | 91 | function shortcutListener(e) { 92 | let key = e.key.toLowerCase(); 93 | 94 | if (listeningForShortcut && getUrl.hasOwnProperty(key)){ 95 | window.location = getUrl[key]; 96 | } 97 | 98 | if (key === SHORTCUT_STARTER) { 99 | clearTimeout(listenerTimeout); 100 | listeningForShortcut = true; 101 | 102 | // Animation reset 103 | for (let i = 0; i < $shortcutDisplayList.length; i++){ 104 | $shortcutDisplayList[i].style.animation = "none"; 105 | setTimeout(function() { $shortcutDisplayList[i].style.animation = ''; }, 10); 106 | } 107 | 108 | listenerTimeout = setTimeout(function(){ listeningForShortcut = false; }, SHORTCUT_TIMEOUT); 109 | } 110 | } 111 | 112 | function main(){ 113 | setupWelcomeMessage(); 114 | setupGroups(); 115 | document.addEventListener('keyup', shortcutListener, false); 116 | } 117 | 118 | main(); 119 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* Red borders on visible elements - handy for debugging */ 2 | /** { border: 1px solid red; }*/ 3 | 4 | :root { 5 | --bg-color: #223030; 6 | --text-color: #dddddd; 7 | --bg-image: url("assets/bg.jpg"); 8 | --SHORTCUT_TIMEOUT: 1.5s; 9 | } 10 | body { 11 | padding: 0; 12 | margin: 0; 13 | 14 | background: var(--bg-image); 15 | background-color: var(--bg-color); 16 | background-size: cover; 17 | color: var(--text-color); 18 | 19 | font-family: 'Raleway', sans-serif; 20 | font-size: 22px; 21 | 22 | user-select: none; 23 | animation: fadein 1s; 24 | } 25 | 26 | #logo { 27 | padding-top: 25vh; 28 | text-align: center; 29 | } 30 | #logo h1 { 31 | font-weight: 200; 32 | font-size: 4rem; 33 | margin-bottom: 0; 34 | } 35 | #logo h2 { 36 | font-weight: 200; 37 | font-size: 2rem; 38 | margin-top: 0; 39 | opacity: 0.5; 40 | } 41 | 42 | #content { 43 | text-align: center; 44 | } 45 | 46 | #credits { 47 | /* Uncomment to hide credits from your local copy */ 48 | /*display: none;*/ 49 | position: absolute; 50 | font-size: 1rem; 51 | opacity: 0.5; 52 | bottom: 1rem; 53 | left: 1rem; 54 | } 55 | 56 | .group { 57 | display: inline-block; 58 | vertical-align: top; 59 | text-align: left; 60 | width: 20%; 61 | padding: 1% 3%; 62 | } 63 | .group h1 { 64 | font-weight: 400; 65 | font-size: 2rem; 66 | margin-bottom: 0; 67 | border-bottom: 2px solid var(--text-color); 68 | } 69 | .group p { 70 | margin-bottom: 0; 71 | padding: 0.3rem 0; 72 | } 73 | .group p + p { 74 | margin: 0; 75 | } 76 | 77 | .shortcut { 78 | float: right; 79 | opacity: 0; 80 | animation: pulse var(--SHORTCUT_TIMEOUT); 81 | } 82 | 83 | a, a:hover { 84 | transition: all 0.4s ease; 85 | } 86 | a { 87 | padding: 0.3rem 0; 88 | color: var(--text-color); 89 | text-decoration: none; 90 | 91 | opacity: 0.5; 92 | padding-left: 0; 93 | } 94 | .group a:hover { 95 | opacity: 1; 96 | padding-left: 0.5rem; 97 | } 98 | #credits a:hover { 99 | opacity: 1; 100 | } 101 | 102 | @keyframes fadein { 103 | from { opacity: 0; } 104 | to { opacity: 1; } 105 | } 106 | @keyframes pulse { 107 | 0% { opacity: 0; } 108 | 20% { opacity: 0.3; } 109 | 80% { opacity: 0.3; } 110 | 100% { opacity: 0; } 111 | } --------------------------------------------------------------------------------