mirror of
https://github.com/manilarome/the-glorious-startpage.git
synced 2025-03-03 08:41:25 +01:00
rewrite of js files (#19)
This commit is contained in:
parent
a9b176a483
commit
581cdea730
11
README.md
11
README.md
@ -64,7 +64,7 @@
|
||||
|
||||
#### Adding more buttons on the web menu
|
||||
|
||||
Add more buttons or web shortcuts in web menu by editing the `webSites` array in `js/sites-list.js`. Make sure to put an icon with `svg` format for the shortcut in `assets/webcons/` folder.
|
||||
Add more buttons or web shortcuts in web menu by editing the `webSites` array in `js/config.js`. Make sure to put an icon with `svg` format for the shortcut in `assets/webcons/` folder.
|
||||
|
||||
```js
|
||||
let webSites = [
|
||||
@ -80,7 +80,7 @@ let webSites = [
|
||||
|
||||
#### Adding more buttons on the dock
|
||||
|
||||
To add more web shortcuts/buttons in the dock, you have to edit the `dockSites` array in `js/sites-list.js`. Make sure to put an icon with `svg` format for the shortcut in `assets/webcons/` folder.
|
||||
To add more web shortcuts/buttons in the dock, you have to edit the `dockSites` array in `js/config.js`. Make sure to put an icon with `svg` format for the shortcut in `assets/webcons/` folder.
|
||||
|
||||
```js
|
||||
let dockSites = [
|
||||
@ -121,6 +121,13 @@ Google is the default search engine of the search bar, if you want to change it
|
||||
|
||||
+ Replace the `user.png` image file in `/assets/`.
|
||||
|
||||
#### Changing the background image
|
||||
|
||||
The background image changes based on time.
|
||||
|
||||
+ Change the background images in `assets/backgrounds/`.
|
||||
+ Make sure that it is in `webp` format.
|
||||
+ A lower resolution of each images are also required.
|
||||
|
||||
#### Keybindings
|
||||
|
||||
|
28
index.html
28
index.html
@ -67,6 +67,7 @@
|
||||
<li id='phrase'>
|
||||
<button type='button' class='phraseButton'>suggestion 4</button>
|
||||
</li>
|
||||
<!-- The list above will be deleted and will be replaced by a list generated by javascript -->
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -230,24 +231,33 @@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src='js/config.js'></script>
|
||||
<script src='js/body-background-set.js'></script>
|
||||
<script src='js/clock.js'></script>
|
||||
<script src='js/sites-list.js'></script>
|
||||
<script src='js/dock-buttons.js'></script>
|
||||
<script src='js/keybindings.js'></script>
|
||||
<script src='js/auto-suggest.js'></script>
|
||||
<script src='js/animate-profile-image.js'></script>
|
||||
<script src='js/show-search-box.js'></script>
|
||||
<script src='js/animate-dashboard.js'></script>
|
||||
<script src='js/greeter-date-message.js'></script>
|
||||
<script src='js/profile-image.js'></script>
|
||||
<script src='js/search-engine-settings.js'></script>
|
||||
<script src='js/search-query-send.js'></script>
|
||||
|
||||
<script src='js/show-search-box.js'></script>
|
||||
<script src='js/centered-box.js'></script>
|
||||
|
||||
<script src='js/greeter-date-message.js'></script>
|
||||
<script src='js/theme-engine.js'></script>
|
||||
<script src='js/dashboard.js'></script>
|
||||
|
||||
<script src='js/web-menu.js'></script>
|
||||
<script src='js/weather-screen.js'></script>
|
||||
<script src='js/weather-settings.js'></script>
|
||||
<script src='js/web-menu.js'></script>
|
||||
<script src='js/centered-box.js'></script>
|
||||
|
||||
<script src='js/auto-suggestion.js'></script>
|
||||
<script src='js/keybindings.js'></script>
|
||||
|
||||
<script src='js/mobile-swipe-event.js'></script>
|
||||
<script src='js/mobile-swipe-callback.js'></script>
|
||||
|
||||
<script src='js/script.js'></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,96 +0,0 @@
|
||||
const dashboard = document.getElementById("rightDashboard");
|
||||
const dashboardOverlay = document.getElementById("dashboardOverlay");
|
||||
|
||||
let rightDashboardVisibility = false;
|
||||
|
||||
// Disable/Enable inputs
|
||||
const disableDashboardInputs = (status) => {
|
||||
const elems = dashboard.getElementsByTagName('input');
|
||||
const len = elems.length;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
elems[i].disabled = status;
|
||||
}
|
||||
}
|
||||
|
||||
const showDashboard = () => {
|
||||
dashboard.classList.add('showRightDashboard');
|
||||
|
||||
// Show overlay
|
||||
dashboardOverlay.classList.add('showDashboardOverlay');
|
||||
|
||||
// Enable Inputs
|
||||
disableDashboardInputs(false);
|
||||
|
||||
rightDashboardVisibility = !rightDashboardVisibility;
|
||||
}
|
||||
|
||||
const hideDashboard = () => {
|
||||
dashboard.classList.remove('showRightDashboard');
|
||||
dashboard.scrollTop = 0;
|
||||
|
||||
// Disable Inputs
|
||||
disableDashboardInputs(true);
|
||||
|
||||
// Hide overlay
|
||||
dashboardOverlay.classList.remove('showDashboardOverlay');
|
||||
|
||||
rightDashboardVisibility = !rightDashboardVisibility;
|
||||
}
|
||||
|
||||
const toggleDashboard = () => {
|
||||
|
||||
console.log('toggle dashboard');
|
||||
|
||||
if (rightDashboardVisibility) {
|
||||
|
||||
// Hide dashboard
|
||||
hideDashboard();
|
||||
|
||||
} else {
|
||||
|
||||
// Show dashboard
|
||||
showDashboard();
|
||||
|
||||
// If centered box is hidden, open it
|
||||
if (centeredBox.classList.contains('hiddenBox')) {
|
||||
|
||||
console.log('centered box is hidden, reopening...');
|
||||
|
||||
// Rotate profile container
|
||||
rotateProfile();
|
||||
|
||||
// Toggle center box
|
||||
toggleCenteredBox();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any of these are open, if yes, close it
|
||||
if (weatherScreen.classList.contains('showWeatherScreen')) {
|
||||
console.log('weather screen is open, closing...');
|
||||
hideWeatherScreen();
|
||||
return;
|
||||
|
||||
} else if (searchBoxContainer.classList.contains('showSearchBox')) {
|
||||
console.log('searchbox is open, closing...');
|
||||
hideSearchBox();
|
||||
|
||||
} else if (webMenu.classList.contains('showWebMenu')) {
|
||||
console.log('web menu is open, closing...');
|
||||
hideWebMenu();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dashboardOverlay.addEventListener(
|
||||
"mouseup",
|
||||
() => {
|
||||
if (rightDashboardVisibility) {
|
||||
toggleDashboard();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Disable dashboard inputs on startup
|
||||
window.onload = disableDashboardInputs(true);
|
@ -1,43 +0,0 @@
|
||||
const profileContainer = document.getElementById("profileImageContainer");
|
||||
|
||||
let profileAnimRunning = false;
|
||||
|
||||
// Don't run animation on startup
|
||||
profileContainer.style.webkitAnimationPlayState = "paused";
|
||||
|
||||
// Rotate profile
|
||||
const rotateProfile = () => {
|
||||
event.preventDefault;
|
||||
|
||||
// Remove anim class
|
||||
profileContainer.classList.remove('rotateProfileAnim');
|
||||
|
||||
// Triggering reflow
|
||||
void profileContainer.offsetWidth;
|
||||
|
||||
// Re-add animation class
|
||||
profileContainer.classList.add('rotateProfileAnim');
|
||||
|
||||
// Start rotation animation
|
||||
profileContainer.style.webkitAnimationPlayState = "running";
|
||||
profileAnimRunning = true;
|
||||
}
|
||||
|
||||
// Re-enable animation after death
|
||||
profileContainer.addEventListener(
|
||||
"animationend",
|
||||
(event) => {
|
||||
profileAnimRunning = false;
|
||||
}
|
||||
);
|
||||
|
||||
// Animate/Show searchbox if profile container was clicked
|
||||
profileContainer.onclick = () => {
|
||||
if (profileAnimRunning) return;
|
||||
|
||||
// Rotate profile
|
||||
// rotateProfile();
|
||||
|
||||
// Toggle search box
|
||||
toggleSearchBox();
|
||||
};
|
@ -1,123 +0,0 @@
|
||||
var searchBox = document.getElementById('searchBox');
|
||||
var suggestionsUL = document.getElementById('suggestions');
|
||||
var suggestionsContainer = document.getElementById('suggestionsContainer');
|
||||
|
||||
|
||||
const hideSuggestions = () => {
|
||||
// Hide suggestions
|
||||
suggestionsContainer.classList.remove('suggestionsShow');
|
||||
}
|
||||
|
||||
const showSuggestions = () => {
|
||||
// Show suggestions
|
||||
suggestionsContainer.classList.add('suggestionsShow');
|
||||
}
|
||||
|
||||
|
||||
// Create input events
|
||||
const phraseEvents = button => {
|
||||
|
||||
// Update searchbox on enter key and mouse click
|
||||
button.onkeyup = event => {
|
||||
|
||||
if (event.key === 'Enter') {
|
||||
|
||||
searchBox.value = button.innerText;
|
||||
searchBox.focus();
|
||||
|
||||
} else if (event.key === 'Backspace') {
|
||||
|
||||
searchBox.focus();
|
||||
|
||||
} else if ((event.key == 'ArrowDown') || event.key == 'ArrowRight') {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const phraseButtons = Array.prototype.slice.call(document.querySelectorAll('button'));
|
||||
const phraseIndex = (phraseButtons.indexOf(document.activeElement) + 1) % phraseButtons.length;
|
||||
const phraseButton = phraseButtons[phraseIndex];
|
||||
phraseButton.focus();
|
||||
|
||||
} else if ((event.key == 'ArrowUp') || event.key == 'ArrowLeft') {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const phraseButtons = Array.prototype.slice.call(document.querySelectorAll('button'));
|
||||
const phraseIndex = (phraseButtons.indexOf(document.activeElement) - 1) % phraseButtons.length;
|
||||
|
||||
if (phraseIndex < 0) {
|
||||
phraseIndex = phraseButtons.length - 1;
|
||||
};
|
||||
|
||||
const phraseButton = phraseButtons[phraseIndex];
|
||||
phraseButton.focus();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Onmouseup event
|
||||
button.onmouseup = event => {
|
||||
searchBox.value = button.innerText;
|
||||
searchBox.focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Generate and parse suggestions
|
||||
const autocompleteCallback = phrase => {
|
||||
|
||||
// Filter/parse the object
|
||||
const suggestion = phrase.map(i => i.phrase)
|
||||
.filter(s => !(s.toLowerCase() === String(searchBox.value).toLowerCase()))
|
||||
.slice(0, 4);
|
||||
|
||||
// Empty ul on every callback to refresh list
|
||||
suggestionsUL.innerHTML = '';
|
||||
|
||||
|
||||
// Generate list elements
|
||||
for (let phrases of suggestion ) {
|
||||
|
||||
// Create html elements
|
||||
const li = document.createElement('li');
|
||||
li.id = 'phrase';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = 'phraseButton';
|
||||
button.innerHTML = phrases;
|
||||
|
||||
|
||||
// Create input events
|
||||
phraseEvents(button);
|
||||
|
||||
|
||||
// Appent to ul
|
||||
li.appendChild(button);
|
||||
suggestionsUL.appendChild(li);
|
||||
}
|
||||
|
||||
// Show suggestions
|
||||
showSuggestions();
|
||||
}
|
||||
|
||||
// Update every keyup
|
||||
searchBox.onkeyup = event => {
|
||||
|
||||
if (event.key === 'Tab') return;
|
||||
|
||||
if (searchBox.value < 1) {
|
||||
|
||||
// Hide suggestions
|
||||
hideSuggestions();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch from duckduckgo
|
||||
const script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = "https://duckduckgo.com/ac/?callback=autocompleteCallback&q="+String(searchBox.value);
|
||||
document.querySelector('head').appendChild(script);
|
||||
|
||||
}
|
137
js/auto-suggestion.js
Normal file
137
js/auto-suggestion.js
Normal file
@ -0,0 +1,137 @@
|
||||
class AutoSuggestion {
|
||||
constructor() {
|
||||
this._searchBox = document.querySelector('#searchBox');
|
||||
this._suggestionsUL = document.querySelector('#suggestions');
|
||||
this._suggestionsContainer = document.querySelector('#suggestionsContainer');
|
||||
|
||||
this._registerSearchBoxOnKeyUpEvent();
|
||||
}
|
||||
|
||||
_hideSuggestions = () => {
|
||||
// Hide suggestions
|
||||
this._suggestionsContainer.classList.remove('suggestionsShow');
|
||||
}
|
||||
|
||||
_showSuggestions = () => {
|
||||
// Show suggestions
|
||||
this._suggestionsContainer.classList.add('suggestionsShow');
|
||||
}
|
||||
|
||||
// Create input events
|
||||
_phraseEvents = button => {
|
||||
|
||||
// Update searchbox on enter key and mouse click
|
||||
button.onkeyup = e => {
|
||||
|
||||
if (e.key === 'Enter') {
|
||||
|
||||
this._searchBox.value = button.innerText;
|
||||
this._searchBox.focus();
|
||||
|
||||
} else if (e.key === 'Backspace') {
|
||||
|
||||
this._searchBox.focus();
|
||||
|
||||
} else if ((e.key == 'ArrowDown') || e.key == 'ArrowRight') {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const phraseButtons = Array.prototype.slice.call(document.querySelectorAll('button'));
|
||||
const phraseIndex = (phraseButtons.indexOf(document.activeElement) + 1) % phraseButtons.length;
|
||||
const phraseButton = phraseButtons[phraseIndex];
|
||||
phraseButton.focus();
|
||||
|
||||
} else if ((e.key == 'ArrowUp') || e.key == 'ArrowLeft') {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const phraseButtons = Array.prototype.slice.call(document.querySelectorAll('button'));
|
||||
const phraseIndex = (phraseButtons.indexOf(document.activeElement) - 1) % phraseButtons.length;
|
||||
|
||||
if (phraseIndex < 0) {
|
||||
phraseIndex = phraseButtons.length - 1;
|
||||
};
|
||||
|
||||
const phraseButton = phraseButtons[phraseIndex];
|
||||
phraseButton.focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Onmouseup event
|
||||
button.onmouseup = e => {
|
||||
this._searchBox.value = button.innerText;
|
||||
this._searchBox.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Generate and parse suggestions
|
||||
_autocompleteCallback = phrase => {
|
||||
|
||||
// Filter/parse the objectgerome matil
|
||||
const suggestion = phrase.map(i => i.phrase)
|
||||
.filter(s => !(s.toLowerCase() === String(this._searchBox.value).toLowerCase()))
|
||||
.slice(0, 4);
|
||||
|
||||
// Empty ul on every callback to refresh list
|
||||
this._suggestionsUL.innerHTML = '';
|
||||
|
||||
// Generate list elements
|
||||
for (let phrases of suggestion) {
|
||||
|
||||
// Create html elements
|
||||
const li = document.createElement('li');
|
||||
li.id = 'phrase';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = 'phraseButton';
|
||||
button.innerHTML = phrases;
|
||||
|
||||
// Create input events
|
||||
this._phraseEvents(button);
|
||||
|
||||
// Appent to ul
|
||||
li.appendChild(button);
|
||||
this._suggestionsUL.appendChild(li);
|
||||
}
|
||||
|
||||
// Show suggestions
|
||||
this._showSuggestions();
|
||||
}
|
||||
|
||||
_fetchSuggestion = () => {
|
||||
|
||||
const endpoint = 'https://duckduckgo.com/ac/';
|
||||
const callback = 'autocompleteCallback'
|
||||
window[callback] = res => {
|
||||
// Passed the suggestion object to process it
|
||||
this._autocompleteCallback(res);
|
||||
}
|
||||
|
||||
// Fetch from duckduckgo
|
||||
const script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = `${endpoint}?callback=${callback}&q=` + String(this._searchBox.value);
|
||||
document.querySelector('head').appendChild(script);
|
||||
}
|
||||
|
||||
_searchBoxOnKeyUpEvent = e => {
|
||||
|
||||
if (e.key === 'Tab') return;
|
||||
|
||||
if (this._searchBox.value < 1) {
|
||||
// Hide suggestions
|
||||
this._hideSuggestions();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch suggestion/phrases
|
||||
this._fetchSuggestion();
|
||||
}
|
||||
|
||||
_registerSearchBoxOnKeyUpEvent = () => {
|
||||
this._searchBox.onkeyup = this._searchBoxOnKeyUpEvent;
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +1,58 @@
|
||||
const backgroundBody = document.getElementById('bodyBackground')
|
||||
class BodyBackground {
|
||||
|
||||
// High quality background, we'll lazy load this
|
||||
const hqBackground = document.createElement("img");
|
||||
constructor() {
|
||||
this._bodyBackground = document.querySelector('#bodyBackground');
|
||||
this._hqBackground = document.createElement('img');
|
||||
this._bodyBackgroundStyle = this._bodyBackground.style;
|
||||
this._startLazyLoad();
|
||||
}
|
||||
|
||||
// Style body background
|
||||
const styleBodyBackground = (bgBodyStyle) => {
|
||||
bgBodyStyle.backgroundSize = 'cover';
|
||||
bgBodyStyle.backgroundRepeat = "no-repeat";
|
||||
bgBodyStyle.backgroundPosition = "center";
|
||||
bgBodyStyle.backgroundAttachment = "fixed";
|
||||
}
|
||||
_setBodyBackgrond = urlStr => {
|
||||
this._bodyBackgroundStyle.background = urlStr;
|
||||
this._bodyBackgroundStyle.backgroundSize = 'cover';
|
||||
this._bodyBackgroundStyle.backgroundRepeat = 'no-repeat';
|
||||
this._bodyBackgroundStyle.backgroundPosition = 'center';
|
||||
this._bodyBackgroundStyle.backgroundAttachment = 'fixed';
|
||||
}
|
||||
|
||||
const lazyLoadBackground = (fileName) => {
|
||||
_lazyLoadBackground = fileName => {
|
||||
|
||||
// Shorten backgroundBody.style or alias it
|
||||
const bgBodyStyle = backgroundBody.style;
|
||||
|
||||
// Set a low quality background image
|
||||
bgBodyStyle.background = "url('assets/backgrounds/" +
|
||||
fileName + "-low" + ".webp')";
|
||||
styleBodyBackground(bgBodyStyle);
|
||||
|
||||
// Add a class to blur it
|
||||
backgroundBody.classList.add("blurFiltered");
|
||||
|
||||
hqBackground.onload = () => {
|
||||
// Set a low quality background image
|
||||
this._setBodyBackgrond(`url('assets/backgrounds/${fileName}-low.webp')`);
|
||||
|
||||
// After downloading the HQ image, set it as bg
|
||||
backgroundBody.style.background = "url("+ hqBackground.src; + ")";
|
||||
styleBodyBackground(bgBodyStyle);
|
||||
// Add a class to blur it
|
||||
this._bodyBackground.classList.add('blurFiltered');
|
||||
|
||||
// Remove class to unblur
|
||||
backgroundBody.classList.remove("blurFiltered");
|
||||
this._hqBackground.onload = () => {
|
||||
|
||||
// After downloading the HQ image, set it as bg
|
||||
this._setBodyBackgrond(`url('${this._hqBackground.src}')`);
|
||||
|
||||
// Remove class to unblur
|
||||
this._bodyBackground.classList.remove('blurFiltered');
|
||||
}
|
||||
|
||||
// Add a delay when to fetch background
|
||||
setTimeout(
|
||||
() => {
|
||||
this._hqBackground.src = `assets/backgrounds/${fileName}.webp`;
|
||||
},
|
||||
50
|
||||
);
|
||||
}
|
||||
|
||||
_startLazyLoad = () => {
|
||||
const date = new Date();
|
||||
const hour = date.getHours();
|
||||
|
||||
// Add a delay when to fetch background
|
||||
setTimeout(
|
||||
() => {
|
||||
hqBackground.src = "assets/backgrounds/" +
|
||||
fileName + ".webp";
|
||||
},
|
||||
50
|
||||
);
|
||||
}
|
||||
if (hour >= 6 && hour < 12) {
|
||||
this._lazyLoadBackground('morning');
|
||||
|
||||
const initLazyLoad = () => {
|
||||
const date = new Date();
|
||||
const hour = date.getHours();
|
||||
} else if (hour >= 12 && hour < 18 ) {
|
||||
this._lazyLoadBackground('noon');
|
||||
|
||||
if (hour >= 6 && hour < 12) {
|
||||
lazyLoadBackground("morning");
|
||||
|
||||
} else if (hour >= 12 && hour < 18 ) {
|
||||
lazyLoadBackground("noon");
|
||||
|
||||
} else {
|
||||
lazyLoadBackground("evening");
|
||||
} else {
|
||||
this._lazyLoadBackground('evening');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize
|
||||
window.onload = initLazyLoad();
|
||||
}
|
@ -1,25 +1,33 @@
|
||||
const centeredBox = document.getElementById("centeredBox");
|
||||
class CenteredBox {
|
||||
constructor() {
|
||||
this._centeredBox = document.querySelector('#centeredBox');
|
||||
|
||||
let centeredBoxVisibility = true;
|
||||
this._centeredBoxVisibility = true;
|
||||
|
||||
const showCenteredBox = () => {
|
||||
centeredBox.classList.remove('hiddenBox');
|
||||
centeredBoxVisibility = !centeredBoxVisibility;
|
||||
}
|
||||
this.showCenteredBox = this.showCenteredBox.bind(this);
|
||||
this.hideCenteredBox = this.hideCenteredBox.bind(this);
|
||||
this.toggleCenteredBox = this.toggleCenteredBox.bind(this);
|
||||
}
|
||||
|
||||
const hideCenteredBox = () => {
|
||||
centeredBox.classList.add('hiddenBox');
|
||||
centeredBoxVisibility = !centeredBoxVisibility;
|
||||
}
|
||||
showCenteredBox = () => {
|
||||
this._centeredBox.classList.remove('hiddenBox');
|
||||
this._centeredBoxVisibility = !this._centeredBoxVisibility;
|
||||
}
|
||||
|
||||
const toggleCenteredBox = () => {
|
||||
hideCenteredBox = () => {
|
||||
this._centeredBox.classList.add('hiddenBox');
|
||||
this._centeredBoxVisibility = !this._centeredBoxVisibility;
|
||||
}
|
||||
|
||||
if (centeredBoxVisibility) {
|
||||
// Hide web menu
|
||||
hideCenteredBox();
|
||||
toggleCenteredBox = () => {
|
||||
|
||||
} else {
|
||||
// Show Web menu
|
||||
showCenteredBox();
|
||||
if (this._centeredBoxVisibility) {
|
||||
// hide centered box
|
||||
this.hideCenteredBox();
|
||||
|
||||
} else {
|
||||
// Show centered box
|
||||
this.showCenteredBox();
|
||||
}
|
||||
}
|
||||
}
|
67
js/clock.js
67
js/clock.js
@ -1,39 +1,42 @@
|
||||
const clock = document.getElementById("clock")
|
||||
class Clock {
|
||||
|
||||
// Append 0 before time elements if less hour's than 10
|
||||
const appendZero = (k) => {
|
||||
if (k < 10) {
|
||||
return "0" + k;
|
||||
} else {
|
||||
return k;
|
||||
constructor() {
|
||||
this._clockEl = document.querySelector('#clock');
|
||||
this._setTime = this._setTime.bind(this);
|
||||
this._startClock();
|
||||
}
|
||||
}
|
||||
|
||||
// Update/Set clock
|
||||
const currentTime = () => {
|
||||
// Date object
|
||||
const date = new Date();
|
||||
// Append 0 before time elements if less hour's than 10
|
||||
_appendZero = k => {
|
||||
if (k < 10) {
|
||||
return '0' + k;
|
||||
} else {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
// Set hour, minute
|
||||
let hour = date.getHours();
|
||||
let min = date.getMinutes();
|
||||
let midDay = "AM";
|
||||
|
||||
// Assigning
|
||||
midDay = (hour >= 12) ? "PM" : "AM";
|
||||
hour = (hour == 0) ? 12 : ((hour > 12) ? (hour - 12): hour);
|
||||
hour = appendZero(hour);
|
||||
min = appendZero(min);
|
||||
_setTime = () => {
|
||||
// Date object
|
||||
const date = new Date();
|
||||
|
||||
// Update clock id element
|
||||
clock.innerText = hour + ":" + min + " " + midDay;
|
||||
|
||||
// Recursion
|
||||
// Call itself if 1 second has passed.
|
||||
// TOKIWO TOMAREEEE!
|
||||
const t = setTimeout(currentTime, 1000);
|
||||
}
|
||||
// Set hour, minute
|
||||
let hour = date.getHours();
|
||||
let min = date.getMinutes();
|
||||
let midDay = 'AM';
|
||||
|
||||
// Assigning
|
||||
midDay = (hour >= 12) ? 'PM' : 'AM';
|
||||
hour = (hour == 0) ? 12 : ((hour > 12) ? (hour - 12) : hour);
|
||||
hour = this._appendZero(hour);
|
||||
min = this._appendZero(min);
|
||||
|
||||
// Start clock
|
||||
window.onload = currentTime();
|
||||
// Update clock id element
|
||||
this._clockEl.innerHTML = `${hour}:${min}${midDay}` ;
|
||||
}
|
||||
|
||||
_startClock = () => {
|
||||
this._setTime();
|
||||
setTimeout(this._setTime, 1000);
|
||||
}
|
||||
|
||||
}
|
323
js/config.js
Normal file
323
js/config.js
Normal file
@ -0,0 +1,323 @@
|
||||
class Config {
|
||||
|
||||
constructor() {
|
||||
this.getWebSites = this.getWebSites.bind(this);
|
||||
this.getDockSites = this.getDockSites.bind(this);
|
||||
}
|
||||
|
||||
getWebSites = () => {
|
||||
// Web menu
|
||||
// A list of websites that will be generated and put on the web menu
|
||||
const webSites = [
|
||||
{
|
||||
site: 'Reddit',
|
||||
icon: 'reddit',
|
||||
url: 'https://reddit.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Github',
|
||||
icon: 'github',
|
||||
url: 'https://github.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Facebook',
|
||||
icon: 'facebook',
|
||||
url: 'https://facebook.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Gmail',
|
||||
icon: 'gmail',
|
||||
url: 'https://mail.google.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Youtube',
|
||||
icon: 'youtube',
|
||||
url: 'https://youtube.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'GDrive',
|
||||
icon: 'gdrive',
|
||||
url: 'https://drive.google.com/',
|
||||
category: 'cloud'
|
||||
},
|
||||
{
|
||||
site: 'Twitter',
|
||||
icon: 'twitter',
|
||||
url: 'https://twitter.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Instagram',
|
||||
icon: 'instagram',
|
||||
url: 'https://instagram.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Bitbucket',
|
||||
icon: 'bitbucket',
|
||||
url: 'https://bitbucket.org/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Gitlab',
|
||||
icon: 'gitlab',
|
||||
url: 'https://gitlab.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Deviantart',
|
||||
icon: 'deviantart',
|
||||
url: 'https://deviantart.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Duckduckgo',
|
||||
icon: 'duckduckgo',
|
||||
url: 'https://duckduckgo.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Ecosia',
|
||||
icon: 'ecosia',
|
||||
url: 'https://ecosia.org/',
|
||||
category: 'search engine'
|
||||
},
|
||||
{
|
||||
site: 'Google',
|
||||
icon: 'google',
|
||||
url: 'https://google.com/',
|
||||
category: 'search engine'
|
||||
},
|
||||
{
|
||||
site: 'Wikipedia',
|
||||
icon: 'wikipedia',
|
||||
url: 'https://wikipedia.org/',
|
||||
category: 'information'
|
||||
},
|
||||
{
|
||||
site: 'Unsplash',
|
||||
icon: 'unsplash',
|
||||
url: 'https://unsplash.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Twitch',
|
||||
icon: 'twitch',
|
||||
url: 'https://twitch.tv/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Yahoo',
|
||||
icon: 'yahoo',
|
||||
url: 'https://mail.yahoo.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Material.io',
|
||||
icon: 'materialio',
|
||||
url: 'https://material.io/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Netflix',
|
||||
icon: 'netflix',
|
||||
url: 'https://netflix.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Office 365',
|
||||
icon: 'office365',
|
||||
url: 'https://office.com/',
|
||||
category: 'information'
|
||||
},
|
||||
{
|
||||
site: '4chan',
|
||||
icon: '4chan',
|
||||
url: 'https://4chan.org/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Discord',
|
||||
icon: 'discord',
|
||||
url: 'https://discord.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Spotify',
|
||||
icon: 'spotify',
|
||||
url: 'https://spotify.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Ebay',
|
||||
icon: 'ebay',
|
||||
url: 'https://ebay.com/',
|
||||
category: 'shop'
|
||||
},
|
||||
{
|
||||
site: 'JSFiddle',
|
||||
icon: 'jsfiddle',
|
||||
url: 'https://jsfiddle.net/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'ArchWiki',
|
||||
icon: 'archwiki',
|
||||
url: 'https://wiki.archlinux.org/',
|
||||
category: 'information'
|
||||
},
|
||||
{
|
||||
site: 'Figma',
|
||||
icon: 'figma',
|
||||
url: 'https://figma.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Stackoverflow',
|
||||
icon: 'stackoverflow',
|
||||
url: 'https://stackoverflow.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Stackexchange',
|
||||
icon: 'stackexchange',
|
||||
url: 'https://stackexchange.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Superuser',
|
||||
icon: 'superuser',
|
||||
url: 'https://superuser.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Calendar',
|
||||
icon: 'calendar',
|
||||
url: 'https://calendar.google.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Messenger',
|
||||
icon: 'messenger',
|
||||
url: 'https://messenger.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Icons8',
|
||||
icon: 'icons8',
|
||||
url: 'https://icons8.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Markdown Cheatsheet',
|
||||
icon: 'markdown',
|
||||
url: 'https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Interneting is Hard',
|
||||
icon: 'interneting-is-hard',
|
||||
url: 'https://internetingishard.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Keycode',
|
||||
icon: 'keycode',
|
||||
url: 'https://keycode.info/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Soundcloud',
|
||||
icon: 'soundcloud',
|
||||
url: 'https://soundcloud.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Amazon',
|
||||
icon: 'amazon',
|
||||
url: 'https://amazon.com/',
|
||||
category: 'shop'
|
||||
},
|
||||
{
|
||||
site: 'Flaticon',
|
||||
icon: 'flaticon',
|
||||
url: 'https://flaticon.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Wikimedia Commons',
|
||||
icon: 'commons',
|
||||
url: 'https://commons.wikimedia.org/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'MEGA',
|
||||
icon: 'mega',
|
||||
url: 'https://mega.nz/',
|
||||
category: 'cloud'
|
||||
},
|
||||
{
|
||||
site: 'MDN Web Docs',
|
||||
icon: 'mdn',
|
||||
url: 'https://developer.mozilla.org/',
|
||||
category: 'development'
|
||||
}
|
||||
];
|
||||
|
||||
return webSites;
|
||||
}
|
||||
|
||||
getDockSites = () => {
|
||||
// Dock
|
||||
// A list of websites that will be generated and put on the dock
|
||||
const dockSites = [
|
||||
{
|
||||
site: 'Reddit',
|
||||
icon: 'reddit',
|
||||
url: 'https://reddit.com/'
|
||||
},
|
||||
{
|
||||
site: 'Github',
|
||||
icon: 'github',
|
||||
url: 'https://github.com/'
|
||||
},
|
||||
{
|
||||
site: 'Facebook',
|
||||
icon: 'facebook',
|
||||
url: 'https://facebook.com/'
|
||||
},
|
||||
{
|
||||
site: 'Gmail',
|
||||
icon: 'gmail',
|
||||
url: 'https://mail.google.com/'
|
||||
},
|
||||
{
|
||||
site: 'Youtube',
|
||||
icon: 'youtube',
|
||||
url: 'https://youtube.com/'
|
||||
},
|
||||
{
|
||||
site: 'GDrive',
|
||||
icon: 'gdrive',
|
||||
url: 'https://drive.google.com/'
|
||||
},
|
||||
{
|
||||
site: 'Twitter',
|
||||
icon: 'twitter',
|
||||
url: 'https://twitter.com/'
|
||||
},
|
||||
{
|
||||
site: 'Material.io',
|
||||
icon: 'materialio',
|
||||
url: 'https://material.io/'
|
||||
}
|
||||
];
|
||||
|
||||
return dockSites;
|
||||
}
|
||||
}
|
114
js/dashboard.js
Normal file
114
js/dashboard.js
Normal file
@ -0,0 +1,114 @@
|
||||
class Dashboard {
|
||||
|
||||
constructor() {
|
||||
this._dashboard = document.querySelector('#rightDashboard');
|
||||
this._dashboardOverlay = document.querySelector('#dashboardOverlay');
|
||||
|
||||
this.rightDashboardVisibility = false;
|
||||
|
||||
this._dashboardOverlayMouseUpEvent = this._dashboardOverlayMouseUpEvent.bind(this);
|
||||
|
||||
this._centeredBox = document.querySelector('#centeredBox');
|
||||
this._webMenu = document.querySelector('#webMenu');
|
||||
this._searchBoxContainer = document.querySelector('#searchBoxContainer');
|
||||
this._weatherScreen = document.querySelector('#weatherScreen');
|
||||
|
||||
this._registerOverlayMouseUpEvent();
|
||||
}
|
||||
|
||||
_disableDashboardInputs = (status) => {
|
||||
const elems = this._dashboard.getElementsByTagName('input');
|
||||
const len = elems.length;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
elems[i].disabled = status;
|
||||
}
|
||||
}
|
||||
|
||||
getRightDashboardVisibility = () => {
|
||||
return this.rightDashboardVisibility;
|
||||
}
|
||||
|
||||
showDashboard = () => {
|
||||
this._dashboard.classList.add('showRightDashboard');
|
||||
|
||||
// Show overlay
|
||||
this._dashboardOverlay.classList.add('showDashboardOverlay');
|
||||
|
||||
// Enable Inputs
|
||||
this._disableDashboardInputs(false);
|
||||
|
||||
this.rightDashboardVisibility = !this.rightDashboardVisibility;
|
||||
}
|
||||
|
||||
hideDashboard = () => {
|
||||
this._dashboard.classList.remove('showRightDashboard');
|
||||
this._dashboard.scrollTop = 0;
|
||||
|
||||
// Disable Inputs
|
||||
this._disableDashboardInputs(true);
|
||||
|
||||
// Hide overlay
|
||||
this._dashboardOverlay.classList.remove('showDashboardOverlay');
|
||||
|
||||
this.rightDashboardVisibility = !this.rightDashboardVisibility;
|
||||
}
|
||||
|
||||
toggleDashboard = () => {
|
||||
|
||||
console.log('toggle dashboard');
|
||||
|
||||
if (this.rightDashboardVisibility) {
|
||||
|
||||
// Hide dashboard
|
||||
this.hideDashboard();
|
||||
|
||||
} else {
|
||||
|
||||
// Show dashboard
|
||||
this.showDashboard();
|
||||
|
||||
// If centered box is hidden, open it
|
||||
if (this._centeredBox.classList.contains('hiddenBox')) {
|
||||
|
||||
console.log('centered box is hidden, reopening...');
|
||||
|
||||
// Rotate profile container
|
||||
profileImage.rotateProfile();
|
||||
|
||||
// Toggle center box
|
||||
centeredBox.toggleCenteredBox();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any of these are open, if yes, close it
|
||||
if (this._searchBoxContainer.classList.contains('showSearchBox')) {
|
||||
console.log('searchbox is open, closing...');
|
||||
searchBoxShow.hideSearchBox();
|
||||
|
||||
} else if (this._webMenu.classList.contains('showWebMenu')) {
|
||||
console.log('web menu is open, closing...');
|
||||
webMenu.hideWebMenu();
|
||||
return;
|
||||
|
||||
} else if (this._weatherScreen.classList.contains('showWeatherScreen')) {
|
||||
console.log('weather screen is open, closing...');
|
||||
weatherScreen.hideWeatherScreen();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_dashboardOverlayMouseUpEvent = e => {
|
||||
if (this.rightDashboardVisibility) {
|
||||
this.toggleDashboard();
|
||||
}
|
||||
console.log('dashboard overlay clicked...');
|
||||
}
|
||||
|
||||
_registerOverlayMouseUpEvent = () => {
|
||||
this._dashboardOverlay.addEventListener('mouseup', this._dashboardOverlayMouseUpEvent);
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +1,124 @@
|
||||
let dock = document.getElementById('dock');
|
||||
|
||||
// Generate button from user
|
||||
const generateFromManual = (id, icon, callback) => {
|
||||
|
||||
let customButtonCallback;
|
||||
|
||||
const dockButton = document.createElement('div');
|
||||
dockButton.id = 'button' + id;
|
||||
dockButton.className = 'dockButton';
|
||||
class DockButtons {
|
||||
|
||||
dockButton.onmouseup = callback;
|
||||
|
||||
const buttonImage = document.createElement('div');
|
||||
buttonImage.id = 'buttonImage' + id;
|
||||
buttonImage.className = 'dockButtonImage';
|
||||
buttonImage.style.background = "url('assets/buttons/" + icon + ".svg')";
|
||||
buttonImage.style.backgroundSize = 'cover';
|
||||
constructor() {
|
||||
this._dock = document.querySelector('#dock');
|
||||
|
||||
// Retrieve dockSites object from Config instance
|
||||
this.dockSites = config.getDockSites();
|
||||
|
||||
// Populate dock
|
||||
this._populateDock();
|
||||
}
|
||||
|
||||
dockButton.appendChild(buttonImage);
|
||||
dock.appendChild(dockButton);
|
||||
}
|
||||
_buildDockButton = (id, className, callback = null) => {
|
||||
|
||||
|
||||
// Generate buttons from array
|
||||
const generateFromList = () => {
|
||||
|
||||
for (let i = 0; i < (dockSites.length); i++) {
|
||||
|
||||
const site = dockSites[i].site;
|
||||
const icon = dockSites[i].icon;
|
||||
const url = dockSites[i].url;
|
||||
|
||||
// Create a href
|
||||
const aDock = document.createElement('a');
|
||||
aDock.className = 'dockLink';
|
||||
aDock.href = url;
|
||||
|
||||
// Create div container
|
||||
const dockButton = document.createElement('div');
|
||||
dockButton.id = 'button' + i;
|
||||
dockButton.id = `button${id}`;
|
||||
dockButton.className = 'dockButton';
|
||||
dockButton.onmouseup = callback;
|
||||
|
||||
return dockButton;
|
||||
}
|
||||
|
||||
_buildDockButtonImage = (id, className, background) => {
|
||||
|
||||
// Create div container for button icon
|
||||
const buttonImage = document.createElement('div');
|
||||
buttonImage.id = 'buttonImage' + i;
|
||||
buttonImage.className = 'dockButtonImage';
|
||||
buttonImage.style.background = "url('assets/webcons/" + icon + ".svg')";
|
||||
buttonImage.id = id;
|
||||
buttonImage.className = className;
|
||||
buttonImage.style.background = background;
|
||||
buttonImage.style.backgroundSize = 'cover';
|
||||
|
||||
// Append divs
|
||||
dockButton.appendChild(buttonImage);
|
||||
aDock.appendChild(dockButton);
|
||||
dock.appendChild(aDock);
|
||||
};
|
||||
}
|
||||
|
||||
const populateDock = () => {
|
||||
|
||||
// Create launcher button
|
||||
generateFromManual(
|
||||
'Launch',
|
||||
'launch',
|
||||
() => {
|
||||
// Toggle web menu
|
||||
toggleWebMenu();
|
||||
}
|
||||
);
|
||||
return buttonImage;
|
||||
}
|
||||
|
||||
// Create dock buttons fetched from sites-list.js
|
||||
generateFromList();
|
||||
_generateFromManual = (id, icon, callback) => {
|
||||
|
||||
// Create weather button
|
||||
generateFromManual(
|
||||
'Weather',
|
||||
'weather',
|
||||
() => {
|
||||
// Toggle weather screen
|
||||
toggleWeatherScreen();
|
||||
}
|
||||
);
|
||||
const dockButton = this._buildDockButton(
|
||||
`button${id}`,
|
||||
'dockButton',
|
||||
callback
|
||||
);
|
||||
|
||||
// Create menu button
|
||||
generateFromManual(
|
||||
'Dashboard',
|
||||
'dashboard',
|
||||
() => {
|
||||
// Toggle dashboard
|
||||
toggleDashboard();
|
||||
}
|
||||
);
|
||||
const buttonImage = this._buildDockButtonImage(
|
||||
`buttonImage${id}`,
|
||||
'dockButtonImage',
|
||||
`url('assets/buttons/${icon}.svg')`
|
||||
);
|
||||
|
||||
dockButton.appendChild(buttonImage);
|
||||
|
||||
this._dock.appendChild(dockButton);
|
||||
}
|
||||
|
||||
_generateFromList = () => {
|
||||
|
||||
for (let i = 0; i < (this.dockSites.length); i++) {
|
||||
|
||||
const site = this.dockSites[i].site;
|
||||
const icon = this.dockSites[i].icon;
|
||||
const url = this.dockSites[i].url;
|
||||
|
||||
// Create a href
|
||||
const aDock = document.createElement('a');
|
||||
aDock.className = 'dockLink';
|
||||
aDock.href = url;
|
||||
|
||||
// Create div container
|
||||
const dockButton = this._buildDockButton(
|
||||
site,
|
||||
'dockButton'
|
||||
);
|
||||
|
||||
// Create div container for button icon
|
||||
const buttonImage = this._buildDockButtonImage(
|
||||
`buttonImage${i}`,
|
||||
'dockButtonImage',
|
||||
`url('assets/webcons/${icon}.svg')`
|
||||
);
|
||||
|
||||
// Append divs
|
||||
dockButton.appendChild(buttonImage);
|
||||
aDock.appendChild(dockButton);
|
||||
|
||||
this._dock.appendChild(aDock);
|
||||
};
|
||||
}
|
||||
|
||||
_populateDock = () => {
|
||||
|
||||
// Create launcher button
|
||||
this._generateFromManual(
|
||||
'Launch',
|
||||
'launch',
|
||||
() => {
|
||||
// Toggle web menu
|
||||
webMenu.toggleWebMenu();
|
||||
}
|
||||
);
|
||||
|
||||
// Create dock buttons fetched from sites-list.js
|
||||
this._generateFromList();
|
||||
|
||||
// Create weather button
|
||||
this._generateFromManual(
|
||||
'Weather',
|
||||
'weather',
|
||||
() => {
|
||||
// Toggle weather screen
|
||||
weatherScreen.toggleWeatherScreen();
|
||||
}
|
||||
);
|
||||
|
||||
// Create menu button
|
||||
this._generateFromManual(
|
||||
'Dashboard',
|
||||
'dashboard',
|
||||
() => {
|
||||
// Toggle dashboard
|
||||
dashboard.toggleDashboard();
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Populate dock
|
||||
window.onload = populateDock();
|
||||
|
||||
|
@ -1,53 +1,67 @@
|
||||
const greeterMessage = document.getElementById("greeterMessage");
|
||||
const dateMessage = document.getElementById("dateMessage");
|
||||
|
||||
const date = new Date();
|
||||
const hour = date.getHours();
|
||||
let greeterSuffix;
|
||||
class GreeterDateMessage {
|
||||
constructor() {
|
||||
this._greeterMessage = document.querySelector('#greeterMessage');
|
||||
this._dateMessage = document.querySelector('#dateMessage');
|
||||
|
||||
const monthsArr = [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
];
|
||||
|
||||
const daysArr = [
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday"
|
||||
]
|
||||
|
||||
const getDayOrdinal = (day) => {
|
||||
return day + (day > 0 ? ['th', 'st', 'nd', 'rd'][(day > 3 && day < 21) ||
|
||||
day % 10 > 3 ? 0 : day % 10] : '');
|
||||
}
|
||||
|
||||
const updateGreeterDateMessage = () => {
|
||||
if (hour >= 6 && hour < 12) {
|
||||
greeterSuffix = "Morning";
|
||||
} else if (hour >= 12 && hour < 18) {
|
||||
greeterSuffix = "Afternoon";
|
||||
} else {
|
||||
greeterSuffix = "Evening";
|
||||
this._updateGreeterDateMessage();
|
||||
}
|
||||
|
||||
greeterMessage.innerHTML = "Good" + "<br>" + greeterSuffix + "!";
|
||||
_getMonths = () => {
|
||||
const monthsArr = [
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December'
|
||||
];
|
||||
return monthsArr;
|
||||
}
|
||||
|
||||
dateMessage.innerHTML = "Today is the " + getDayOrdinal(date.getDate()) +
|
||||
" of " + monthsArr[date.getMonth()] + ", and it's " + daysArr[date.getDay()] + ".";
|
||||
}
|
||||
_getDays = () => {
|
||||
const _daysArr = [
|
||||
'Sunday',
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
'Wednesday',
|
||||
'Thursday',
|
||||
'Friday',
|
||||
'Saturday'
|
||||
];
|
||||
return _daysArr;
|
||||
}
|
||||
|
||||
window.onload = updateGreeterDateMessage();
|
||||
_getDayOrdinal = (day) => {
|
||||
return day + (day > 0 ? ['th', 'st', 'nd', 'rd'][(day > 3 && day < 21) ||
|
||||
day % 10 > 3 ? 0 : day % 10] : '');
|
||||
}
|
||||
|
||||
_updateGreeterDateMessage = () => {
|
||||
|
||||
const date = new Date();
|
||||
const hour = date.getHours();
|
||||
let greeterSuffix = '';
|
||||
|
||||
if (hour >= 6 && hour < 12) {
|
||||
greeterSuffix = 'Morning';
|
||||
|
||||
} else if (hour >= 12 && hour < 18) {
|
||||
greeterSuffix = 'Afternoon';
|
||||
|
||||
} else {
|
||||
greeterSuffix = 'Evening';
|
||||
}
|
||||
|
||||
this._greeterMessage.innerHTML = `Good<br>${greeterSuffix}!`;
|
||||
this._dateMessage.innerHTML = `Today's the ${this._getDayOrdinal(date.getDate())} of ` +
|
||||
`${this._getMonths()[date.getMonth()]}, and it's ${this._getDays()[date.getDay()]}.`;
|
||||
}
|
||||
|
||||
}
|
@ -1,81 +1,109 @@
|
||||
let keysPressed = {};
|
||||
class KeyBinding {
|
||||
|
||||
document.addEventListener(
|
||||
'keydown',
|
||||
(event) => {
|
||||
|
||||
keysPressed[event.key] = true;
|
||||
constructor() {
|
||||
|
||||
// Open dashboard
|
||||
if (keysPressed['Alt'] && event.key === 's') {
|
||||
event.preventDefault();
|
||||
toggleDashboard();
|
||||
this._searchBox = document.querySelector('#searchBox');
|
||||
|
||||
this._keysPressed = {};
|
||||
|
||||
this._documentAddKeyDownEvent = this._documentAddKeyDownEvent.bind(this);
|
||||
this._documentAddKeyUpEvent = this._documentAddKeyUpEvent.bind(this);
|
||||
|
||||
this._registerDocumentAddKeyDownEvent();
|
||||
this._registerDocumentAddKeyUpEvent();
|
||||
}
|
||||
|
||||
_documentAddKeyDownEvent = e => {
|
||||
|
||||
const searchBoxVisibility = searchBoxShow.getSearchBoxVisibility();
|
||||
|
||||
this._keysPressed[e.key] = true;
|
||||
|
||||
|
||||
if (this._keysPressed['Alt'] && e.key === 's') {
|
||||
|
||||
e.preventDefault();
|
||||
dashboard.toggleDashboard();
|
||||
return;
|
||||
} else if (keysPressed['Alt'] && event.key === 'e') {
|
||||
event.preventDefault();
|
||||
toggleWebMenu();
|
||||
|
||||
} else if (this._keysPressed['Alt'] && e.key === 'e') {
|
||||
|
||||
e.preventDefault();
|
||||
webMenu.toggleWebMenu();
|
||||
return;
|
||||
} else if (keysPressed['Alt'] && event.key === 'x') {
|
||||
event.preventDefault();
|
||||
toggleWeatherScreen();
|
||||
|
||||
} else if (this._keysPressed['Alt'] && e.key === 'x') {
|
||||
|
||||
e.preventDefault();
|
||||
weatherScreen.toggleWeatherScreen();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (event.key === 'Escape') {
|
||||
if (e.key === 'Escape') {
|
||||
|
||||
event.preventDefault();
|
||||
e.preventDefault();
|
||||
|
||||
// If any of this are open, close it
|
||||
if (searchBoxVisility) {
|
||||
if (searchBoxVisibility) {
|
||||
|
||||
// Hide searchbox
|
||||
toggleSearchBox();
|
||||
searchBox.value = '';
|
||||
searchBoxShow.toggleSearchBox();
|
||||
this._searchBox.value = '';
|
||||
return;
|
||||
|
||||
} else if (weatherScreenVisibility) {
|
||||
} else if (dashboard.getRightDashboardVisibility()) {
|
||||
|
||||
toggleWeatherScreen();
|
||||
// Hide dashboard
|
||||
dashboard.toggleDashboard();
|
||||
return;
|
||||
|
||||
} else if (weatherScreen.getWeatherScreenVisiblity()) {
|
||||
|
||||
// Hide weather
|
||||
weatherScreen.toggleWeatherScreen();
|
||||
return;
|
||||
|
||||
} else if (rightDashboardVisibility) {
|
||||
|
||||
toggleDashboard();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Show web menu
|
||||
toggleWebMenu();
|
||||
webMenu.toggleWebMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchBoxVisility === false) {
|
||||
if (searchBoxVisibility === false) {
|
||||
|
||||
// Don't show searchbox when web menu, dashboard
|
||||
// and weather screen is open
|
||||
if (webMenuVisibility || weatherScreenVisibility ||
|
||||
rightDashboardVisibility) return;
|
||||
if (dashboard.getRightDashboardVisibility() ||
|
||||
webMenu.getwebMenuVisibility() ||
|
||||
weatherScreen.getWeatherScreenVisiblity()) return;
|
||||
|
||||
// Only accept single charactered key and backspace to open search box
|
||||
if ((event.key.length > 1) && (event.key !== 'Backspace')) return;
|
||||
if ((e.key.length > 1) && (e.key !== 'Backspace')) return;
|
||||
|
||||
// Open searchbox
|
||||
toggleSearchBox();
|
||||
searchBoxShow.toggleSearchBox();
|
||||
|
||||
} else {
|
||||
|
||||
// Backspacing while there's no search query will hide searhbox
|
||||
// Will also hide if you hit enter
|
||||
if ((event.key === 'Backspace' || event.key === 'Enter') &&
|
||||
searchBox.value < 1) { toggleSearchBox(); return; };
|
||||
if ((e.key === 'Backspace' || e.key === 'Enter') &&
|
||||
this._searchBox.value < 1) { searchBoxShow.toggleSearchBox(); return; };
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'keyup',
|
||||
(event) => {
|
||||
delete keysPressed[event.key];
|
||||
}
|
||||
);
|
||||
|
||||
_documentAddKeyUpEvent = e => {
|
||||
delete this._keysPressed[e.key];
|
||||
}
|
||||
|
||||
_registerDocumentAddKeyDownEvent = () => {
|
||||
document.addEventListener('keydown', this._documentAddKeyDownEvent);
|
||||
}
|
||||
|
||||
_registerDocumentAddKeyUpEvent = () => {
|
||||
document.addEventListener('keyup', this._documentAddKeyUpEvent);
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +1,80 @@
|
||||
// Swipe Callbacks
|
||||
class SwipeEventCallbacks extends SwipeEventManager {
|
||||
constructor() {
|
||||
super();
|
||||
this.swipeEvent = this.swipeEvent;
|
||||
|
||||
// Backgound body swipe callback
|
||||
const bodyBackgroundSwipeEvent = (el, d) => {
|
||||
this._createSwipeEvents();
|
||||
}
|
||||
|
||||
// Swipe left will open dashboard
|
||||
if (d === 'left') {
|
||||
toggleDashboard();
|
||||
} else if (d === 'down') {
|
||||
// Swiping down will open search box
|
||||
toggleSearchBox();
|
||||
} else if (d == 'right') {
|
||||
// Swiping right will open web menu
|
||||
toggleWebMenu();
|
||||
} else if (d == 'up') {
|
||||
// Swiping up will open weather screen
|
||||
toggleWeatherScreen();
|
||||
// Backgound body swipe callback
|
||||
_bodyBackgroundSwipeEvent = (el, d) => {
|
||||
|
||||
// Swipe left will open dashboard
|
||||
if (d === 'left') {
|
||||
dashboard.toggleDashboard();
|
||||
} else if (d === 'down') {
|
||||
// Swiping down will open search box
|
||||
searchBoxShow.toggleSearchBox();
|
||||
} else if (d == 'right') {
|
||||
// Swiping right will open web menu
|
||||
webMenu.toggleWebMenu();
|
||||
} else if (d == 'up') {
|
||||
// Swiping up will open weather screen
|
||||
weatherScreen.toggleWeatherScreen();
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard swipe callback
|
||||
_rightDashboardSwipeEvent = (el, d) => {
|
||||
|
||||
// Swipe right will close dashboard
|
||||
if (d === "right") {
|
||||
dashboard.toggleDashboard();
|
||||
}
|
||||
}
|
||||
|
||||
// Blur overlay swipe event
|
||||
_centeredBoxOverlaySwipeEvent = (el, d) => {
|
||||
|
||||
// Swiping up will close search box
|
||||
if (d === 'up') {
|
||||
searchBoxShow.toggleSearchBox();
|
||||
}
|
||||
}
|
||||
|
||||
// Web menu swipe event
|
||||
_webMenuSwipeEvent = (el, d) => {
|
||||
|
||||
// Swiping left will close web menu
|
||||
if (d == 'left') {
|
||||
webMenu.toggleWebMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// Weather screen swipe event
|
||||
_weatherScreenSwipeEvent = (el, d) => {
|
||||
|
||||
// Swiping left will the weather screem
|
||||
if (d == 'left') {
|
||||
weatherScreen.toggleWeatherScreen();
|
||||
}
|
||||
}
|
||||
|
||||
// Assign swipe callback for each IDs
|
||||
_createSwipeEvents = () => {
|
||||
this.swipeEvent('bodyBackground', this._bodyBackgroundSwipeEvent);
|
||||
|
||||
this.swipeEvent('rightDashboard', this._rightDashboardSwipeEvent);
|
||||
|
||||
this.swipeEvent('centeredBoxOverlay', this._centeredBoxOverlaySwipeEvent);
|
||||
|
||||
this.swipeEvent('webMenu', this._webMenuSwipeEvent);
|
||||
|
||||
this.swipeEvent('weatherScreen', this._weatherScreenSwipeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard swipe callback
|
||||
const rightDashboardSwipeEvent = (el, d) => {
|
||||
|
||||
// Swipe right will close dashboard
|
||||
if (d === "right") {
|
||||
toggleDashboard();
|
||||
}
|
||||
}
|
||||
|
||||
// Blur overlay swipe event
|
||||
const centeredBoxOverlaySwipeEvent = (el, d) => {
|
||||
|
||||
// Swiping up will close search box
|
||||
if (d === 'up') {
|
||||
toggleSearchBox();
|
||||
}
|
||||
}
|
||||
|
||||
// Web menu swipe event
|
||||
const webMenuSwipeEvent = (el, d) => {
|
||||
|
||||
// Swiping left will close web menu
|
||||
if (d == 'left') {
|
||||
toggleWebMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// Weather screen swipe event
|
||||
const weatherScreenSwipeEvent = (el, d) => {
|
||||
|
||||
// Swiping left will the weather screem
|
||||
if (d == 'left') {
|
||||
toggleWeatherScreen();
|
||||
}
|
||||
}
|
||||
|
||||
swipeEvent('bodyBackground', bodyBackgroundSwipeEvent);
|
||||
|
||||
swipeEvent('rightDashboard', rightDashboardSwipeEvent);
|
||||
|
||||
swipeEvent('centeredBoxOverlay', centeredBoxOverlaySwipeEvent);
|
||||
|
||||
swipeEvent('webMenu', webMenuSwipeEvent);
|
||||
|
||||
swipeEvent('weatherScreen', weatherScreenSwipeEvent);
|
@ -1,61 +1,71 @@
|
||||
const swipeEvent = (elementID, callback) => {
|
||||
class SwipeEventManager {
|
||||
|
||||
const el = document.getElementById(elementID);
|
||||
let dir;
|
||||
constructor() {
|
||||
this.swipeEvent = this.swipeEvent.bind(this);
|
||||
|
||||
el.addEventListener(
|
||||
'touchstart',
|
||||
(event) => {
|
||||
// event.preventDefault();
|
||||
xDown = event.touches[0].clientX;
|
||||
yDown = event.touches[0].clientY;
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
this._xDown = null;
|
||||
this._yDown = null;
|
||||
}
|
||||
|
||||
el.addEventListener(
|
||||
'touchmove',
|
||||
(event) => {
|
||||
// event.preventDefault();
|
||||
if ( ! xDown || ! yDown ) {
|
||||
return;
|
||||
}
|
||||
swipeEvent = (elementID, callback) => {
|
||||
|
||||
const xUp = event.touches[0].clientX;
|
||||
const yUp = event.touches[0].clientY;
|
||||
const xDiff = xDown - xUp;
|
||||
const yDiff = yDown - yUp;
|
||||
const el = document.getElementById(elementID);
|
||||
let dir;
|
||||
|
||||
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
|
||||
if ( xDiff > 0 ) {
|
||||
// Left Swipe
|
||||
dir = 'left'
|
||||
} else {
|
||||
// Right Swipe
|
||||
dir = 'right';
|
||||
}
|
||||
} else {
|
||||
el.addEventListener(
|
||||
'touchstart',
|
||||
(event) => {
|
||||
// event.preventDefault();
|
||||
this._xDown = event.touches[0].clientX;
|
||||
this._yDown = event.touches[0].clientY;
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
|
||||
if ( yDiff > 0 ) {
|
||||
// Up Swipe
|
||||
dir = 'up';
|
||||
} else {
|
||||
// Down Swipe
|
||||
dir = 'down';
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset values */
|
||||
xDown = null;
|
||||
yDown = null;
|
||||
|
||||
if (dir !== ""){
|
||||
if (typeof callback == "function") {
|
||||
callback(el, dir);
|
||||
el.addEventListener(
|
||||
'touchmove',
|
||||
(event) => {
|
||||
// event.preventDefault();
|
||||
if ( ! this._xDown || ! this._yDown ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
}
|
||||
const xUp = event.touches[0].clientX;
|
||||
const yUp = event.touches[0].clientY;
|
||||
const xDiff = this._xDown - xUp;
|
||||
const yDiff = this._yDown - yUp;
|
||||
|
||||
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
|
||||
if ( xDiff > 0 ) {
|
||||
// Left Swipe
|
||||
dir = 'left'
|
||||
} else {
|
||||
// Right Swipe
|
||||
dir = 'right';
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( yDiff > 0 ) {
|
||||
// Up Swipe
|
||||
dir = 'up';
|
||||
} else {
|
||||
// Down Swipe
|
||||
dir = 'down';
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset values */
|
||||
this._xDown = null;
|
||||
this._yDown = null;
|
||||
|
||||
if (dir !== ''){
|
||||
if (typeof callback == 'function') {
|
||||
callback(el, dir);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
63
js/profile-image.js
Normal file
63
js/profile-image.js
Normal file
@ -0,0 +1,63 @@
|
||||
class ProfileImage {
|
||||
|
||||
constructor() {
|
||||
this._profileContainer = document.querySelector('#profileImageContainer')
|
||||
|
||||
this._profileAnimRunning = false;
|
||||
|
||||
// Don't run animation on startup
|
||||
this._profileContainer.style.webkitAnimationPlayState = 'paused';
|
||||
|
||||
this.rotateProfile = this.rotateProfile.bind(this);
|
||||
|
||||
this._animationEndEvent = this._animationEndEvent.bind(this);
|
||||
this._onClickEvent = this._onClickEvent.bind(this);
|
||||
|
||||
this.getProfileAnimationStatus = this.getProfileAnimationStatus.bind(this);
|
||||
|
||||
this._registerAnimationEndEvent();
|
||||
this._registerOnClickEvent();
|
||||
}
|
||||
|
||||
rotateProfile = () => {
|
||||
event.preventDefault;
|
||||
|
||||
// Remove anim class
|
||||
this._profileContainer.classList.remove('rotateProfileAnim');
|
||||
|
||||
// Triggering reflow
|
||||
void this._profileContainer.offsetWidth;
|
||||
|
||||
// Re-add animation class
|
||||
this._profileContainer.classList.add('rotateProfileAnim');
|
||||
|
||||
// Start rotation animation
|
||||
this._profileContainer.style.webkitAnimationPlayState = 'running';
|
||||
this._profileAnimRunning = true;
|
||||
}
|
||||
|
||||
_animationEndEvent = e => {
|
||||
this._profileAnimRunning = false;
|
||||
}
|
||||
|
||||
// Re-enable animation after death
|
||||
_registerAnimationEndEvent = () => {
|
||||
this._profileContainer.addEventListener('animationend', this._animationEndEvent);
|
||||
}
|
||||
|
||||
_onClickEvent = e => {
|
||||
if (this._profileAnimRunning) return;
|
||||
searchBoxShow.toggleSearchBox();
|
||||
}
|
||||
|
||||
_registerOnClickEvent = () => {
|
||||
this._profileContainer.onclick = this._onClickEvent;
|
||||
}
|
||||
|
||||
getProfileAnimationStatus = () => {
|
||||
return this._profileAnimRunning;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
56
js/script.js
Normal file
56
js/script.js
Normal file
@ -0,0 +1,56 @@
|
||||
// Instantiate config
|
||||
const config = new Config();
|
||||
|
||||
// Instantiate background setter
|
||||
const bodyBackground = new BodyBackground();
|
||||
|
||||
// Instantiate a clock object
|
||||
const clock = new Clock();
|
||||
|
||||
// Instantiate dock buttons
|
||||
const dockButtons = new DockButtons();
|
||||
|
||||
// Instantiate profile image/animation
|
||||
const profileImage = new ProfileImage();
|
||||
|
||||
// Instantiate searchbox events
|
||||
const searchBoxShow = new SearchBoxShow();
|
||||
|
||||
// Instantiate autosuggestion
|
||||
const autoSuggestion = new AutoSuggestion();
|
||||
|
||||
// Instantiate search engine settings
|
||||
const searchEngineSettings = new SearchEngineSettings();
|
||||
|
||||
// Instantiate center box
|
||||
const centeredBox = new CenteredBox();
|
||||
|
||||
// Instantiate web menu
|
||||
const webMenu = new WebMenu();
|
||||
|
||||
// Instantiate weather screen
|
||||
const weatherScreen = new WeatherScreen();
|
||||
|
||||
// Instantiate weather settings
|
||||
const weatherSettings = new WeatherSettings();
|
||||
|
||||
// Instantiate greeter message
|
||||
const greeter = new GreeterDateMessage();
|
||||
|
||||
// Instantiate search send
|
||||
const searchQuerySend = new SearchQuerySend();
|
||||
|
||||
// Instantiate theme engine
|
||||
const themeEngine = new ThemeEngine();
|
||||
|
||||
// Instantiate dasbhoard
|
||||
const dashboard = new Dashboard();
|
||||
|
||||
// Instantiate keybindings
|
||||
const keyBindings = new KeyBinding();
|
||||
|
||||
// Instantiate swipe event
|
||||
const swipeEventManager = new SwipeEventManager();
|
||||
|
||||
// Intantiate swipe event callbacks
|
||||
const swipeEventCallbacks = new SwipeEventCallbacks();
|
@ -1,69 +1,90 @@
|
||||
var localStorage = window.localStorage;
|
||||
class SearchEngineSettings {
|
||||
|
||||
var searchBox = document.getElementById("searchBox");
|
||||
const selectEngine = document.getElementById("searchEngineSelect");
|
||||
const searchEngineAsDefault = document.getElementById("searchEngineAsDefault");
|
||||
constructor() {
|
||||
this._localStorage = window.localStorage;
|
||||
|
||||
// Get default search engine
|
||||
let defaultEngine = localStorage.getItem('searchEngine') || 'google';
|
||||
this._searchBox = document.querySelector('#searchBox');
|
||||
this._selectSearchEngine = document.querySelector('#searchEngineSelect');
|
||||
this._selectSearchEngineApply = document.querySelector('#searchEngineAsDefault');
|
||||
|
||||
this._defaultSearchEngine = this._localStorage.getItem('searchEngine') || 'google';
|
||||
this._placeholderPrefix = ' Search with ';
|
||||
this._searchQueryPrefix = 'http://www.google.com/search?q=';
|
||||
|
||||
let searchQueryPrefix;
|
||||
this._onClickEvent = this._onClickEvent.bind(this);
|
||||
this._onChangeEvent = this._onChangeEvent.bind(this);
|
||||
|
||||
const placeholderPrefix = " Search with ";
|
||||
|
||||
// Update query string and placeholder
|
||||
const selectQueryString = () => {
|
||||
|
||||
if (defaultEngine === "google") {
|
||||
searchQueryPrefix = 'http://www.google.com/search?q=';
|
||||
searchBox.placeholder = placeholderPrefix + "Google";
|
||||
|
||||
} else if (defaultEngine === "duckduckgo") {
|
||||
searchQueryPrefix = 'https://duckduckgo.com/?q=';
|
||||
searchBox.placeholder = placeholderPrefix + "Duckduckgo";
|
||||
|
||||
} else if (defaultEngine === "ecosia") {
|
||||
searchQueryPrefix = 'https://www.ecosia.org/search?q=';
|
||||
searchBox.placeholder = placeholderPrefix + "Ecosia";
|
||||
|
||||
} else if (defaultEngine === "yahoo") {
|
||||
searchQueryPrefix = 'http://search.yahoo.com/search?p=';
|
||||
searchBox.placeholder = placeholderPrefix + "Yahoo";
|
||||
|
||||
} else if (defaultEngine === "bing") {
|
||||
searchQueryPrefix = 'https://www.bing.com/search?q=';
|
||||
searchBox.placeholder = placeholderPrefix + "Bing";
|
||||
|
||||
} else {
|
||||
searchQueryPrefix = 'http://www.google.com/search?q=';
|
||||
searchBox.placeholder = placeholderPrefix + "Google";
|
||||
this._init();
|
||||
}
|
||||
|
||||
}
|
||||
_init = () => {
|
||||
this._selectQueryString();
|
||||
this._selectTheEngine();
|
||||
this._registerOnChangeEvent();
|
||||
this._registerOnClickEvent();
|
||||
}
|
||||
|
||||
// Use this to select the default search engine on startup
|
||||
const selectTheEngine = () => {
|
||||
// Available values: google, duckduckgo, ecosia, etc.
|
||||
selectEngine.value = defaultEngine;
|
||||
selectQueryString();
|
||||
}
|
||||
// Update query string and placeholder
|
||||
_selectQueryString = () => {
|
||||
|
||||
// Update settings if the value changes
|
||||
selectEngine.onchange = () => {
|
||||
// Get Value
|
||||
const selectedEngine = selectEngine.options[selectEngine.selectedIndex].value;
|
||||
defaultEngine = selectedEngine;
|
||||
selectTheEngine()
|
||||
}
|
||||
if (this._defaultSearchEngine === 'google') {
|
||||
this._searchQueryPrefix = 'http://www.google.com/search?q=';
|
||||
this._searchBox.placeholder = this._placeholderPrefix + 'Google';
|
||||
|
||||
searchEngineAsDefault.onclick = () => {
|
||||
const selectCurrentIndex = selectEngine.options[selectEngine.selectedIndex]
|
||||
alert('Success! ' + selectCurrentIndex.text +
|
||||
' is now your default search engine!');
|
||||
} else if (this._defaultSearchEngine === 'duckduckgo') {
|
||||
this._searchQueryPrefix = 'https://duckduckgo.com/?q=';
|
||||
this._searchBox.placeholder = this._placeholderPrefix + 'Duckduckgo';
|
||||
|
||||
// Save search engine
|
||||
localStorage.setItem('searchEngine', selectCurrentIndex.value);
|
||||
}
|
||||
} else if (this._defaultSearchEngine === 'ecosia') {
|
||||
this._searchQueryPrefix = 'https://www.ecosia.org/search?q=';
|
||||
this._searchBox.placeholder = this._placeholderPrefix + 'Ecosia';
|
||||
|
||||
// Initialize
|
||||
window.onload = selectTheEngine();
|
||||
} else if (this._defaultSearchEngine === 'yahoo') {
|
||||
this._searchQueryPrefix = 'http://search.yahoo.com/search?p=';
|
||||
this._searchBox.placeholder = this._placeholderPrefix + 'Yahoo';
|
||||
|
||||
} else if (this._defaultSearchEngine === 'bing') {
|
||||
this._searchQueryPrefix = 'https://www.bing.com/search?q=';
|
||||
this._searchBox.placeholder = this._placeholderPrefix + 'Bing';
|
||||
|
||||
} else {
|
||||
this._searchQueryPrefix = 'http://www.google.com/search?q=';
|
||||
this._searchBox.placeholder = this._placeholderPrefix + 'Google';
|
||||
}
|
||||
}
|
||||
|
||||
_getSearchQueryPrefix = () => {
|
||||
return this._searchQueryPrefix;
|
||||
}
|
||||
|
||||
// Use this to select the default search engine on startup
|
||||
_selectTheEngine = () => {
|
||||
// Available values: google, duckduckgo, ecosia, etc.
|
||||
this._selectSearchEngine.value = this._defaultSearchEngine;
|
||||
this._selectQueryString();
|
||||
}
|
||||
|
||||
_onChangeEvent = e => {
|
||||
const selectedEngine = this._selectSearchEngine.options[this._selectSearchEngine.selectedIndex].value;
|
||||
this._defaultSearchEngine = selectedEngine;
|
||||
this._selectTheEngine()
|
||||
}
|
||||
|
||||
_registerOnChangeEvent = () => {
|
||||
this._selectSearchEngine.onchange = this._onChangeEvent;
|
||||
}
|
||||
|
||||
_onClickEvent = e => {
|
||||
const selectCurrentIndex = this._selectSearchEngine.options[this._selectSearchEngine.selectedIndex]
|
||||
alert('Success! ' + selectCurrentIndex.text +
|
||||
' is now your default search engine!');
|
||||
|
||||
// Save search engine
|
||||
this._localStorage.setItem('searchEngine', selectCurrentIndex.value);
|
||||
}
|
||||
|
||||
_registerOnClickEvent = () => {
|
||||
this._selectSearchEngineApply.onclick = this._onClickEvent;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +1,18 @@
|
||||
// Search box
|
||||
var searchBox = document.getElementById("searchBox");
|
||||
class SearchQuerySend extends SearchEngineSettings {
|
||||
|
||||
// Web Search
|
||||
const webSearch = () => {
|
||||
// Search
|
||||
window.location.href = encodeURI(searchQueryPrefix + searchBox.value);
|
||||
};
|
||||
constructor() {
|
||||
super();
|
||||
this._searchBox = document.querySelector('#searchBox');
|
||||
this._keyUpEvent = this._keyUpEvent.bind(this);
|
||||
this._registerKeyUpEvent();
|
||||
}
|
||||
|
||||
// Key release event
|
||||
searchBox.addEventListener(
|
||||
"keyup",
|
||||
(event) => {
|
||||
|
||||
_sendQuery = () => {
|
||||
// Search
|
||||
window.location.href = encodeURI(this._getSearchQueryPrefix() + this._searchBox.value);
|
||||
};
|
||||
|
||||
_keyUpEvent = event => {
|
||||
if (event.key === 'Tab') return;
|
||||
|
||||
// Number 13 is the "Enter" key on the keyboard
|
||||
@ -26,8 +27,11 @@ searchBox.addEventListener(
|
||||
event.preventDefault();
|
||||
|
||||
// Search the web
|
||||
webSearch()
|
||||
this._sendQuery()
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
_registerKeyUpEvent = () => {
|
||||
this._searchBox.addEventListener('keyup', this._keyUpEvent);
|
||||
}
|
||||
}
|
||||
|
@ -1,52 +1,69 @@
|
||||
var searchBox = document.getElementById('searchBox');
|
||||
const searchBoxContainer = document.getElementById('searchBoxContainer');
|
||||
const centeredBoxOverlay = document.getElementById('centeredBoxOverlay');
|
||||
class SearchBoxShow {
|
||||
constructor() {
|
||||
|
||||
let searchBoxVisility = false;
|
||||
this._searchBox = document.querySelector('#searchBox');
|
||||
this._searchBoxContainer = document.querySelector('#searchBoxContainer');
|
||||
this._centeredBoxOverlay = document.querySelector('#centeredBoxOverlay');
|
||||
|
||||
const showSearchBox = () => {
|
||||
searchBoxContainer.classList.add('showSearchBox');
|
||||
this._searchBoxVisility = false;
|
||||
|
||||
// Focus
|
||||
searchBox.focus();
|
||||
|
||||
searchBoxVisility = !searchBoxVisility;
|
||||
|
||||
// Toggle overlay
|
||||
centeredBoxOverlay.classList.toggle('showOverlay');
|
||||
}
|
||||
|
||||
const hideSearchBox = () => {
|
||||
searchBoxContainer.classList.remove('showSearchBox');
|
||||
|
||||
// Toggle overlay
|
||||
centeredBoxOverlay.classList.toggle('showOverlay');
|
||||
|
||||
searchBox.value = '';
|
||||
|
||||
// Hide suggestions
|
||||
hideSuggestions();
|
||||
|
||||
searchBoxVisility = !searchBoxVisility;
|
||||
}
|
||||
|
||||
const toggleSearchBox = () => {
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileAnimRunning) return;
|
||||
|
||||
// Rotate profile
|
||||
rotateProfile();
|
||||
|
||||
if (searchBoxVisility) {
|
||||
// Hide search box
|
||||
hideSearchBox();
|
||||
|
||||
} else {
|
||||
// Show search box
|
||||
showSearchBox();
|
||||
this.showSearchBox = this.showSearchBox.bind(this);
|
||||
this.hideSearchBox = this.hideSearchBox.bind(this);
|
||||
this.toggleSearchBox = this.toggleSearchBox.bind(this);
|
||||
|
||||
}
|
||||
|
||||
console.log('toggle searchbox');
|
||||
}
|
||||
getSearchBoxVisibility = () => {
|
||||
return this._searchBoxVisility;
|
||||
}
|
||||
|
||||
showSearchBox = () => {
|
||||
this._searchBoxContainer.classList.add('showSearchBox');
|
||||
|
||||
// Focus
|
||||
this._searchBox.focus();
|
||||
|
||||
this._searchBoxVisility = !this._searchBoxVisility;
|
||||
|
||||
// Toggle overlay
|
||||
this._centeredBoxOverlay.classList.toggle('showOverlay');
|
||||
}
|
||||
|
||||
hideSearchBox = () => {
|
||||
this._searchBoxContainer.classList.remove('showSearchBox');
|
||||
|
||||
// Toggle overlay
|
||||
this._centeredBoxOverlay.classList.toggle('showOverlay');
|
||||
|
||||
this._searchBox.value = '';
|
||||
|
||||
// Hide suggestions
|
||||
console.warn('hideSuggestions()');
|
||||
|
||||
this._searchBoxVisility = !this._searchBoxVisility;
|
||||
}
|
||||
|
||||
toggleSearchBox = () => {
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileImage.getProfileAnimationStatus()) return;
|
||||
|
||||
// Rotate profile
|
||||
profileImage.rotateProfile();
|
||||
|
||||
if (this._searchBoxVisility) {
|
||||
// Hide search box
|
||||
this.hideSearchBox();
|
||||
|
||||
} else {
|
||||
// Show search box
|
||||
this.showSearchBox();
|
||||
}
|
||||
|
||||
console.log('toggle searchbox');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
309
js/sites-list.js
309
js/sites-list.js
@ -1,309 +0,0 @@
|
||||
// You can easily add data here and it will be auto generated
|
||||
|
||||
// Web menu
|
||||
// A list of websites that will be generated and put on the web menu
|
||||
const webSites = [
|
||||
{
|
||||
site: 'Reddit',
|
||||
icon: 'reddit',
|
||||
url: 'https://reddit.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Github',
|
||||
icon: 'github',
|
||||
url: 'https://github.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Facebook',
|
||||
icon: 'facebook',
|
||||
url: 'https://facebook.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Gmail',
|
||||
icon: 'gmail',
|
||||
url: 'https://mail.google.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Youtube',
|
||||
icon: 'youtube',
|
||||
url: 'https://youtube.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'GDrive',
|
||||
icon: 'gdrive',
|
||||
url: 'https://drive.google.com/',
|
||||
category: 'cloud'
|
||||
},
|
||||
{
|
||||
site: 'Twitter',
|
||||
icon: 'twitter',
|
||||
url: 'https://twitter.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Instagram',
|
||||
icon: 'instagram',
|
||||
url: 'https://instagram.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Bitbucket',
|
||||
icon: 'bitbucket',
|
||||
url: 'https://bitbucket.org/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Gitlab',
|
||||
icon: 'gitlab',
|
||||
url: 'https://gitlab.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Deviantart',
|
||||
icon: 'deviantart',
|
||||
url: 'https://deviantart.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Duckduckgo',
|
||||
icon: 'duckduckgo',
|
||||
url: 'https://duckduckgo.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Ecosia',
|
||||
icon: 'ecosia',
|
||||
url: 'https://ecosia.org/',
|
||||
category: 'search engine'
|
||||
},
|
||||
{
|
||||
site: 'Google',
|
||||
icon: 'google',
|
||||
url: 'https://google.com/',
|
||||
category: 'search engine'
|
||||
},
|
||||
{
|
||||
site: 'Wikipedia',
|
||||
icon: 'wikipedia',
|
||||
url: 'https://wikipedia.org/',
|
||||
category: 'information'
|
||||
},
|
||||
{
|
||||
site: 'Unsplash',
|
||||
icon: 'unsplash',
|
||||
url: 'https://unsplash.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Twitch',
|
||||
icon: 'twitch',
|
||||
url: 'https://twitch.tv/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Yahoo',
|
||||
icon: 'yahoo',
|
||||
url: 'https://mail.yahoo.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Material.io',
|
||||
icon: 'materialio',
|
||||
url: 'https://material.io/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Netflix',
|
||||
icon: 'netflix',
|
||||
url: 'https://netflix.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Office 365',
|
||||
icon: 'office365',
|
||||
url: 'https://office.com/',
|
||||
category: 'information'
|
||||
},
|
||||
{
|
||||
site: '4chan',
|
||||
icon: '4chan',
|
||||
url: 'https://4chan.org/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Discord',
|
||||
icon: 'discord',
|
||||
url: 'https://discord.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Spotify',
|
||||
icon: 'spotify',
|
||||
url: 'https://spotify.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Ebay',
|
||||
icon: 'ebay',
|
||||
url: 'https://ebay.com/',
|
||||
category: 'shop'
|
||||
},
|
||||
{
|
||||
site: 'JSFiddle',
|
||||
icon: 'jsfiddle',
|
||||
url: 'https://jsfiddle.net/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'ArchWiki',
|
||||
icon: 'archwiki',
|
||||
url: 'https://wiki.archlinux.org/',
|
||||
category: 'information'
|
||||
},
|
||||
{
|
||||
site: 'Figma',
|
||||
icon: 'figma',
|
||||
url: 'https://figma.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Stackoverflow',
|
||||
icon: 'stackoverflow',
|
||||
url: 'https://stackoverflow.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Stackexchange',
|
||||
icon: 'stackexchange',
|
||||
url: 'https://stackexchange.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Superuser',
|
||||
icon: 'superuser',
|
||||
url: 'https://superuser.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Calendar',
|
||||
icon: 'calendar',
|
||||
url: 'https://calendar.google.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Messenger',
|
||||
icon: 'messenger',
|
||||
url: 'https://messenger.com/',
|
||||
category: 'social'
|
||||
},
|
||||
{
|
||||
site: 'Icons8',
|
||||
icon: 'icons8',
|
||||
url: 'https://icons8.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Markdown Cheatsheet',
|
||||
icon: 'markdown',
|
||||
url: 'https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Interneting is Hard',
|
||||
icon: 'interneting-is-hard',
|
||||
url: 'https://internetingishard.com/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Keycode',
|
||||
icon: 'keycode',
|
||||
url: 'https://keycode.info/',
|
||||
category: 'development'
|
||||
},
|
||||
{
|
||||
site: 'Soundcloud',
|
||||
icon: 'soundcloud',
|
||||
url: 'https://soundcloud.com/',
|
||||
category: 'media'
|
||||
},
|
||||
{
|
||||
site: 'Amazon',
|
||||
icon: 'amazon',
|
||||
url: 'https://amazon.com/',
|
||||
category: 'shop'
|
||||
},
|
||||
{
|
||||
site: 'Flaticon',
|
||||
icon: 'flaticon',
|
||||
url: 'https://flaticon.com/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'Wikimedia Commons',
|
||||
icon: 'commons',
|
||||
url: 'https://commons.wikimedia.org/',
|
||||
category: 'design'
|
||||
},
|
||||
{
|
||||
site: 'MEGA',
|
||||
icon: 'mega',
|
||||
url: 'https://mega.nz/',
|
||||
category: 'cloud'
|
||||
},
|
||||
{
|
||||
site: 'MDN Web Docs',
|
||||
icon: 'mdn',
|
||||
url: 'https://developer.mozilla.org/',
|
||||
category: 'development'
|
||||
}
|
||||
];
|
||||
|
||||
// Dock
|
||||
// A list of websites that will be generated and put on the dock
|
||||
const dockSites = [
|
||||
{
|
||||
site: 'Reddit',
|
||||
icon: 'reddit',
|
||||
url: 'https://reddit.com/'
|
||||
},
|
||||
{
|
||||
site: 'Github',
|
||||
icon: 'github',
|
||||
url: 'https://github.com/'
|
||||
},
|
||||
{
|
||||
site: 'Facebook',
|
||||
icon: 'facebook',
|
||||
url: 'https://facebook.com/'
|
||||
},
|
||||
{
|
||||
site: 'Gmail',
|
||||
icon: 'gmail',
|
||||
url: 'https://mail.google.com/'
|
||||
},
|
||||
{
|
||||
site: 'Youtube',
|
||||
icon: 'youtube',
|
||||
url: 'https://youtube.com/'
|
||||
},
|
||||
{
|
||||
site: 'GDrive',
|
||||
icon: 'gdrive',
|
||||
url: 'https://drive.google.com/'
|
||||
},
|
||||
{
|
||||
site: 'Twitter',
|
||||
icon: 'twitter',
|
||||
url: 'https://twitter.com/'
|
||||
},
|
||||
{
|
||||
site: 'Material.io',
|
||||
icon: 'materialio',
|
||||
url: 'https://material.io/'
|
||||
}
|
||||
];
|
@ -1,210 +1,213 @@
|
||||
var localStorage = window.localStorage;
|
||||
class ThemeEngine {
|
||||
constructor() {
|
||||
this._localStorage = window.localStorage;
|
||||
|
||||
const backgroundTextBox = document.getElementById('backgroundSet');
|
||||
const backgroundOpacityTextBox = document.getElementById('backgroundOpacitySet');
|
||||
const foregroundTextBox = document.getElementById('foregroundSet');
|
||||
const foregroundOpacityTextBox = document.getElementById('foregroundOpacitySet');
|
||||
this._backgroundTextBox = document.querySelector('#backgroundSet');
|
||||
this._backgroundOpacityTextBox = document.querySelector('#backgroundOpacitySet');
|
||||
this._foregroundTextBox = document.querySelector('#foregroundSet');
|
||||
this._foregroundOpacityTextBox = document.querySelector('#foregroundOpacitySet');
|
||||
|
||||
const blurTextBox = document.getElementById('blurSet');
|
||||
this._blurTextBox = document.querySelector('#blurSet');
|
||||
this._applyTheme = document.querySelector('#themeEngineAsDefault');
|
||||
this._resetTheme = document.querySelector('#themeEngineReset');
|
||||
|
||||
const applyTheme = document.getElementById('themeEngineAsDefault');
|
||||
const resetTheme = document.getElementById('themeEngineReset');
|
||||
|
||||
// Save CSS color constiables default in localStorage
|
||||
// Will only save if you visit the webpage for the very first time
|
||||
const saveDefaultCSS = () => {
|
||||
|
||||
const origBaseBG = localStorage.getItem('origBaseBG');
|
||||
const origBaseColor = localStorage.getItem('origBaseColor');
|
||||
const origBlurStrength = localStorage.getItem('origBlurStrength');
|
||||
|
||||
if ((origBaseBG === null) || (origBaseColor === null) || (origBlurStrength) === null) {
|
||||
|
||||
localStorage.setItem(
|
||||
'origBaseBG',
|
||||
window.getComputedStyle(document.documentElement).getPropertyValue('--base-bg')
|
||||
);
|
||||
localStorage.setItem(
|
||||
'origBaseColor',
|
||||
window.getComputedStyle(document.documentElement).getPropertyValue('--base-color')
|
||||
);
|
||||
localStorage.setItem(
|
||||
'origBlurStrength',
|
||||
window.getComputedStyle(document.documentElement).getPropertyValue('--blur-strength')
|
||||
);
|
||||
this._init();
|
||||
}
|
||||
}
|
||||
|
||||
// Check color validity
|
||||
const checkColorValidity = (colorStr) => {
|
||||
_saveDefaultCSS = () => {
|
||||
|
||||
// Check if RGBA - (#RRGGBBAA)
|
||||
const colorRGBA = /^#[0-9A-F]{8}$/i.test(colorStr);
|
||||
|
||||
// If not RGBA
|
||||
if (!colorRGBA) {
|
||||
|
||||
// If RGB - (#RRGGBB)
|
||||
if (/^#([0-9A-F]{3}){1,2}$/i.test(colorStr)) {
|
||||
|
||||
// Add completely opaque alpha
|
||||
return colorStr + 'FF';
|
||||
const origBaseBG = this._localStorage.getItem('origBaseBG');
|
||||
const origBaseColor = this._localStorage.getItem('origBaseColor');
|
||||
const origBlurStrength = this._localStorage.getItem('origBlurStrength');
|
||||
|
||||
// If three-charactered HEX color - (#RGB)
|
||||
} else if (/^#([0-9A-F]{3}){1,2}$/i.test(colorStr)) {
|
||||
if ((origBaseBG === null) || (origBaseColor === null) || (origBlurStrength) === null) {
|
||||
|
||||
// Convert it to RRGGBB
|
||||
return colorStr.replace(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, "#$1$1$2$2$3$3");
|
||||
|
||||
// If three-charactered HEX Color(#RGB) with AA - (#RGBAA)
|
||||
} else if (colorStr.length == 6) {
|
||||
|
||||
const bg = colorStr.slice(0, -2);
|
||||
const op = colorStr.slice(-2);
|
||||
|
||||
return bg.replace(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, "#$1$1$2$2$3$3") + op;
|
||||
|
||||
} else {
|
||||
alert('Invalid color');
|
||||
this._localStorage.setItem(
|
||||
'origBaseBG',
|
||||
window.getComputedStyle(document.documentElement).getPropertyValue('--base-bg')
|
||||
);
|
||||
this._localStorage.setItem(
|
||||
'origBaseColor',
|
||||
window.getComputedStyle(document.documentElement).getPropertyValue('--base-color')
|
||||
);
|
||||
this._localStorage.setItem(
|
||||
'origBlurStrength',
|
||||
window.getComputedStyle(document.documentElement).getPropertyValue('--blur-strength')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// It's RGBA and a valid color so just return it
|
||||
return colorStr;
|
||||
}
|
||||
_checkColorValidity = colorStr => {
|
||||
|
||||
// Update textboxes
|
||||
const updateTextBoxValues = (bgColor, bgOpacity, fgColor, fgOpacity, blurPower) => {
|
||||
// Set placeholders
|
||||
backgroundTextBox.value = '';
|
||||
backgroundTextBox.placeholder = bgColor;
|
||||
// Check if RGBA - (#RRGGBBAA)
|
||||
const colorRGBA = /^#[0-9A-F]{8}$/i.test(colorStr);
|
||||
|
||||
backgroundOpacityTextBox.value = '';
|
||||
backgroundOpacityTextBox.placeholder = bgOpacity;
|
||||
// If not RGBA
|
||||
if (!colorRGBA) {
|
||||
|
||||
foregroundTextBox.value = '';
|
||||
foregroundTextBox.placeholder = fgColor;
|
||||
foregroundOpacityTextBox.value = '';
|
||||
foregroundOpacityTextBox.placeholder = fgOpacity;
|
||||
// If RGB - (#RRGGBB)
|
||||
if (/^#([0-9A-F]{3}){1,2}$/i.test(colorStr)) {
|
||||
|
||||
// Add completely opaque alpha
|
||||
return colorStr + 'FF';
|
||||
|
||||
// If three-charactered HEX color - (#RGB)
|
||||
} else if (/^#([0-9A-F]{3}){1,2}$/i.test(colorStr)) {
|
||||
|
||||
blurTextBox.value = '';
|
||||
blurTextBox.placeholder = blurPower;
|
||||
}
|
||||
// Convert it to RRGGBB
|
||||
return colorStr.replace(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, '#$1$1$2$2$3$3');
|
||||
|
||||
// Theme processing
|
||||
const processTheme = () => {
|
||||
// If three-charactered HEX Color(#RGB) with AA - (#RGBAA)
|
||||
} else if (colorStr.length == 6) {
|
||||
|
||||
// Retrieve custom colors
|
||||
let baseBG = localStorage.getItem('baseBG');
|
||||
let baseColor = localStorage.getItem('baseColor');
|
||||
let blurStrength = localStorage.getItem('blurStrength');
|
||||
const bg = colorStr.slice(0, -2);
|
||||
const op = colorStr.slice(-2);
|
||||
|
||||
// If custom color doesn't exist, use the value in CSS
|
||||
if (baseBG === null) {
|
||||
baseBG = localStorage.getItem('origBaseBG');
|
||||
return bg.replace(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, '#$1$1$2$2$3$3') + op;
|
||||
|
||||
} else {
|
||||
alert('Invalid color');
|
||||
}
|
||||
}
|
||||
|
||||
// It's RGBA and a valid color so just return it
|
||||
return colorStr;
|
||||
}
|
||||
|
||||
if (baseColor === null) {
|
||||
baseColor = localStorage.getItem('origBaseColor');
|
||||
_updateTextBoxValues = (bgColor, bgOpacity, fgColor, fgOpacity, blurPower) => {
|
||||
|
||||
// Set placeholders
|
||||
this._backgroundTextBox.value = '';
|
||||
this._backgroundTextBox.placeholder = bgColor;
|
||||
|
||||
this._backgroundOpacityTextBox.value = '';
|
||||
this._backgroundOpacityTextBox.placeholder = bgOpacity;
|
||||
|
||||
this._foregroundTextBox.value = '';
|
||||
this._foregroundTextBox.placeholder = fgColor;
|
||||
this._foregroundOpacityTextBox.value = '';
|
||||
this._foregroundOpacityTextBox.placeholder = fgOpacity;
|
||||
|
||||
this._blurTextBox.value = '';
|
||||
this._blurTextBox.placeholder = blurPower;
|
||||
|
||||
}
|
||||
|
||||
if (blurStrength === null) {
|
||||
blurStrength = localStorage.getItem('origBlurStrength');
|
||||
_processTheme = () => {
|
||||
|
||||
// Retrieve custom colors
|
||||
let baseBG = this._localStorage.getItem('baseBG');
|
||||
let baseColor = this._localStorage.getItem('baseColor');
|
||||
let blurStrength = this._localStorage.getItem('blurStrength');
|
||||
|
||||
// If custom color doesn't exist, use the value in CSS
|
||||
if (baseBG === null) {
|
||||
baseBG = this._localStorage.getItem('origBaseBG');
|
||||
}
|
||||
|
||||
if (baseColor === null) {
|
||||
baseColor = this._localStorage.getItem('origBaseColor');
|
||||
}
|
||||
|
||||
if (blurStrength === null) {
|
||||
blurStrength = this._localStorage.getItem('origBlurStrength');
|
||||
}
|
||||
|
||||
// Remove whitespace
|
||||
baseBG = baseBG.replace(/ /g,'');
|
||||
baseColor = baseColor.replace(/ /g,'');
|
||||
blurStrength = blurStrength.replace(/ /g,'');
|
||||
|
||||
// Check validity
|
||||
baseBG = this._checkColorValidity(baseBG);
|
||||
baseColor = this._checkColorValidity(baseColor);
|
||||
|
||||
// Slice to separate RGB and A of background color
|
||||
// Slice alpha out
|
||||
const backgroundColor = baseBG.slice(0, -2);
|
||||
// Get alpha
|
||||
const backgroundOpacity = baseBG.slice(-2);
|
||||
|
||||
|
||||
// Slice to separate RGB and A of foreground color
|
||||
// Slice alpha out
|
||||
const foregroundColor = baseColor.slice(0, -2);
|
||||
// Get alpha
|
||||
const foregroundOpacity = baseColor.slice(-2);
|
||||
|
||||
this._updateTextBoxValues(
|
||||
backgroundColor,
|
||||
backgroundOpacity,
|
||||
foregroundColor,
|
||||
foregroundOpacity,
|
||||
blurStrength
|
||||
)
|
||||
}
|
||||
|
||||
// Remove whitespace
|
||||
baseBG = baseBG.replace(/ /g,'');
|
||||
baseColor = baseColor.replace(/ /g,'');
|
||||
blurStrength = blurStrength.replace(/ /g,'');
|
||||
_updateCSSconstiables = () => {
|
||||
|
||||
// Check validity
|
||||
baseBG = checkColorValidity(baseBG);
|
||||
baseColor = checkColorValidity(baseColor);
|
||||
// Get value from input fields
|
||||
const background = (this._backgroundTextBox.value || this._backgroundTextBox.placeholder) +
|
||||
(this._backgroundOpacityTextBox.value || this._backgroundOpacityTextBox.placeholder);
|
||||
|
||||
// Slice to separate RGB and A of background color
|
||||
// Slice alpha out
|
||||
const backgroundColor = baseBG.slice(0, -2);
|
||||
// Get alpha
|
||||
const backgroundOpacity = baseBG.slice(-2);
|
||||
const foreground = (this._foregroundTextBox.value || this._foregroundTextBox.placeholder) +
|
||||
(this._foregroundOpacityTextBox.value || this._foregroundOpacityTextBox.placeholder);
|
||||
|
||||
const blurPower = (this._blurTextBox.value || this._blurTextBox.placeholder);
|
||||
|
||||
// Check color validity
|
||||
const bgColor = this._checkColorValidity(background);
|
||||
const fgColor = this._checkColorValidity(foreground);
|
||||
|
||||
// Slice to separate RGB and A of foreground color
|
||||
// Slice alpha out
|
||||
const foregroundColor = baseColor.slice(0, -2);
|
||||
// Get alpha
|
||||
const foregroundOpacity = baseColor.slice(-2);
|
||||
// Change CSS colors
|
||||
document.documentElement.style.setProperty('--base-bg', bgColor);
|
||||
document.documentElement.style.setProperty('--base-color', fgColor);
|
||||
document.documentElement.style.setProperty('--blur-strength', blurPower);
|
||||
|
||||
updateTextBoxValues(
|
||||
backgroundColor,
|
||||
backgroundOpacity,
|
||||
foregroundColor,
|
||||
foregroundOpacity,
|
||||
blurStrength
|
||||
)
|
||||
}
|
||||
// Save custom color
|
||||
this._localStorage.setItem('baseBG', bgColor);
|
||||
this._localStorage.setItem('baseColor', fgColor);
|
||||
this._localStorage.setItem('blurStrength', blurPower);
|
||||
|
||||
// Update colors
|
||||
const updateCSSconstiables = () => {
|
||||
this._processTheme();
|
||||
}
|
||||
|
||||
// Get value from input fields
|
||||
const background = (backgroundTextBox.value || backgroundTextBox.placeholder) +
|
||||
(backgroundOpacityTextBox.value || backgroundOpacityTextBox.placeholder);
|
||||
_applyOnClickEvent = e => {
|
||||
this._updateCSSconstiables();
|
||||
alert('Success!');
|
||||
}
|
||||
|
||||
const foreground = (foregroundTextBox.value || foregroundTextBox.placeholder) +
|
||||
(foregroundOpacityTextBox.value || foregroundOpacityTextBox.placeholder);
|
||||
|
||||
const blurPower = (blurTextBox.value || blurTextBox.placeholder);
|
||||
_registerApplyOnClickEvent = () => {
|
||||
this._applyTheme.onclick = this._applyOnClickEvent;
|
||||
}
|
||||
|
||||
// Check color validity
|
||||
const bgColor = checkColorValidity(background);
|
||||
const fgColor = checkColorValidity(foreground);
|
||||
_resetOnClickEvent = e => {
|
||||
this._localStorage.removeItem('baseBG');
|
||||
this._localStorage.removeItem('baseColor');
|
||||
this._localStorage.removeItem('blurStrength');
|
||||
|
||||
// Change CSS colors
|
||||
document.documentElement.style.setProperty('--base-bg', bgColor);
|
||||
document.documentElement.style.setProperty('--base-color', fgColor);
|
||||
document.documentElement.style.setProperty('--blur-strength', blurPower);
|
||||
this._saveDefaultCSS();
|
||||
this._processTheme();
|
||||
this._updateCSSconstiables();
|
||||
|
||||
alert('Success!');
|
||||
}
|
||||
|
||||
// Save custom color
|
||||
localStorage.setItem('baseBG', bgColor);
|
||||
localStorage.setItem('baseColor', fgColor);
|
||||
localStorage.setItem('blurStrength', blurPower);
|
||||
_registerResetOnClickEvent = () => {
|
||||
this._resetTheme.onclick = this._resetOnClickEvent;
|
||||
}
|
||||
|
||||
processTheme();
|
||||
}
|
||||
_init = () => {
|
||||
|
||||
// Run on window onload
|
||||
const updateOnStartUp = () => {
|
||||
// Update
|
||||
processTheme();
|
||||
this._saveDefaultCSS();
|
||||
|
||||
// Update settings
|
||||
updateCSSconstiables();
|
||||
}
|
||||
// Update
|
||||
this._processTheme();
|
||||
// Update settings
|
||||
this._updateCSSconstiables();
|
||||
|
||||
// Apply button event handler
|
||||
applyTheme.onclick = () => {
|
||||
updateCSSconstiables();
|
||||
alert('Success!');
|
||||
}
|
||||
this._registerApplyOnClickEvent();
|
||||
this._registerResetOnClickEvent();
|
||||
}
|
||||
|
||||
// Reset button event handler
|
||||
resetTheme.onclick = () => {
|
||||
localStorage.removeItem('baseBG');
|
||||
localStorage.removeItem('baseColor');
|
||||
localStorage.removeItem('blurStrength');
|
||||
|
||||
saveDefaultCSS();
|
||||
processTheme();
|
||||
updateCSSconstiables();
|
||||
|
||||
alert('Success!');
|
||||
}
|
||||
|
||||
// Initialize
|
||||
const onStartUp = () => {
|
||||
saveDefaultCSS();
|
||||
updateOnStartUp();
|
||||
}
|
||||
|
||||
// Call Initialize
|
||||
window.onload = onStartUp();
|
||||
}
|
@ -1,278 +1,288 @@
|
||||
const weatherScreen = document.getElementById("weatherScreen");
|
||||
class WeatherScreen {
|
||||
|
||||
let weatherScreenVisibility = false;
|
||||
constructor() {
|
||||
this._weatherScreenVisibility = false;
|
||||
this._tempSymbol = '°C';
|
||||
|
||||
const weatherIcon = document.getElementById("weatherTodayIcon");
|
||||
const weatherLocation = document.getElementById("weatherTodayLocation");
|
||||
const weatherDescription = document.getElementById("weatherTodayDescription");
|
||||
this._weatherScreen = document.querySelector('#weatherScreen');
|
||||
this._weatherIcon = document.querySelector('#weatherTodayIcon');
|
||||
this._weatherLocation = document.querySelector('#weatherTodayLocation');
|
||||
this._weatherDescription = document.querySelector('#weatherTodayDescription');
|
||||
this._sunriseHour = document.querySelector('#sunriseTodayHour');
|
||||
this._sunsetHour = document.querySelector('#sunsetTodayHour');
|
||||
this._updateHour = document.querySelector('#updateTodayHour');
|
||||
this._weatherDockImageButton = document.querySelector('#buttonImageWeather');
|
||||
this._forecastContainer = document.querySelector('#forecastContainer');
|
||||
|
||||
const sunriseHour = document.getElementById("sunriseTodayHour");
|
||||
const sunsetHour = document.getElementById("sunsetTodayHour");
|
||||
const updateHour = document.getElementById("updateTodayHour")
|
||||
|
||||
const weatherDockImageButton = document.getElementById("buttonImageWeather");
|
||||
const forecastContainer = document.getElementById("forecastContainer");
|
||||
|
||||
const formatUnixTime = unix => {
|
||||
const date = new Date(unix*1000);
|
||||
const hour = date.getHours();
|
||||
const minutes = "0" + date.getMinutes();
|
||||
const formattedTime = hour + ':' + minutes.substr(-2);
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
const getWeatherIcon = code => {
|
||||
const icon_tbl = {
|
||||
'01d': 'sun_icon.svg',
|
||||
'01n': 'moon_icon.svg',
|
||||
'02d': 'dfew_clouds.svg',
|
||||
'02n': 'nfew_clouds.svg',
|
||||
'03d': 'dscattered_clouds.svg',
|
||||
'03n': 'nscattered_clouds.svg',
|
||||
'04d': 'dbroken_clouds.svg',
|
||||
'04n': 'nbroken_clouds.svg',
|
||||
'09d': 'dshower_rain.svg',
|
||||
'09n': 'nshower_rain.svg',
|
||||
'10d': 'd_rain.svg',
|
||||
'10n': 'n_rain.svg',
|
||||
'11d': 'dthunderstorm.svg',
|
||||
'11n': 'nthunderstorm.svg',
|
||||
'13d': 'snow.svg',
|
||||
'13n': 'snow.svg',
|
||||
'50d': 'dmist.svg',
|
||||
'50n': 'nmist.svg'
|
||||
};
|
||||
|
||||
return icon_tbl[code];
|
||||
}
|
||||
|
||||
const updateWeatherDockButton = icon => {
|
||||
weatherDockImageButton.style.background = "url('assets/weather-icons/" + icon + "')";
|
||||
weatherDockImageButton.style.backgroundSize = "cover";
|
||||
}
|
||||
|
||||
const setWeatherValue = (loc, desc, icon, sunr, suns, updt) => {
|
||||
|
||||
const temp_symbol = (units === "metric") ? "°C" : "°F";
|
||||
|
||||
weatherLocation.innerHTML = loc;
|
||||
weatherDescription.innerHTML = desc + temp_symbol;
|
||||
|
||||
weatherIcon.style.background = "url('assets/weather-icons/" + icon + "')";
|
||||
weatherIcon.style.backgroundSize = "cover";
|
||||
|
||||
sunriseHour.innerHTML = sunr;
|
||||
sunsetHour.innerHTML = suns;
|
||||
updateHour.innerHTML = updt;
|
||||
|
||||
// Update weather button on dock
|
||||
updateWeatherDockButton(icon);
|
||||
}
|
||||
|
||||
const createForecastBody = (fIcon, forecastTemp, foreDescription, fHour, fDate) => {
|
||||
|
||||
// Main Div
|
||||
const forecastDay = document.createElement('div');
|
||||
forecastDay.className = 'weatherForecastDay';
|
||||
|
||||
// Icon Container Div
|
||||
const forecastIconContainer = document.createElement('div');
|
||||
forecastIconContainer.className = 'weatherForecastDayIconContainer';
|
||||
|
||||
// Icon Div
|
||||
const forecastIcon = document.createElement('div');
|
||||
forecastIcon.className = 'weatherForecastDayIcon';
|
||||
forecastIcon.style.background = "url('assets/weather-icons/" + fIcon + "')";
|
||||
forecastIcon.style.backgroundSize = 'cover';
|
||||
|
||||
// Details Div
|
||||
const forecastDetails = document.createElement('div');
|
||||
forecastDetails.className = 'weatherForecastDayDetails';
|
||||
|
||||
const forecastTemperature = document.createElement('div');
|
||||
forecastTemperature.className = 'weatherForecastDayDetailsTemperature';
|
||||
forecastTemperature.innerHTML = forecastTemp;
|
||||
|
||||
const forecastDescription = document.createElement('div');
|
||||
forecastDescription.className = 'weatherForecastDayDetailsDescription';
|
||||
forecastDescription.innerHTML = foreDescription;
|
||||
|
||||
// Append details to div container
|
||||
forecastDetails.appendChild(forecastTemperature);
|
||||
forecastDetails.appendChild(forecastDescription);
|
||||
|
||||
// Date Div
|
||||
const forecastDayDate = document.createElement('div');
|
||||
forecastDayDate.className = 'weatherForecastDayDate';
|
||||
|
||||
const forecastHour = document.createElement('div');
|
||||
forecastHour.className = 'weatherForecastDayDateHour';
|
||||
forecastHour.innerHTML = fHour;
|
||||
|
||||
const forecastDate = document.createElement('div');
|
||||
forecastDate.className = 'weatherForecastDayDateDate';
|
||||
forecastDate.innerHTML = fDate;
|
||||
|
||||
// Append icon image to div container
|
||||
forecastIconContainer.appendChild(forecastIcon);
|
||||
|
||||
// Append details to div container
|
||||
forecastDayDate.appendChild(forecastHour);
|
||||
forecastDayDate.appendChild(forecastDate);
|
||||
|
||||
// Append to main div
|
||||
forecastDay.appendChild(forecastIconContainer);
|
||||
forecastDay.appendChild(forecastDetails);
|
||||
forecastDay.appendChild(forecastDayDate);
|
||||
|
||||
// Append to the main container
|
||||
forecastContainer.appendChild(forecastDay);
|
||||
}
|
||||
|
||||
const setErrValue = () => {
|
||||
const wLoc = "Earth, Milky Way";
|
||||
const wDesc = "dust & clouds, -1000";
|
||||
const wIcon = "weather-error.svg";
|
||||
|
||||
const time = "00:00";
|
||||
|
||||
setWeatherValue(wLoc, wDesc, wIcon, time, time, time);
|
||||
}
|
||||
|
||||
// Process weather data
|
||||
const processWeatherData = (data) => {
|
||||
|
||||
const cityName = data.name;
|
||||
const countryName = data.sys.country;
|
||||
const weatherDescription = data.weather[0].description;
|
||||
const weatherIcon = data.weather[0].icon;
|
||||
const weatherTemp = Math.floor(data.main.temp);
|
||||
const sunRise = data.sys.sunrise;
|
||||
const sunSet = data.sys.sunset;
|
||||
const update = data.dt;
|
||||
|
||||
const wLoc = cityName + ", " + countryName;
|
||||
let wDesc = weatherDescription + ", " + weatherTemp;
|
||||
|
||||
// Capitalize first word
|
||||
wDesc = wDesc && wDesc[0].toUpperCase() + wDesc.slice(1)
|
||||
|
||||
const wIcon = getWeatherIcon(weatherIcon);
|
||||
const rise = formatUnixTime(sunRise);
|
||||
const set = formatUnixTime(sunSet);
|
||||
const upd = formatUnixTime(update);
|
||||
|
||||
setWeatherValue(wLoc, wDesc, wIcon, rise, set, upd);
|
||||
}
|
||||
|
||||
// This will be called in weather-settings
|
||||
const getWeatherData = (appID, cityID, units) => {
|
||||
|
||||
requestString = "https://api.openweathermap.org/data/2.5/weather?APPID=" + appID + "&id=" + cityID + "&units=" + units;
|
||||
|
||||
const request = new XMLHttpRequest();
|
||||
request.open("GET", requestString, true);
|
||||
request.onload = e => {
|
||||
if (request.readyState === 4 && request.status === 200 && request.status < 400) {
|
||||
processWeatherData(JSON.parse(request.response));
|
||||
} else {
|
||||
setErrValue();
|
||||
};
|
||||
};
|
||||
request.send();
|
||||
};
|
||||
|
||||
// Fetch forecast
|
||||
const getForecastData = (appID, cityID, units) => {
|
||||
requestString = "https://api.openweathermap.org/data/2.5/forecast?APPID=" + appID + "&id=" + cityID + "&units=" + units;
|
||||
|
||||
request = new XMLHttpRequest();
|
||||
request.open("GET", requestString, true);
|
||||
request.onload = e => {
|
||||
if (request.readyState === 4 && request.status === 200 && request.status < 400) {
|
||||
processForecastData(JSON.parse(request.response));
|
||||
} else {
|
||||
setErrValue();
|
||||
};
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
|
||||
// Process forecast data
|
||||
const processForecastData = data => {
|
||||
|
||||
// Empty forecast container to avoid duplication
|
||||
forecastContainer.innerHTML = '';
|
||||
|
||||
const forecast = data.list;
|
||||
|
||||
for (let i = 8; i < forecast.length; i+=8) {
|
||||
|
||||
const temp_symbol = (units === "metric") ? "°C" : "°F";
|
||||
|
||||
const foreIcon = forecast[i].weather[0].icon;
|
||||
const minimumTemp = forecast[i].main.temp_min;
|
||||
const maximumTemp = forecast[i].main.temp_max;
|
||||
const foreDescription = forecast[i].weather[0].description;
|
||||
const dateTime = forecast[i].dt_txt;
|
||||
|
||||
const fIcon = getWeatherIcon(foreIcon);
|
||||
const minTemp = Math.floor(minimumTemp);
|
||||
const maxTemp = Math.floor(maximumTemp);
|
||||
const forecastTemp = minTemp + ' ~ ' + maxTemp + temp_symbol;
|
||||
const fHour = dateTime.substr(dateTime.indexOf(' ') + 1).slice(0, -3);;
|
||||
const fDate = dateTime.substr(0, dateTime.indexOf(' '));
|
||||
|
||||
createForecastBody(fIcon, forecastTemp, foreDescription, fHour, fDate);
|
||||
this._webMenu = document.querySelector('#webMenu');
|
||||
this._dashboard = document.querySelector('#rightDashboard');
|
||||
this._searchBoxContainer = document.querySelector('#searchBoxContainer');
|
||||
}
|
||||
}
|
||||
|
||||
const showWeatherScreen = () => {
|
||||
weatherScreen.classList.add('showWeatherScreen');
|
||||
weatherScreenVisibility = !weatherScreenVisibility;
|
||||
}
|
||||
_formatUnixTime = unix => {
|
||||
const date = new Date(unix*1000);
|
||||
const hour = date.getHours();
|
||||
const minutes = '0' + date.getMinutes();
|
||||
const formattedTime = hour + ':' + minutes.substr(-2);
|
||||
|
||||
const hideWeatherScreen = () => {
|
||||
weatherScreen.classList.remove('showWeatherScreen');
|
||||
weatherScreenVisibility = !weatherScreenVisibility;
|
||||
}
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
const toggleWeatherScreen = () => {
|
||||
getWeatherScreenVisiblity = () => {
|
||||
return this._weatherScreenVisibility;
|
||||
}
|
||||
|
||||
console.log('toggle weather screen');
|
||||
_getWeatherIcon = code => {
|
||||
const icon_tbl = {
|
||||
'01d': 'sun_icon.svg',
|
||||
'01n': 'moon_icon.svg',
|
||||
'02d': 'dfew_clouds.svg',
|
||||
'02n': 'nfew_clouds.svg',
|
||||
'03d': 'dscattered_clouds.svg',
|
||||
'03n': 'nscattered_clouds.svg',
|
||||
'04d': 'dbroken_clouds.svg',
|
||||
'04n': 'nbroken_clouds.svg',
|
||||
'09d': 'dshower_rain.svg',
|
||||
'09n': 'nshower_rain.svg',
|
||||
'10d': 'd_rain.svg',
|
||||
'10n': 'n_rain.svg',
|
||||
'11d': 'dthunderstorm.svg',
|
||||
'11n': 'nthunderstorm.svg',
|
||||
'13d': 'snow.svg',
|
||||
'13n': 'snow.svg',
|
||||
'50d': 'dmist.svg',
|
||||
'50n': 'nmist.svg'
|
||||
};
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileAnimRunning) return;
|
||||
return icon_tbl[code];
|
||||
}
|
||||
|
||||
// Rotate profile
|
||||
rotateProfile();
|
||||
_updateWeatherDockButton = icon => {
|
||||
this._weatherDockImageButton.style.background = `url('assets/weather-icons/${icon}')`;
|
||||
this._weatherDockImageButton.style.backgroundSize = 'cover';
|
||||
}
|
||||
|
||||
if (weatherScreenVisibility) {
|
||||
// Hide search box
|
||||
hideWeatherScreen();
|
||||
_setWeatherValue = (loc, desc, icon, sunr, suns, updt) => {
|
||||
|
||||
this._weatherLocation.innerHTML = loc;
|
||||
this._weatherDescription.innerHTML = desc + this._tempSymbol;
|
||||
|
||||
} else {
|
||||
// Show search box
|
||||
showWeatherScreen();
|
||||
}
|
||||
this._weatherIcon.style.background = `url('assets/weather-icons/${icon}')`;
|
||||
this._weatherIcon.style.backgroundSize = 'cover';
|
||||
|
||||
// Check if any of these are open, if yes, close it
|
||||
if (webMenu.classList.contains('showWebMenu')) {
|
||||
console.log('web menu is open, closing...');
|
||||
hideWebMenu();
|
||||
return;
|
||||
this._sunriseHour.innerHTML = sunr;
|
||||
this._sunsetHour.innerHTML = suns;
|
||||
this._updateHour.innerHTML = updt;
|
||||
|
||||
} else if (searchBoxContainer.classList.contains('showSearchBox')) {
|
||||
console.log('searchbox is open, closing...');
|
||||
hideSearchBox();
|
||||
|
||||
} else if (dashboard.classList.contains('showRightDashboard')) {
|
||||
console.log('dashboard is open, closing...');
|
||||
hideDashboard();
|
||||
// return;
|
||||
}
|
||||
// Update weather button on dock
|
||||
this._updateWeatherDockButton(icon);
|
||||
}
|
||||
|
||||
_createForecastBody = (fIcon, forecastTemp, foreDescription, fHour, fDate) => {
|
||||
|
||||
// Main Div
|
||||
const forecastDay = document.createElement('div');
|
||||
forecastDay.className = 'weatherForecastDay';
|
||||
|
||||
// Icon Container Div
|
||||
const forecastIconContainer = document.createElement('div');
|
||||
forecastIconContainer.className = 'weatherForecastDayIconContainer';
|
||||
|
||||
// Icon Div
|
||||
const forecastIcon = document.createElement('div');
|
||||
forecastIcon.className = 'weatherForecastDayIcon';
|
||||
forecastIcon.style.background = `url('assets/weather-icons/${fIcon}')`;
|
||||
forecastIcon.style.backgroundSize = 'cover';
|
||||
|
||||
// Details Div
|
||||
const forecastDetails = document.createElement('div');
|
||||
forecastDetails.className = 'weatherForecastDayDetails';
|
||||
|
||||
const forecastTemperature = document.createElement('div');
|
||||
forecastTemperature.className = 'weatherForecastDayDetailsTemperature';
|
||||
forecastTemperature.innerHTML = forecastTemp;
|
||||
|
||||
const forecastDescription = document.createElement('div');
|
||||
forecastDescription.className = 'weatherForecastDayDetailsDescription';
|
||||
forecastDescription.innerHTML = foreDescription;
|
||||
|
||||
// Append details to div container
|
||||
forecastDetails.appendChild(forecastTemperature);
|
||||
forecastDetails.appendChild(forecastDescription);
|
||||
|
||||
// Date Div
|
||||
const forecastDayDate = document.createElement('div');
|
||||
forecastDayDate.className = 'weatherForecastDayDate';
|
||||
|
||||
const forecastHour = document.createElement('div');
|
||||
forecastHour.className = 'weatherForecastDayDateHour';
|
||||
forecastHour.innerHTML = fHour;
|
||||
|
||||
const forecastDate = document.createElement('div');
|
||||
forecastDate.className = 'weatherForecastDayDateDate';
|
||||
forecastDate.innerHTML = fDate;
|
||||
|
||||
// Append icon image to div container
|
||||
forecastIconContainer.appendChild(forecastIcon);
|
||||
|
||||
// Append details to div container
|
||||
forecastDayDate.appendChild(forecastHour);
|
||||
forecastDayDate.appendChild(forecastDate);
|
||||
|
||||
// Append to main div
|
||||
forecastDay.appendChild(forecastIconContainer);
|
||||
forecastDay.appendChild(forecastDetails);
|
||||
forecastDay.appendChild(forecastDayDate);
|
||||
|
||||
// Append to the main container
|
||||
this._forecastContainer.appendChild(forecastDay);
|
||||
}
|
||||
|
||||
|
||||
_setErrValue = () => {
|
||||
const wLoc = 'Earth, Milky Way';
|
||||
const wDesc = 'dust & clouds, -1000';
|
||||
const wIcon = 'weather-error.svg';
|
||||
|
||||
const time = '00:00';
|
||||
|
||||
this._setWeatherValue(wLoc, wDesc, wIcon, time, time, time);
|
||||
}
|
||||
|
||||
|
||||
_processWeatherData = (data) => {
|
||||
|
||||
const cityName = data.name;
|
||||
const countryName = data.sys.country;
|
||||
const weatherDescription = data.weather[0].description;
|
||||
const weatherIcon = data.weather[0].icon;
|
||||
const weatherTemp = Math.floor(data.main.temp);
|
||||
const sunRise = data.sys.sunrise;
|
||||
const sunSet = data.sys.sunset;
|
||||
const update = data.dt;
|
||||
|
||||
const wLoc = cityName + ', ' + countryName;
|
||||
|
||||
let wDesc = weatherDescription + ', ' + weatherTemp;
|
||||
wDesc = wDesc && wDesc[0].toUpperCase() + wDesc.slice(1)
|
||||
|
||||
const wIcon = this._getWeatherIcon(weatherIcon);
|
||||
const rise = this._formatUnixTime(sunRise);
|
||||
const set = this._formatUnixTime(sunSet);
|
||||
const upd = this._formatUnixTime(update);
|
||||
|
||||
this._setWeatherValue(wLoc, wDesc, wIcon, rise, set, upd);
|
||||
}
|
||||
|
||||
getWeatherData = (appID, cityID, units) => {
|
||||
|
||||
const requestString = `https://api.openweathermap.org/data/2.5/weather?APPID=${appID}&id=${cityID}&units=${units}`;
|
||||
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', requestString, true);
|
||||
request.onload = e => {
|
||||
if (request.readyState === 4 && request.status === 200 && request.status < 400) {
|
||||
this._processWeatherData(JSON.parse(request.response));
|
||||
this._tempSymbol = (units === 'metric') ? '°C' : '°F';
|
||||
} else {
|
||||
this._setErrValue();
|
||||
};
|
||||
};
|
||||
request.send();
|
||||
};
|
||||
|
||||
|
||||
getForecastData = (appID, cityID, units) => {
|
||||
|
||||
const requestString = `https://api.openweathermap.org/data/2.5/forecast?APPID=${appID}&id=${cityID}&units=${units}`;
|
||||
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', requestString, true);
|
||||
request.onload = e => {
|
||||
if (request.readyState === 4 && request.status === 200 && request.status < 400) {
|
||||
this._processForecastData(JSON.parse(request.response));
|
||||
this._tempSymbol = (units === 'metric') ? '°C' : '°F';
|
||||
} else {
|
||||
this._setErrValue();
|
||||
};
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
|
||||
_processForecastData = data => {
|
||||
|
||||
// Empty forecast container to avoid duplication
|
||||
this._forecastContainer.innerHTML = '';
|
||||
|
||||
const forecast = data.list;
|
||||
|
||||
for (let i = 8; i < forecast.length; i+=8) {
|
||||
|
||||
const foreIcon = forecast[i].weather[0].icon;
|
||||
const minimumTemp = forecast[i].main.temp_min;
|
||||
const maximumTemp = forecast[i].main.temp_max;
|
||||
const foreDescription = forecast[i].weather[0].description;
|
||||
const dateTime = forecast[i].dt_txt;
|
||||
|
||||
const fIcon = this._getWeatherIcon(foreIcon);
|
||||
const minTemp = Math.floor(minimumTemp);
|
||||
const maxTemp = Math.floor(maximumTemp);
|
||||
const forecastTemp = minTemp + ' ~ ' + maxTemp + this._tempSymbol;
|
||||
const fHour = dateTime.substr(dateTime.indexOf(' ') + 1).slice(0, -3);;
|
||||
const fDate = dateTime.substr(0, dateTime.indexOf(' '));
|
||||
|
||||
this._createForecastBody(fIcon, forecastTemp, foreDescription, fHour, fDate);
|
||||
}
|
||||
}
|
||||
|
||||
showWeatherScreen = () => {
|
||||
this._weatherScreen.classList.add('showWeatherScreen');
|
||||
this._weatherScreenVisibility = !this._weatherScreenVisibility;
|
||||
}
|
||||
|
||||
hideWeatherScreen = () => {
|
||||
this._weatherScreen.classList.remove('showWeatherScreen');
|
||||
this._weatherScreenVisibility = !this._weatherScreenVisibility;
|
||||
}
|
||||
|
||||
toggleWeatherScreen = () => {
|
||||
|
||||
console.log('toggle weather screen');
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileImage.getProfileAnimationStatus()) return;
|
||||
|
||||
// Rotate profile
|
||||
profileImage.rotateProfile();
|
||||
|
||||
if (this._weatherScreenVisibility) {
|
||||
// Hide weather screen
|
||||
this.hideWeatherScreen();
|
||||
|
||||
} else {
|
||||
// Show weather screen
|
||||
this.showWeatherScreen();
|
||||
}
|
||||
|
||||
// Check if any of these are open, if yes, close it
|
||||
if (this._webMenu.classList.contains('showWebMenu')) {
|
||||
console.log('web menu is open, closing...');
|
||||
webMenu.hideWebMenu();
|
||||
return;
|
||||
|
||||
} else if (this._searchBoxContainer.classList.contains('showSearchBox')) {
|
||||
console.log('searchbox is open, closing...');
|
||||
hideSearchBox();
|
||||
|
||||
} else if (this._dashboard.classList.contains('showRightDashboard')) {
|
||||
console.log('dashboard is open, closing...');
|
||||
dashboard.hideDashboard();
|
||||
// return;
|
||||
}
|
||||
|
||||
// Toggle center box
|
||||
centeredBox.toggleCenteredBox();
|
||||
}
|
||||
|
||||
// Toggle center box
|
||||
toggleCenteredBox();
|
||||
}
|
@ -1,76 +1,97 @@
|
||||
// Set constiable
|
||||
let appID, cityID, units;
|
||||
class WeatherSettings {
|
||||
|
||||
// Input elements
|
||||
constructor() {
|
||||
|
||||
// Textboxes
|
||||
const apiBox = document.getElementById("apiBox");
|
||||
const cityBox = document.getElementById("cityBox");
|
||||
this._localStorage = window.localStorage;
|
||||
|
||||
this._appID = '';
|
||||
this._cityID = '';
|
||||
this._units = '';
|
||||
|
||||
// Select menu
|
||||
const weatherSelectUnits = document.getElementById("weatherSelectUnits");
|
||||
this._apiBox = document.querySelector('#apiBox');
|
||||
this._cityBox = document.querySelector('#cityBox');
|
||||
|
||||
// Div buttons
|
||||
const weatherSettingsReset = document.getElementById("weatherSettingsReset");
|
||||
const weatherSettingsApply = document.getElementById("weatherSettingsApply");
|
||||
this._weatherSelectUnits = document.querySelector('#weatherSelectUnits');
|
||||
|
||||
// Apply credentials
|
||||
const applyWeatherSettings = (key, city, units) => {
|
||||
localStorage.setItem('apiKey', key);
|
||||
localStorage.setItem('cityID', city);
|
||||
localStorage.setItem('units', units);
|
||||
}
|
||||
this._weatherSettingsReset = document.querySelector('#weatherSettingsReset');
|
||||
this._weatherSettingsApply = document.querySelector('#weatherSettingsApply');
|
||||
|
||||
// Clear credentials
|
||||
const resetWeatherSettings = () => {
|
||||
localStorage.removeItem('apiKey');
|
||||
localStorage.removeItem('cityID');
|
||||
localStorage.removeItem('units');
|
||||
}
|
||||
this.getWeatherData = weatherScreen.getWeatherData;
|
||||
this.getForecastData = weatherScreen.getForecastData;
|
||||
|
||||
// Update functions
|
||||
const deleteWeatherSettingsValue = () => {
|
||||
apiBox.value = '';
|
||||
cityBox.value = '';
|
||||
weatherSelectUnits.value = "metric";
|
||||
}
|
||||
this._init();
|
||||
}
|
||||
|
||||
const updateWeatherSettingsPlaceholder = () => {
|
||||
apiBox.placeholder = String(appID) || "API Key";
|
||||
cityBox.placeholder = String(cityID) || "City ID";
|
||||
weatherSelectUnits.value = String(units) || "metric";
|
||||
}
|
||||
// Apply credentials
|
||||
_applyWeatherSettings = (key, city, units) => {
|
||||
this._localStorage.setItem('apiKey', key);
|
||||
this._localStorage.setItem('cityID', city);
|
||||
this._localStorage.setItem('units', units);
|
||||
}
|
||||
|
||||
const updateWeatherSettings = () => {
|
||||
appID = localStorage.getItem('apiKey') || "API Key";
|
||||
cityID = localStorage.getItem('cityID') || "City ID";
|
||||
units = localStorage.getItem('units') || "metric";
|
||||
// Clear credentials
|
||||
_resetWeatherSettings = () => {
|
||||
this._localStorage.removeItem('apiKey');
|
||||
this._localStorage.removeItem('cityID');
|
||||
this._localStorage.removeItem('units');
|
||||
}
|
||||
|
||||
// Update weather forecast elements
|
||||
getWeatherData(appID, cityID, units);
|
||||
getForecastData(appID, cityID, units);
|
||||
// Reset textboxes
|
||||
_deleteWeatherSettingsValue = () => {
|
||||
this._apiBox.value = '';
|
||||
this._cityBox.value = '';
|
||||
this._weatherSelectUnits.value = 'metric';
|
||||
}
|
||||
|
||||
deleteWeatherSettingsValue();
|
||||
updateWeatherSettingsPlaceholder();
|
||||
}
|
||||
// Update textbox placeholders
|
||||
_updateWeatherSettingsPlaceholder = () => {
|
||||
this._apiBox.placeholder = String(this._appID) || 'API Key';
|
||||
this._cityBox.placeholder = String(this._cityID) || 'City ID';
|
||||
this._weatherSelectUnits.value = String(this._units) || 'metric';
|
||||
}
|
||||
|
||||
// Reset button was pressed
|
||||
weatherSettingsReset.onclick = () => {
|
||||
// Reset keys
|
||||
resetWeatherSettings();
|
||||
updateWeatherSettings();
|
||||
alert('Credentials deleted!');
|
||||
}
|
||||
// Update weather settings
|
||||
_updateWeatherSettings = () => {
|
||||
this._appID = localStorage.getItem('apiKey') || 'API Key';
|
||||
this._cityID = localStorage.getItem('cityID') || 'City ID';
|
||||
this._units = localStorage.getItem('units') || 'metric';
|
||||
|
||||
// Apply settings
|
||||
weatherSettingsApply.onclick = () => {
|
||||
applyWeatherSettings(
|
||||
apiBox.value || apiBox.placeholder,
|
||||
cityBox.value || cityBox.placeholder,
|
||||
weatherSelectUnits.options[weatherSelectUnits.selectedIndex].value
|
||||
);
|
||||
updateWeatherSettings();
|
||||
alert('Successfully updated!');
|
||||
}
|
||||
// Update weather forecast elements
|
||||
this.getWeatherData(this._appID, this._cityID, this._units);
|
||||
this.getForecastData(this._appID, this._cityID, this._units);
|
||||
|
||||
window.onload = updateWeatherSettings();
|
||||
this._deleteWeatherSettingsValue();
|
||||
this._updateWeatherSettingsPlaceholder();
|
||||
}
|
||||
|
||||
_weatherResetOnClickEvent = e => {
|
||||
// Reset keys
|
||||
this._resetWeatherSettings();
|
||||
this._updateWeatherSettings();
|
||||
alert('Credentials deleted!');
|
||||
}
|
||||
|
||||
_registerWeatherResetOnClickEvent = () => {
|
||||
this._weatherSettingsReset.onclick = this._weatherResetOnClickEvent;
|
||||
}
|
||||
|
||||
_weatherApplyOnClickEvent = e => {
|
||||
this._applyWeatherSettings(
|
||||
this._apiBox.value || this._apiBox.placeholder,
|
||||
this._cityBox.value || this._cityBox.placeholder,
|
||||
this._weatherSelectUnits.options[this._weatherSelectUnits.selectedIndex].value
|
||||
);
|
||||
this._updateWeatherSettings();
|
||||
alert('Successfully updated!');
|
||||
}
|
||||
|
||||
_registerWeatherApplyOnClickEvent = () => {
|
||||
this._weatherSettingsApply.onclick = this._weatherApplyOnClickEvent;
|
||||
}
|
||||
|
||||
_init = () => {
|
||||
this._updateWeatherSettings();
|
||||
this._registerWeatherResetOnClickEvent();
|
||||
this._registerWeatherApplyOnClickEvent();
|
||||
}
|
||||
}
|
764
js/web-menu.js
764
js/web-menu.js
@ -1,405 +1,435 @@
|
||||
const webMenu = document.getElementById("webMenu");
|
||||
const webMenuList = document.getElementById("webMenuList");
|
||||
const webMenuListContainer = document.getElementById("webMenuListContainer");
|
||||
const webMenuSearchBox = document.getElementById("webMenuSearchBox");
|
||||
class WebMenu {
|
||||
|
||||
var webMenuVisibility = false;
|
||||
constructor() {
|
||||
this._dashboard = document.querySelector('#rightDashboard');
|
||||
this._weatherScreen = document.querySelector('#weatherScreen');
|
||||
this._webSites = config.getWebSites();
|
||||
|
||||
let webItemFocus;
|
||||
let webListIndex = 0;
|
||||
this._webMenu = document.querySelector('#webMenu');
|
||||
this._webMenuList = document.querySelector('#webMenuList');
|
||||
this._webMenuListContainer = document.querySelector('#webMenuListContainer');
|
||||
this._webMenuSearchBox = document.querySelector('#webMenuSearchBox');
|
||||
|
||||
// Disable/Enable inputs
|
||||
const disableWebMenuInputs = (status) => {
|
||||
const elems = webMenu.getElementsByTagName('input');
|
||||
const len = elems.length;
|
||||
this._webMenuVisibility = false;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
elems[i].disabled = status;
|
||||
}
|
||||
}
|
||||
this._webItemFocus;
|
||||
this._webListIndex = 0;
|
||||
|
||||
// Create mouse event for passed li
|
||||
const createCallback = (li, url) => {
|
||||
// Create a callback property for the passed li
|
||||
li.callback = () => {
|
||||
window.location.href = encodeURI(url);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort list alphabetically
|
||||
const sortList = () => {
|
||||
Array.from(webMenuList.getElementsByTagName("li"))
|
||||
.sort((a, b) => a.textContent.localeCompare(b.textContent))
|
||||
.forEach(li => webMenuList.appendChild(li));
|
||||
}
|
||||
|
||||
// Populate web menu
|
||||
const populateWebMenu = () => {
|
||||
|
||||
// Generate a list
|
||||
for (let webData of webSites) {
|
||||
|
||||
const site = webData.site;
|
||||
const icon = webData.icon;
|
||||
const url = webData.url;
|
||||
|
||||
const li = document.createElement('li');
|
||||
|
||||
// Add mouseup event
|
||||
createCallback(li, url);
|
||||
|
||||
// Create a href
|
||||
const aWebLink = document.createElement('a');
|
||||
aWebLink.className = 'webMenuLink';
|
||||
aWebLink.href = url;
|
||||
aWebLink.tabIndex = '-1';
|
||||
|
||||
// Create an outer div, child of li
|
||||
let webItemDiv = document.createElement('div')
|
||||
webItemDiv.className = 'webItem';
|
||||
// webItemDiv.tabitemIndex = '1';
|
||||
webItemDiv.id = "id" + site;
|
||||
|
||||
// Create a second div, webItemContainer
|
||||
const webItemContainer = document.createElement('div');
|
||||
webItemContainer.className = 'webItemContainer';
|
||||
|
||||
// Create the innermost div, contains icon and label
|
||||
const webItemBody = document.createElement('div');
|
||||
webItemBody.className = 'webItemBody';
|
||||
|
||||
// Create div for webItemIcon
|
||||
const webItemIconContainer = document.createElement('div');
|
||||
webItemIconContainer.className = 'webItemIconContainer';
|
||||
|
||||
const webItemIcon = document.createElement('div');
|
||||
webItemIcon.className = 'webItemIcon';
|
||||
webItemIcon.style.background = "url('assets/webcons/" + icon + ".svg')";
|
||||
webItemIcon.style.backgroundSize = 'cover';
|
||||
|
||||
// Create webItemName
|
||||
const webItemName = document.createElement('div');
|
||||
webItemName.className = 'webItemName';
|
||||
webItemName.innerHTML = site;
|
||||
|
||||
// Append divs with heirarchy
|
||||
webItemDiv.appendChild(webItemContainer);
|
||||
webItemContainer.appendChild(webItemBody);
|
||||
|
||||
webItemIconContainer.appendChild(webItemIcon);
|
||||
webItemBody.appendChild(webItemIconContainer);
|
||||
webItemBody.appendChild(webItemName);
|
||||
|
||||
aWebLink.appendChild(webItemDiv);
|
||||
|
||||
li.appendChild(aWebLink);
|
||||
webMenuList.appendChild(li);
|
||||
this._fuzzySearch();
|
||||
this._init();
|
||||
}
|
||||
|
||||
// Call to sort list
|
||||
sortList();
|
||||
}
|
||||
// Return web menu status
|
||||
getwebMenuVisibility = () => {
|
||||
return this._webMenuVisibility;
|
||||
}
|
||||
|
||||
// Fuzzy search
|
||||
String.prototype.fuzzy = function(term, ratio) {
|
||||
const string = this.toLowerCase();
|
||||
const compare = term.toLowerCase();
|
||||
let matches = 0;
|
||||
|
||||
if (string.indexOf(compare) > -1) return true; // covers basic partial matches
|
||||
for (let i = 0; i < compare.length; i++) {
|
||||
string.indexOf(compare[i]) > -1 ? matches += 1 : matches -=1;
|
||||
}
|
||||
return (matches/this.length >= ratio || term == "");
|
||||
};
|
||||
// Disable textboxes
|
||||
_disableWebMenuInputs = (status) => {
|
||||
const elems = this._webMenu.getElementsByTagName('input');
|
||||
const len = elems.length;
|
||||
|
||||
// Search through the list
|
||||
const filterWebList = () => {
|
||||
for (let i = 0; i < len; i++) {
|
||||
elems[i].disabled = status;
|
||||
}
|
||||
}
|
||||
|
||||
let input, filter, ul, li, a, i, txtValue;
|
||||
// Create callback property, to be used when enter was pressed while item is focused
|
||||
_createWebItemCallback = (li, url) => {
|
||||
// Create a callback property for the passed li
|
||||
li.callback = () => {
|
||||
window.location.href = encodeURI(url);
|
||||
}
|
||||
}
|
||||
|
||||
input = webMenuSearchBox;
|
||||
filter = input.value.toUpperCase();
|
||||
ul = webMenuList;
|
||||
li = ul.getElementsByTagName('li');
|
||||
|
||||
// Loop through all list items, and focus if matches the search query
|
||||
for (let i = 0; i < li.length; i++) {
|
||||
// Sort list alphabetically
|
||||
_sortList = () => {
|
||||
Array.from(this._webMenuList.getElementsByTagName('li'))
|
||||
.sort((a, b) => a.textContent.localeCompare(b.textContent))
|
||||
.forEach(li => this._webMenuList.appendChild(li));
|
||||
}
|
||||
|
||||
a = li[i].getElementsByClassName("webItemName")[0];
|
||||
txtValue = a.innerHTML || a.textContent || a.innerText;
|
||||
// Create/generate web items
|
||||
_populateWebMenu = () => {
|
||||
|
||||
// If an item match, hightlight it and focus
|
||||
// if (txtValue.toUpperCase().indexOf(filter) !== -1) {
|
||||
if (txtValue.toUpperCase().fuzzy(filter, 1) === true) {
|
||||
// Generate a list
|
||||
for (let webData of this._webSites) {
|
||||
|
||||
const site = webData.site;
|
||||
const icon = webData.icon;
|
||||
const url = webData.url;
|
||||
|
||||
const li = document.createElement('li');
|
||||
|
||||
// Create callback property
|
||||
this._createWebItemCallback(li, url);
|
||||
|
||||
// Create a href
|
||||
const aWebLink = document.createElement('a');
|
||||
aWebLink.className = 'webMenuLink';
|
||||
aWebLink.href = url;
|
||||
aWebLink.tabIndex = '-1';
|
||||
|
||||
// Create an outer div, child of li
|
||||
let webItemDiv = document.createElement('div')
|
||||
webItemDiv.className = 'webItem';
|
||||
webItemDiv.id = 'id' + site;
|
||||
|
||||
// Unselect/Unhightlight old active
|
||||
const oldWebItemFocus = webItemFocus;
|
||||
const oldWebItemFocusChild = oldWebItemFocus.querySelector('.webItem');
|
||||
oldWebItemFocusChild.classList.remove('webItemFocus');
|
||||
// Create a second div, webItemContainer
|
||||
const webItemContainer = document.createElement('div');
|
||||
webItemContainer.className = 'webItemContainer';
|
||||
|
||||
// Update webItemFocus
|
||||
webItemFocus = li[i];
|
||||
// Create the innermost div, contains icon and label
|
||||
const webItemBody = document.createElement('div');
|
||||
webItemBody.className = 'webItemBody';
|
||||
|
||||
// Update weblistindex
|
||||
webListIndex = i;
|
||||
// Create div for webItemIcon
|
||||
const webItemIconContainer = document.createElement('div');
|
||||
webItemIconContainer.className = 'webItemIconContainer';
|
||||
|
||||
// Get child
|
||||
const webItemFocusChild = webItemFocus.querySelector('.webItem');
|
||||
// Add webItemFocus class to child
|
||||
webItemFocusChild.classList.add('webItemFocus');
|
||||
const webItemIcon = document.createElement('div');
|
||||
webItemIcon.className = 'webItemIcon';
|
||||
webItemIcon.style.background = `url('assets/webcons/${icon}.svg')`;
|
||||
webItemIcon.style.backgroundSize = 'cover';
|
||||
|
||||
// Scroll focus into active
|
||||
webItemFocus.scrollIntoView();
|
||||
// Create webItemName
|
||||
const webItemName = document.createElement('div');
|
||||
webItemName.className = 'webItemName';
|
||||
webItemName.innerHTML = site;
|
||||
|
||||
// Append divs with heirarchy
|
||||
webItemDiv.appendChild(webItemContainer);
|
||||
webItemContainer.appendChild(webItemBody);
|
||||
|
||||
webItemIconContainer.appendChild(webItemIcon);
|
||||
webItemBody.appendChild(webItemIconContainer);
|
||||
webItemBody.appendChild(webItemName);
|
||||
|
||||
aWebLink.appendChild(webItemDiv);
|
||||
|
||||
li.appendChild(aWebLink);
|
||||
this._webMenuList.appendChild(li);
|
||||
}
|
||||
|
||||
// Call to sort list
|
||||
this._sortList();
|
||||
}
|
||||
}
|
||||
|
||||
// Reset focus on web menu close
|
||||
const focusReset = () => {
|
||||
const oldWebItemFocus = webItemFocus;
|
||||
const oldWebItemFocusChild = oldWebItemFocus.querySelector('.webItem');
|
||||
|
||||
oldWebItemFocusChild.classList.remove('webItemFocus');
|
||||
webListIndex = 0;
|
||||
}
|
||||
// Allow fuzzy searching in web menu
|
||||
_fuzzySearch = () => {
|
||||
String.prototype.fuzzy = function(term, ratio) {
|
||||
const string = this.toLowerCase();
|
||||
const compare = term.toLowerCase();
|
||||
let matches = 0;
|
||||
|
||||
// Covers basic partial matches
|
||||
if (string.indexOf(compare) > -1) return true;
|
||||
|
||||
for (let i = 0; i < compare.length; i++) {
|
||||
string.indexOf(compare[i]) > -1 ? matches += 1 : matches -=1;
|
||||
}
|
||||
return ((matches / this.length) >= ratio || term == '');
|
||||
};
|
||||
}
|
||||
|
||||
// Get first item of ul
|
||||
const getFirstItem = () => {
|
||||
const ul = webMenuList;
|
||||
const li = ul.getElementsByTagName('li');
|
||||
// Focus on searched item
|
||||
_filterWebList = () => {
|
||||
|
||||
// Focus on first item
|
||||
webItemFocus = li[0];
|
||||
|
||||
// Get child
|
||||
const webItemFocusChildren = webItemFocus.querySelector('.webItem');
|
||||
|
||||
// Add webItemFocus class
|
||||
webItemFocusChildren.classList.add('webItemFocus');
|
||||
}
|
||||
|
||||
const showWebMenu = () => {
|
||||
webMenu.classList.add('showWebMenu');
|
||||
|
||||
// Enable inputs
|
||||
disableWebMenuInputs(false);
|
||||
|
||||
webMenuVisibility = !webMenuVisibility;
|
||||
|
||||
// Focus to input field
|
||||
webMenuSearchBox.focus();
|
||||
}
|
||||
|
||||
const hideWebMenu = () => {
|
||||
// Clear input field
|
||||
webMenuSearchBox.value = '';
|
||||
|
||||
// Unfocus input field
|
||||
webMenuSearchBox.blur();
|
||||
|
||||
// Refilter web list
|
||||
filterWebList();
|
||||
|
||||
// Scroll to top
|
||||
webMenuListContainer.scrollTop = 0;
|
||||
|
||||
// Reset focus item
|
||||
focusReset();
|
||||
|
||||
// Get first item
|
||||
getFirstItem();
|
||||
|
||||
webMenu.classList.remove('showWebMenu');
|
||||
|
||||
// Disable inputs
|
||||
disableWebMenuInputs(true);
|
||||
|
||||
webMenuVisibility = !webMenuVisibility;
|
||||
}
|
||||
|
||||
const toggleWebMenu = () => {
|
||||
|
||||
console.log('toggle web menu');
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileAnimRunning) return;
|
||||
|
||||
// Rotate profile
|
||||
rotateProfile();
|
||||
|
||||
if (webMenuVisibility) {
|
||||
// Hide web menu
|
||||
hideWebMenu();
|
||||
|
||||
} else {
|
||||
// Show Web menu
|
||||
showWebMenu();
|
||||
}
|
||||
|
||||
// Check if any of these are open, if yes, close it
|
||||
if (weatherScreen.classList.contains('showWeatherScreen')) {
|
||||
console.log('weather screen is open, closing...');
|
||||
hideWeatherScreen();
|
||||
return;
|
||||
|
||||
} else if (searchBoxContainer.classList.contains('showSearchBox')) {
|
||||
console.log('searchbox is open, closing...');
|
||||
hideSearchBox();
|
||||
|
||||
} else if (dashboard.classList.contains('showRightDashboard')) {
|
||||
console.log('dashboard is open, closing...');
|
||||
hideDashboard();
|
||||
}
|
||||
|
||||
// Toggle center box
|
||||
toggleCenteredBox();
|
||||
}
|
||||
|
||||
// Remove class to focused item
|
||||
const removeClass = (el, className) => {
|
||||
// Remove webItemFocus class
|
||||
const oldWebItemFocus = el.querySelector('.webItem');
|
||||
oldWebItemFocus.classList.remove('webItemFocus');
|
||||
};
|
||||
|
||||
// Add class to focused item
|
||||
const addClass = (el, className) => {
|
||||
const webItemFocusChild = el.querySelector('.webItem');
|
||||
|
||||
// Add webItemFocus class to child
|
||||
webItemFocusChild.classList.add('webItemFocus');
|
||||
|
||||
// Scroll focus into active
|
||||
webItemFocusChild.scrollIntoView();
|
||||
};
|
||||
|
||||
const navigateWithArrows = (key, len) => {
|
||||
// assign constiables to key codes
|
||||
const [right, left, down, up] = [39, 37, 40, 38];
|
||||
|
||||
const getIndexByWindowWidth = () => {
|
||||
if (window.innerWidth <= 580) { return 1 }
|
||||
// width of elements in pixels
|
||||
const menuItemWidth = 138;
|
||||
const scrollBarWidth = 10;
|
||||
// viewport width
|
||||
const vw = (unit) => window.innerWidth * (unit / 100);
|
||||
let input, filter, ul, li, a, i, txtValue;
|
||||
|
||||
// Gets the number of columns by dividing the screen width minus the padding, scroll width and
|
||||
// average of menu item width by the menu item width
|
||||
const containerWindow = ((window.innerWidth - (menuItemWidth / 2) - scrollBarWidth - vw(24)) / menuItemWidth);
|
||||
// Get rounded result
|
||||
return Math.round(containerWindow);
|
||||
}
|
||||
input = webMenuSearchBox;
|
||||
filter = input.value.toUpperCase();
|
||||
ul = this._webMenuList;
|
||||
li = ul.getElementsByTagName('li');
|
||||
|
||||
// Loop through all list items, and focus if matches the search query
|
||||
for (let i = 0; i < li.length; i++) {
|
||||
|
||||
// Determine the index position by key
|
||||
const changeWebListIndex = () => {
|
||||
switch (key) {
|
||||
case right:
|
||||
webListIndex++;
|
||||
// Clear web menu searchbox
|
||||
webMenuSearchBox.value = '';
|
||||
break;
|
||||
case left:
|
||||
webListIndex--;
|
||||
// Clear web menu searchbox
|
||||
webMenuSearchBox.value = '';
|
||||
break;
|
||||
case up:
|
||||
webListIndex = webListIndex - getIndexByWindowWidth();
|
||||
// Clear web menu searchbox
|
||||
webMenuSearchBox.value = '';
|
||||
break;
|
||||
case down:
|
||||
webListIndex = webListIndex + getIndexByWindowWidth();
|
||||
// Clear web menu searchbox
|
||||
webMenuSearchBox.value = '';
|
||||
break;
|
||||
a = li[i].getElementsByClassName('webItemName')[0];
|
||||
txtValue = a.innerHTML || a.textContent || a.innerText;
|
||||
|
||||
// If an item match, hightlight it and focus
|
||||
// if (txtValue.toUpperCase().indexOf(filter) !== -1) {
|
||||
if (txtValue.toUpperCase().fuzzy(filter, 1) === true) {
|
||||
|
||||
// Unselect/Unhightlight old active
|
||||
const oldWebItemFocus = this._webItemFocus;
|
||||
const oldWebItemFocusChild = oldWebItemFocus.querySelector('.webItem');
|
||||
oldWebItemFocusChild.classList.remove('webItemFocus');
|
||||
|
||||
// Update webItemFocus
|
||||
this._webItemFocus = li[i];
|
||||
|
||||
// Update weblistindex
|
||||
this._webListIndex = i;
|
||||
|
||||
// Get child
|
||||
const webItemFocusChild = this._webItemFocus.querySelector('.webItem');
|
||||
// Add webItemFocus class to child
|
||||
webItemFocusChild.classList.add('webItemFocus');
|
||||
|
||||
// Scroll focus into active
|
||||
this._webItemFocus.scrollIntoView();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const changeItemFocus = (condition, overFlowIndex) => {
|
||||
const next = webMenuList.getElementsByTagName('li')[webListIndex];
|
||||
if(typeof next !== undefined && condition) {
|
||||
webItemFocus = next;
|
||||
// Reset focus/go back to item #1
|
||||
_focusReset = () => {
|
||||
const oldWebItemFocus = this._webItemFocus;
|
||||
const oldWebItemFocusChild = oldWebItemFocus.querySelector('.webItem');
|
||||
|
||||
oldWebItemFocusChild.classList.remove('webItemFocus');
|
||||
this._webListIndex = 0;
|
||||
}
|
||||
|
||||
// Get item #1
|
||||
_getFirstItem = () => {
|
||||
const ul = this._webMenuList;
|
||||
const li = ul.getElementsByTagName('li');
|
||||
|
||||
// Focus on first item
|
||||
this._webItemFocus = li[0];
|
||||
|
||||
// Get child
|
||||
const webItemFocusChildren = this._webItemFocus.querySelector('.webItem');
|
||||
|
||||
// Add webItemFocus class
|
||||
webItemFocusChildren.classList.add('webItemFocus');
|
||||
}
|
||||
|
||||
// Show web menu screen
|
||||
showWebMenu = () => {
|
||||
this._webMenu.classList.add('showWebMenu');
|
||||
|
||||
// Enable inputs
|
||||
this._disableWebMenuInputs(false);
|
||||
|
||||
this._webMenuVisibility = !this._webMenuVisibility;
|
||||
|
||||
// Focus to input field
|
||||
this._webMenuSearchBox.focus();
|
||||
}
|
||||
|
||||
// Hide web menu screen
|
||||
hideWebMenu = () => {
|
||||
// Clear input field
|
||||
this._webMenuSearchBox.value = '';
|
||||
|
||||
// Unfocus input field
|
||||
this._webMenuSearchBox.blur();
|
||||
|
||||
// Refilter web list
|
||||
this._filterWebList();
|
||||
|
||||
// Scroll to top
|
||||
this._webMenuListContainer.scrollTop = 0;
|
||||
|
||||
// Reset focus item
|
||||
this._focusReset();
|
||||
|
||||
// Get first item
|
||||
this._getFirstItem();
|
||||
|
||||
this._webMenu.classList.remove('showWebMenu');
|
||||
|
||||
// Disable inputs
|
||||
this._disableWebMenuInputs(true);
|
||||
|
||||
this._webMenuVisibility = !this._webMenuVisibility;
|
||||
}
|
||||
|
||||
// Toggle web menu screen
|
||||
toggleWebMenu = () => {
|
||||
|
||||
console.log('toggle web menu');
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileImage.getProfileAnimationStatus()) return;
|
||||
|
||||
// Rotate profile
|
||||
profileImage.rotateProfile();
|
||||
|
||||
if (this._webMenuVisibility) {
|
||||
// Hide web menu
|
||||
this.hideWebMenu();
|
||||
|
||||
} else {
|
||||
// Show Web menu
|
||||
this.showWebMenu();
|
||||
}
|
||||
|
||||
// Check if any of these are open, if yes, close it
|
||||
if (searchBoxContainer.classList.contains('showSearchBox')) {
|
||||
console.log('searchbox is open, closing...');
|
||||
searchBoxShow.hideSearchBox();
|
||||
|
||||
} else if (this._dashboard.classList.contains('showRightDashboard')) {
|
||||
console.log('dashboard is open, closing...');
|
||||
dashboard.hideDashboard();
|
||||
|
||||
} else if (this._weatherScreen.classList.contains('showWeatherScreen')) {
|
||||
console.log('weather screen is open, closing...');
|
||||
weatherScreen.hideWeatherScreen();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Toggle center box
|
||||
centeredBox.toggleCenteredBox();
|
||||
}
|
||||
|
||||
// Remove focus class
|
||||
_removeClass = (el, className) => {
|
||||
// Remove webItemFocus class
|
||||
const oldWebItemFocus = el.querySelector('.webItem');
|
||||
oldWebItemFocus.classList.remove('webItemFocus');
|
||||
}
|
||||
|
||||
// Add focus class
|
||||
_addClass = (el, className) => {
|
||||
const webItemFocusChild = el.querySelector('.webItem');
|
||||
|
||||
// Add webItemFocus class to child
|
||||
webItemFocusChild.classList.add('webItemFocus');
|
||||
|
||||
// Scroll focus into active
|
||||
webItemFocusChild.scrollIntoView();
|
||||
}
|
||||
|
||||
// Arrow key navigation
|
||||
_navigateWithArrows = (key, len) => {
|
||||
// assign constiables to key codes
|
||||
const [right, left, down, up] = [39, 37, 40, 38];
|
||||
|
||||
const getIndexByWindowWidth = () => {
|
||||
if (window.innerWidth <= 580) { return 1; }
|
||||
// width of elements in pixels
|
||||
const menuItemWidth = 138;
|
||||
const scrollBarWidth = 10;
|
||||
// viewport width
|
||||
const vw = (unit) => window.innerWidth * (unit / 100);
|
||||
|
||||
// Gets the number of columns by dividing the screen width minus the padding, scroll width and
|
||||
// average of menu item width by the menu item width
|
||||
const containerWindow = ((window.innerWidth - (menuItemWidth / 2) - scrollBarWidth - vw(24)) / menuItemWidth);
|
||||
// Get rounded result
|
||||
return Math.round(containerWindow);
|
||||
}
|
||||
|
||||
// Determine the index position by key
|
||||
const changeWebListIndex = () => {
|
||||
switch (key) {
|
||||
case right:
|
||||
this._webListIndex++;
|
||||
// Clear web menu searchbox
|
||||
this._webMenuSearchBox.value = '';
|
||||
break;
|
||||
case left:
|
||||
this._webListIndex--;
|
||||
// Clear web menu searchbox
|
||||
this._webMenuSearchBox.value = '';
|
||||
break;
|
||||
case up:
|
||||
this._webListIndex = this._webListIndex - getIndexByWindowWidth();
|
||||
// Clear web menu searchbox
|
||||
this._webMenuSearchBox.value = '';
|
||||
break;
|
||||
case down:
|
||||
this._webListIndex = this._webListIndex + getIndexByWindowWidth();
|
||||
// Clear web menu searchbox
|
||||
this._webMenuSearchBox.value = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const changeItemFocus = (condition, overFlowIndex) => {
|
||||
const next = this._webMenuList.getElementsByTagName('li')[this._webListIndex];
|
||||
if(typeof next !== undefined && condition) {
|
||||
this._webItemFocus = next;
|
||||
} else {
|
||||
this._webListIndex = overFlowIndex;
|
||||
this._webItemFocus = this._webMenuList.getElementsByTagName('li')[overFlowIndex];
|
||||
}
|
||||
}
|
||||
|
||||
const changeItemFocusByKey = () => {
|
||||
if (key === right) { return changeItemFocus((this._webListIndex <= len), 0) }
|
||||
if (key === left) { return changeItemFocus((this._webListIndex >= 0), len) }
|
||||
if (key === up) { return changeItemFocus((this._webListIndex >= 0), len) }
|
||||
if (key === down) { return changeItemFocus((this._webListIndex <= len), 0) }
|
||||
}
|
||||
|
||||
|
||||
changeWebListIndex();
|
||||
if (this._webItemFocus) {
|
||||
this._removeClass(this._webItemFocus, 'webItemFocus');
|
||||
changeItemFocusByKey();
|
||||
this._addClass(this._webItemFocus, 'webItemFocus');
|
||||
// console.log(webListIndex);
|
||||
} else {
|
||||
webListIndex = overFlowIndex;
|
||||
webItemFocus = webMenuList.getElementsByTagName('li')[overFlowIndex];
|
||||
this._webListIndex = 0;
|
||||
this._webItemFocus = this._webMenuList.getElementsByTagName('li')[0];
|
||||
this._addClass(this._webItemFocus, 'webItemFocus');
|
||||
}
|
||||
}
|
||||
|
||||
const changeItemFocusByKey = () => {
|
||||
if (key === right) { return changeItemFocus((webListIndex <= len), 0) }
|
||||
if (key === left) { return changeItemFocus((webListIndex >= 0), len) }
|
||||
if (key === up) { return changeItemFocus((webListIndex >= 0), len) }
|
||||
if (key === down) { return changeItemFocus((webListIndex <= len), 0) }
|
||||
_webMenuKeyDownEvent = e => {
|
||||
const len = this._webMenuList.getElementsByTagName('li').length - 1;
|
||||
this._navigateWithArrows(e.which, len);
|
||||
}
|
||||
|
||||
|
||||
changeWebListIndex();
|
||||
if (webItemFocus) {
|
||||
removeClass(webItemFocus, 'webItemFocus');
|
||||
changeItemFocusByKey();
|
||||
addClass(webItemFocus, 'webItemFocus');
|
||||
// console.log(webListIndex);
|
||||
} else {
|
||||
webListIndex = 0;
|
||||
webItemFocus = webMenuList.getElementsByTagName('li')[0];
|
||||
addClass(webItemFocus, 'webItemFocus');
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard navigation
|
||||
webMenu.addEventListener(
|
||||
'keydown',
|
||||
(event) => {
|
||||
const len = webMenuList.getElementsByTagName('li').length - 1;
|
||||
navigateWithArrows(event.which, len);
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Type event on web mmenu search box
|
||||
webMenuSearchBox.onkeydown = (event) => {
|
||||
|
||||
// Don't hijack keyboard navigation buttons (up, down, left, right)
|
||||
if ((event.key === 'ArrowRight') || (event.key === 'ArrowDown') ||
|
||||
(event.key === 'ArrowLeft') || (event.key === 'ArrowUp')) return;
|
||||
|
||||
if (event.key === 'Tab') return;
|
||||
|
||||
if (event.key === 'Enter' && webItemFocus) {
|
||||
// Run the focused li's callback
|
||||
webItemFocus.callback();
|
||||
|
||||
// Hide web menu
|
||||
toggleWebMenu();
|
||||
|
||||
} else if (event.key === 'Backspace' && webMenuSearchBox.value.length < 1) {
|
||||
// Hide web menu if backspace is pressed and searchbox value is 0
|
||||
toggleWebMenu();
|
||||
return;
|
||||
|
||||
} else if ((event.key === 'Escape') || (event.key === 'Alt')) {
|
||||
// Ignore escape and alt key
|
||||
return;
|
||||
_registerWebMenuKeyDownEvent = () => {
|
||||
this._webMenu.addEventListener('keydown', this._webMenuKeyDownEvent, false);
|
||||
}
|
||||
|
||||
|
||||
_webMenuSearchBoxKeyDownEvent = e => {
|
||||
|
||||
// Don't hijack keyboard navigation buttons (up, down, left, right)
|
||||
if ((e.key === 'ArrowRight') || (e.key === 'ArrowDown') ||
|
||||
(e.key === 'ArrowLeft') || (e.key === 'ArrowUp')) return;
|
||||
|
||||
if (e.key === 'Tab') return;
|
||||
|
||||
if (e.key === 'Enter' && this._webItemFocus) {
|
||||
|
||||
// Run the focused li's callback
|
||||
this._webItemFocus.callback();
|
||||
|
||||
// Hide web menu
|
||||
this.toggleWebMenu();
|
||||
|
||||
} else if (e.key === 'Backspace' && webMenuSearchBox.value.length < 1) {
|
||||
// Hide web menu if backspace is pressed and searchbox value is 0
|
||||
this.toggleWebMenu();
|
||||
return;
|
||||
|
||||
} else if ((e.key === 'Escape') || (e.key === 'Alt')) {
|
||||
// Ignore escape and alt key
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter
|
||||
this._filterWebList();
|
||||
|
||||
}
|
||||
|
||||
_registerWebMenuSearchBoxKeyDownEvent = () => {
|
||||
this._webMenuSearchBox.onkeydown = this._webMenuSearchBoxKeyDownEvent;
|
||||
}
|
||||
|
||||
_init = () => {
|
||||
this._populateWebMenu();
|
||||
this._getFirstItem();
|
||||
|
||||
// Disable inputs
|
||||
this._disableWebMenuInputs(true);
|
||||
|
||||
this._registerWebMenuSearchBoxKeyDownEvent();
|
||||
this._registerWebMenuKeyDownEvent();
|
||||
}
|
||||
|
||||
// Filter
|
||||
filterWebList();
|
||||
}
|
||||
|
||||
// Populate and get first child
|
||||
const initWebMenu = () => {
|
||||
populateWebMenu();
|
||||
getFirstItem();
|
||||
|
||||
// Disable inputs
|
||||
disableWebMenuInputs(true);
|
||||
}
|
||||
|
||||
// Initialize web menu
|
||||
window.onload = initWebMenu();
|
Loading…
Reference in New Issue
Block a user