From a70554653edfcf82684e84eb3398d91aa4859bfe Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 24 Feb 2020 17:00:38 +0100 Subject: [PATCH 001/154] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 6cf71d5..2253dbb 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ Berzan.js is a specialised frontend for Novasoftware's schedule viewer and skolm It is currently perpetually developed, with features being added and bugs fixed as I find the motivation and inspiration to. The goal is to make it work across as many devices as well as possible while maintaining its stability, speed, and features. +## Features + +* Schedule viewer +* Lunch viewer +* Offline viewing of schedule (and soon lunch) +* Ability to set default class for schedule viewer +* User interface adapts to whatever device you're using + ## Third party code used * Slideout.js * Bootstrap's Reboot was used as base for the stylesheet. \ No newline at end of file From 1f9bbc3eb9da078658266fd8d787cef3d366697f Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 24 Feb 2020 17:04:04 +0100 Subject: [PATCH 002/154] Update link --- views/about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/about.html b/views/about.html index 1057eb8..68245f7 100644 --- a/views/about.html +++ b/views/about.html @@ -3,7 +3,7 @@

Kod-relaterat

-

Källkod

GitHub +

Källkod

GitHub

Bibliotek använt för slideout-menyn

Slideout.js From 0521e4560f29492e0a0708466b17a8ecfeb4ea46 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 11:19:51 +0100 Subject: [PATCH 003/154] Add link to proxy API --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 2253dbb..5b5c85e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ It is currently perpetually developed, with features being added and bugs fixed * Ability to set default class for schedule viewer * User interface adapts to whatever device you're using +## Related sources + +Code used for proxying API calls: https://gitlab.com/Newbyte/berzanjs-api + ## Third party code used * Slideout.js * Bootstrap's Reboot was used as base for the stylesheet. \ No newline at end of file From 488cdda641828b9eda5bb83eae85348473f38b48 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 11:32:58 +0100 Subject: [PATCH 004/154] Remove filetype selection as schedule now renders as HTML elements via JSON --- html/settings.html | 5 ----- js/settings.js | 16 ---------------- 2 files changed, 21 deletions(-) diff --git a/html/settings.html b/html/settings.html index bf1b0e3..1d16cba 100644 --- a/html/settings.html +++ b/html/settings.html @@ -35,11 +35,6 @@

Anpassning

-
-

Bildformat för schemat

- - -

Sida för mobilmenyn

diff --git a/js/settings.js b/js/settings.js index 1fe5775..e0361fd 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,7 +1,6 @@ function setupSettings() { const CHANGE_STARTPAGE_BUTTONS = document.getElementsByClassName("startPagePicker"); const CLASS_SAVE_FIELD = document.getElementById("defaultClass"); - const CHANGE_FILETYPE_BUTTONS = document.getElementsByClassName("filetypePicker"); const CHANGE_SLIDEOUT_SIDE_BUTTONS = document.getElementsByClassName("slideoutSidePicker"); const CHANGE_LANGUAGE_SELECTION = document.getElementById("languageSelection"); const SERVICE_WORKER_SELECTION = document.getElementById("serviceWorkerSelection"); @@ -45,21 +44,6 @@ function setupSettings() { }); } - for (let i = 0; i < CHANGE_FILETYPE_BUTTONS.length; i++) { - CHANGE_FILETYPE_BUTTONS[i].addEventListener("click", function() { - switch (i) { - case 0: - localStorage.setItem("scheduleFiletype", "png"); - showSnackbar("Schemat laddas nu som PNG"); - break; - case 1: - localStorage.setItem("scheduleFiletype", "gif"); - showSnackbar("Schemat laddas nu som GIF"); - break; - } - }); - } - for (let i = 0; i < CHANGE_SLIDEOUT_SIDE_BUTTONS.length; i++) { CHANGE_SLIDEOUT_SIDE_BUTTONS[i].addEventListener("click", function() { switch (i) { From 738689954384b2bc39cf260668dfd2769e107024 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 11:36:19 +0100 Subject: [PATCH 005/154] Remove language selection as I'm not aware of any way of querying any language that isn't Swedish in the new API --- html/settings.html | 9 --------- js/settings.js | 37 +------------------------------------ 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/html/settings.html b/html/settings.html index 1d16cba..d943b05 100644 --- a/html/settings.html +++ b/html/settings.html @@ -23,15 +23,6 @@
-
-

Språk

- -

Anpassning

diff --git a/js/settings.js b/js/settings.js index e0361fd..47ae17a 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,49 +1,14 @@ function setupSettings() { - const CHANGE_STARTPAGE_BUTTONS = document.getElementsByClassName("startPagePicker"); const CLASS_SAVE_FIELD = document.getElementById("defaultClass"); const CHANGE_SLIDEOUT_SIDE_BUTTONS = document.getElementsByClassName("slideoutSidePicker"); - const CHANGE_LANGUAGE_SELECTION = document.getElementById("languageSelection"); const SERVICE_WORKER_SELECTION = document.getElementById("serviceWorkerSelection"); const STYLE_SELECTION = document.getElementById("styleSelection"); const SLIDEOUT_FAIL_SELECTION = document.getElementById("slideoutFailWarn"); - const LANGUAGES = [ "sv-se", "en-gb", "de-de", "fr-fr" ]; - + addToggle(STYLE_SELECTION, "newDesign", updateStyle); addToggle(SERVICE_WORKER_SELECTION, "serviceWorkerEnabled", updateServiceWorker); addToggle(SLIDEOUT_FAIL_SELECTION, "slideoutWarnDisable"); - for (let i = 0; i < LANGUAGES.length; i++) { - if (LANGUAGES[i] === localStorage.getItem("appLanguage")) CHANGE_LANGUAGE_SELECTION.selectedIndex = i; - } - - CHANGE_LANGUAGE_SELECTION.addEventListener("change", function() { - localStorage.setItem("appLanguage", LANGUAGES[CHANGE_LANGUAGE_SELECTION.selectedIndex]); - if (LANGUAGES[CHANGE_LANGUAGE_SELECTION.selectedIndex] === "de-de") alert("Due to what seems to be a bug with Novasoftware (the provider of the schedule), when German is selected as language the schedule will frequently fail to load."); - }); - - for (let i = 0; i < CHANGE_STARTPAGE_BUTTONS.length; i++) { - CHANGE_STARTPAGE_BUTTONS[i].addEventListener("click", function() { - switch (i) { - case 0: - localStorage.setItem("startPage", "schedule"); - showSnackbar("Startsida bytt till schema"); - break; - case 1: - localStorage.setItem("startPage", "lunch"); - showSnackbar("Startsida bytt till lunch"); - break; - case 2: - localStorage.setItem("startPage", "etc"); - showSnackbar("Startsida bytt till övrigt"); - break; - default: - localStorage.setItem("startPage", "schedule"); - showSnackbar("Startsida bytt till schema"); - break; - } - }); - } - for (let i = 0; i < CHANGE_SLIDEOUT_SIDE_BUTTONS.length; i++) { CHANGE_SLIDEOUT_SIDE_BUTTONS[i].addEventListener("click", function() { switch (i) { From 70755903d9baa2953f2e74c40877ce5f3618124b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 11:55:14 +0100 Subject: [PATCH 006/154] Remove part of message that probably only was relevant due to my past ignorance --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 3aeaa3e..f737769 100644 --- a/js/index.js +++ b/js/index.js @@ -139,7 +139,7 @@ function init() { console.log("[Service Worker] ... failed (" + error + ")"); }); } else { - console.log("[Service Worker] Service workers are not supported (don't listen to me, I'm usually wrong on this one)"); + console.log("[Service Worker] Service workers are not supported"); } } From 4f2ce9218679e998fe576fbf75d71f35aeb05cfb Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 16:17:11 +0100 Subject: [PATCH 007/154] Show default class instead of no class if user has not interacted with input fields and switched tabs --- js/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/index.js b/js/index.js index f737769..6a46774 100644 --- a/js/index.js +++ b/js/index.js @@ -355,6 +355,7 @@ function setupNeoschedule() { updateNeoscheduleVars(); if (INPUT_FIELDS[1].value.length !== 0) { + sessionStorage.setItem("inputField1", INPUT_FIELDS[1].value); handleRenderRequest(SCHEDULE_INPUT_FORM); } From a9b6bde76448831b7ab332668d95bef069f1e3c2 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 16:20:24 +0100 Subject: [PATCH 008/154] Goodbye, old friend --- js/index.js | 133 +--------------------------------------------------- 1 file changed, 1 insertion(+), 132 deletions(-) diff --git a/js/index.js b/js/index.js index 6a46774..5dea324 100644 --- a/js/index.js +++ b/js/index.js @@ -59,9 +59,7 @@ function init() { window.onresize = function () { checkDeviceType(); - if (sessionStorage.getItem("currentView") === "schedule") { - viewSchedule(false); - } + // TODO: make schedule re-render when window is resized }; for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { @@ -438,135 +436,6 @@ function intoText(obj) { return TEXT; } -function setupSchedulePage() { - sessionStorage.setItem("inputField0", DATE.getWeek().toString()); - const INPUT_FIELDS = document.getElementsByClassName("inputField"); - const SEARCH_BUTTON = document.getElementById("searchClass"); - const DAY_DROPDOWN = document.getElementById("dayDropdown"); - const SCHEDULE = document.getElementById("schedule"); - const FORM = document.getElementById("inputForm"); - - for (let i = 0; i < INPUT_FIELDS.length; i++) { - if (sessionStorage.getItem("inputField" + i)) INPUT_FIELDS[i].value = sessionStorage.getItem("inputField" + i); - } - - if (firstScheduleLoad && localStorage.getItem("defaultClass")) { - INPUT_FIELDS[1].value = localStorage.getItem("defaultClass"); - firstScheduleLoad = false; - } - - if (isMobile) { - SEARCH_BUTTON.innerHTML = "Visa"; - } else { - SEARCH_BUTTON.innerHTML = "Visa schema"; - } - - INPUT_FIELDS[0].addEventListener("change", function() { - viewSchedule(); - }); - - DAY_DROPDOWN.onchange = function() { - scheduleInit = true; - viewSchedule(); - }; - - SCHEDULE.addEventListener("error", function() { - if (scheduleInit) - showSnackbar("Kunde inte ladda schema :("); - }); - - FORM.addEventListener("submit", function(evnt) { - evnt.preventDefault(); - scheduleInit = true; - viewSchedule(); - }); - - for (let i = 0; i < INPUT_FIELDS.length; i++) { - INPUT_FIELDS[i].addEventListener("blur", function() { - sessionStorage.setItem("inputField" + i, INPUT_FIELDS[i].value); - }); - } - - if (isMobile) { - if (DATE.getDay() < 6) { - DAY_DROPDOWN.selectedIndex = DATE.getDay() === 0 ? 1 : DATE.getDay(); - } else { - DAY_DROPDOWN.selectedIndex = 1; - } - } else { - DAY_DROPDOWN.selectedIndex = 0; - } - - if (INPUT_FIELDS[1].value.length !== 0) { - scheduleInit = true; - viewSchedule(); - sessionStorage.setItem("inputField1", INPUT_FIELDS[1].value); - } -} - -function viewSchedule(prompt) { - if (scheduleInit === false) return; - if (typeof prompt === "undefined") prompt = true; - const WEEK_INPUT_FIELD = document.getElementById("weekNumberField"); - const CLASS_INPUT_FIELD = document.getElementById("classNameField"); - const DAY_DROPDOWN = document.getElementById("dayDropdown"); - const SCHEDULE = document.getElementById("schedule"); - let currentWeek = WEEK_INPUT_FIELD.value; - let className = CLASS_INPUT_FIELD.value; - let weekDay; - - switch (DAY_DROPDOWN.selectedIndex) { - case 0: - weekDay = 0; - break; - case 1: - weekDay = 1; - break; - case 2: - weekDay = 2; - break; - case 3: - weekDay = 4; - break; - case 4: - weekDay = 8; - break; - case 5: - weekDay = 16; - break; - default: - weekDay = 0; - throw "DAY_DROPDOWN had an invalid index (" + DAY_DROPDOWN.selectedIndex.toString() + ")."; - } - - if (className.length > 0) { - SCHEDULE.onload = function() { - SCHEDULE.style.display = "block"; - }; - SCHEDULE.src = getScheduleURL(className, currentWeek, weekDay.toString(), localStorage.getItem("appLanguage"), localStorage.getItem("scheduleFiletype")); - } else if (prompt === true) { - showSnackbar("Välj en klass först"); - return; - } - - if (className === "åsna") { - loadPage("https://www.youtube.com/embed/L_jWHffIx5E"); - return; - } - - if (className === "debug") { - putPage("debug", "Debug", setupDebugMenu); - return; - } - - if (!(localStorage.getItem("defaultClass"))) - localStorage.setItem("defaultClass", CLASS_INPUT_FIELD.value); -} - -function getScheduleURL(className, week, weekDay, language, filetype) { - return "http://www.novasoftware.se/ImgGen/schedulegenerator.aspx?format=" + filetype + "&schoolid=89920/" + language + "&type=-1&id=" + className + "&period=&week=" + week + "&mode=0&printer=0&colors=32&head=0&clock=0&foot=0&day=" + weekDay + "&width=" + window.innerWidth + "&height=" + window.innerHeight; -} - function getScheduleJSON(className, week, weekDay) { return new Promise((resolve, reject) => { getClassGUIDByName(className) From a979077ff04a90c06633285b8dbb6a1d6440d5b5 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 16:21:03 +0100 Subject: [PATCH 009/154] Remove redundant variable --- js/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/index.js b/js/index.js index 5dea324..6714f7a 100644 --- a/js/index.js +++ b/js/index.js @@ -12,7 +12,6 @@ const CONTENT_DIV = document.getElementById("wrapper"); const DATE = new Date(); const MODULES = new ModuleManager(); let allowKeyNav = true; -let scheduleInit = false; let firstScheduleLoad = true; let scheduleWidth; let scheduleHeight; From 4b402ee1338176e1695c1b9c0d9261bbfef4dc41 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 16:41:00 +0100 Subject: [PATCH 010/154] Add a guide to branches --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 5b5c85e..40b13ca 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,21 @@ It is currently perpetually developed, with features being added and bugs fixed Code used for proxying API calls: https://gitlab.com/Newbyte/berzanjs-api +## Guide to branches + +* master + * Improvements/bugfixes land here first, but are not guaranteed to be of quality. + * If you are interested in contributing to Berzan.js, this is the branch you should base your code on. + * Hosted on [berzan.netlify.com](https://berzan.netlify.com) +* gh-pages (meaning GitHub pages) + * Code from master is merged in here when I consider it good enough. Code here should always be reliable + * Hosted on [berzan.js.org](https://berzan.js.org) (recommended for daily usage) +* ie11-experiment + * At one point I had the goal to get Berzan.js working in Internet Explorer 11. I didn't want to sacrifice some things code-wise, so I decided to make make a separate branch to determine how drastic the changes would have to be to support IE. Turns out Internet Explorer 11 did not only dislike my JavaScript, but also my CSS, so I gave up considering how bad this browser is overall and the limitations I would have to impose to support it. Kept for future reference. + * Anyway, this branch contains the code that makes the JavaScript work in Internet Explorer 11. CSS does not render correctly. +* serviceworker-improvements + * This was a branch I used when working on improving the broken hackjob that was my old service worker implementation. + ## Third party code used * Slideout.js * Bootstrap's Reboot was used as base for the stylesheet. \ No newline at end of file From 6a05081804ddf705c787af9b46ef91b00077104c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 16:45:49 +0100 Subject: [PATCH 011/154] Add licensing information to README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 40b13ca..533b7bf 100644 --- a/README.md +++ b/README.md @@ -33,4 +33,8 @@ Code used for proxying API calls: https://gitlab.com/Newbyte/berzanjs-api ## Third party code used * Slideout.js -* Bootstrap's Reboot was used as base for the stylesheet. \ No newline at end of file +* Bootstrap's Reboot was used as base for the stylesheet. + +## License + +Berzan.js is licensed under the Mozilla Public License Version 2. This license both imposes certain restrictions and gives you certain freedoms in regards to how you are allowed to use the code. See the file LICENSE or [this](https://www.mozilla.org/en-US/MPL/2.0/) for more information. From 5ee626341e6fb86fa3a2827a6ef4da2e23c97966 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Feb 2020 17:00:06 +0100 Subject: [PATCH 012/154] Remove experimental service worker code that never really did anything (and also was broken). --- html/settings.html | 7 ------- js/index.js | 10 ---------- js/settings.js | 2 -- sw2.js | 1 - 4 files changed, 20 deletions(-) delete mode 100644 sw2.js diff --git a/html/settings.html b/html/settings.html index d943b05..d2281e6 100644 --- a/html/settings.html +++ b/html/settings.html @@ -48,13 +48,6 @@
-
-

Utökat service worker-stöd

- -
\ No newline at end of file diff --git a/js/index.js b/js/index.js index 6714f7a..a80c12a 100644 --- a/js/index.js +++ b/js/index.js @@ -45,7 +45,6 @@ function init() { createSlideout(); checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order - updateServiceWorker(); document.getElementById("hamburgerSvg").addEventListener("click", function () { slideout.toggle(); @@ -229,15 +228,6 @@ function updateNeoscheduleVars() { } } -function updateServiceWorker() { - if (localStorage.getItem("serviceWorkerEnabled") === "on") { - const DOCUMENT_HEAD = document.getElementsByTagName("HEAD"); - const SW2 = document.createElement("SCRIPT"); - SW2.setAttribute("src", "sw2.js"); - DOCUMENT_HEAD[0].appendChild(SW2); - } -} - function updateNavBlocking() { const CONTENT_INPUT_FIELDS = document.getElementsByTagName("INPUT"); for (let i = 0; i < CONTENT_INPUT_FIELDS.length; i++) { diff --git a/js/settings.js b/js/settings.js index 47ae17a..674755e 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,12 +1,10 @@ function setupSettings() { const CLASS_SAVE_FIELD = document.getElementById("defaultClass"); const CHANGE_SLIDEOUT_SIDE_BUTTONS = document.getElementsByClassName("slideoutSidePicker"); - const SERVICE_WORKER_SELECTION = document.getElementById("serviceWorkerSelection"); const STYLE_SELECTION = document.getElementById("styleSelection"); const SLIDEOUT_FAIL_SELECTION = document.getElementById("slideoutFailWarn"); addToggle(STYLE_SELECTION, "newDesign", updateStyle); - addToggle(SERVICE_WORKER_SELECTION, "serviceWorkerEnabled", updateServiceWorker); addToggle(SLIDEOUT_FAIL_SELECTION, "slideoutWarnDisable"); for (let i = 0; i < CHANGE_SLIDEOUT_SIDE_BUTTONS.length; i++) { diff --git a/sw2.js b/sw2.js deleted file mode 100644 index ad86b2e..0000000 --- a/sw2.js +++ /dev/null @@ -1 +0,0 @@ -console.log("hello"); \ No newline at end of file From 06b837201a9accbe881197ded3ee67b6c866aae4 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 10:37:41 +0100 Subject: [PATCH 013/154] Remove initialisation code for removed features --- js/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/js/index.js b/js/index.js index a80c12a..bb67ea4 100644 --- a/js/index.js +++ b/js/index.js @@ -93,12 +93,6 @@ function init() { } } - if (localStorage.getItem("scheduleFiletype") === null) - localStorage.setItem("scheduleFiletype", "png"); - - if (localStorage.getItem("appLanguage") === null) - localStorage.setItem("appLanguage", "sv-se"); - if (localStorage.getItem("APIURLOverride") === null) localStorage.setItem("APIURLOverride", DEFAULT_API_URL); From 1ffea05b89a6e5f7140824707229850b170aa951 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 11:06:35 +0100 Subject: [PATCH 014/154] Add note regarding caching --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 533b7bf..d5d42c8 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Code used for proxying API calls: https://gitlab.com/Newbyte/berzanjs-api * Improvements/bugfixes land here first, but are not guaranteed to be of quality. * If you are interested in contributing to Berzan.js, this is the branch you should base your code on. * Hosted on [berzan.netlify.com](https://berzan.netlify.com) + * Note that this is not recommended for daily usage, and due to Berzan.js' caching strategy you may end up only getting updates when a version bump is performed regardless. * gh-pages (meaning GitHub pages) * Code from master is merged in here when I consider it good enough. Code here should always be reliable * Hosted on [berzan.js.org](https://berzan.js.org) (recommended for daily usage) From 48c766cf988241cc21f2f270b0c48f894b9b89a2 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 11:08:43 +0100 Subject: [PATCH 015/154] Add about to cache --- sw.js | 1 + 1 file changed, 1 insertion(+) diff --git a/sw.js b/sw.js index 9a15432..fba7093 100644 --- a/sw.js +++ b/sw.js @@ -10,6 +10,7 @@ const URLS_TO_CACHE = [ "/views/neoschedule.html", "/views/etc.html", "/views/settings.html", + "/views/about.html", "/manifest.json", "/img/logo/logo-512.png", "https://cdnjs.cloudflare.com/ajax/libs/slideout/1.0.1/slideout.js" From 9b06b12c017862415f00f30de4194c964bb64739 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 11:37:34 +0100 Subject: [PATCH 016/154] Remove currently shown schedule before rendering new one --- js/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index bb67ea4..3757915 100644 --- a/js/index.js +++ b/js/index.js @@ -359,9 +359,15 @@ function setupNeoschedule() { } function handleRenderRequest(form) { + const SCHEDULE_MOUNT = document.getElementById("scheduleMount"); + + while (SCHEDULE_MOUNT.firstChild) { + SCHEDULE_MOUNT.firstChild.remove(); + } + getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) .then(scheduleJSON => { - renderSchedule(scheduleJSON); + renderSchedule(scheduleJSON, SCHEDULE_MOUNT); if (!localStorage.getItem("defaultClass")) { localStorage.setItem("defaultClass", form[1].value); } @@ -371,8 +377,7 @@ function handleRenderRequest(form) { }); } -function renderSchedule(scheduleJSON) { - const SCHEDULE_MOUNT = document.getElementById("scheduleMount"); +function renderSchedule(scheduleJSON, schedule_mount) { const SCHEDULE_CONTAINER = document.createElement("DIV"); const BOXES = scheduleJSON.data.boxList; const TEXTS = scheduleJSON.data.textList; @@ -387,7 +392,7 @@ function renderSchedule(scheduleJSON) { SCHEDULE_CONTAINER.appendChild(TEXT); } - SCHEDULE_MOUNT.appendChild(SCHEDULE_CONTAINER); + schedule_mount.appendChild(SCHEDULE_CONTAINER); } function intoBox(obj) { From a367a42e34da3b1271d49457b671216f51641687 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 13:53:06 +0100 Subject: [PATCH 017/154] Fix schedule rendering above UI elements --- css/style.css | 5 +++++ js/index.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/css/style.css b/css/style.css index 936e03b..e957670 100644 --- a/css/style.css +++ b/css/style.css @@ -287,6 +287,11 @@ nav, .mobileNavButton, #schedule, #wrapper { line-height: normal; } +.scheduleElement { + position: absolute; + z-index: -1; +} + #identity { padding-top: 8px; font-size: 30px; diff --git a/js/index.js b/js/index.js index 3757915..a87e788 100644 --- a/js/index.js +++ b/js/index.js @@ -397,7 +397,7 @@ function renderSchedule(scheduleJSON, schedule_mount) { function intoBox(obj) { const BOX = document.createElement("DIV"); - BOX.style.position = "absolute"; + BOX.classList.add("scheduleElement"); BOX.style.boxSizing = "content-box"; BOX.style.backgroundColor = obj.bcolor; BOX.style.color = obj.fcolor; @@ -411,7 +411,7 @@ function intoBox(obj) { function intoText(obj) { const TEXT = document.createElement("SPAN"); - TEXT.style.position = "absolute"; + TEXT.classList.add("scheduleElement"); TEXT.style.color = obj.fcolor; TEXT.style.fontSize = obj.fontsize.toString() + "px"; TEXT.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; From 026ea4ec26c3aef5dd494fc7116f9a1eac97da06 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 14:03:49 +0100 Subject: [PATCH 018/154] Make code a little prettier --- js/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index a87e788..fb5b2b9 100644 --- a/js/index.js +++ b/js/index.js @@ -52,7 +52,12 @@ function init() { document.addEventListener("keypress", function (event) { const TAB_INDEX = parseInt(event.key); - if (!(isNaN(TAB_INDEX)) && TAB_INDEX < NAVIGATION_BUTTONS.length + 1 && TAB_INDEX > 0 && allowKeyNav) changeTab(TAB_INDEX); + if ( + !(isNaN(TAB_INDEX)) && + TAB_INDEX < NAVIGATION_BUTTONS.length + 1 && + TAB_INDEX > 0 && + allowKeyNav + ) changeTab(TAB_INDEX); }); window.onresize = function () { From b451d3bd34a9ca3b7d60dcb0c96771651f02d48c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 14:04:56 +0100 Subject: [PATCH 019/154] Remove inconsistent whitespace --- js/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/index.js b/js/index.js index fb5b2b9..199fb85 100644 --- a/js/index.js +++ b/js/index.js @@ -46,11 +46,11 @@ function init() { createSlideout(); checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order - document.getElementById("hamburgerSvg").addEventListener("click", function () { + document.getElementById("hamburgerSvg").addEventListener("click", function() { slideout.toggle(); }); - document.addEventListener("keypress", function (event) { + document.addEventListener("keypress", function(event) { const TAB_INDEX = parseInt(event.key); if ( !(isNaN(TAB_INDEX)) && @@ -60,17 +60,17 @@ function init() { ) changeTab(TAB_INDEX); }); - window.onresize = function () { + window.onresize = function() { checkDeviceType(); // TODO: make schedule re-render when window is resized }; for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { - NAVIGATION_BUTTONS[i].addEventListener("click", function () { + NAVIGATION_BUTTONS[i].addEventListener("click", function() { loadPage(i); NAVIGATION_BUTTONS[i].blur(); }); - MOBILE_NAV_BUTTONS[i].addEventListener("click", function () { + MOBILE_NAV_BUTTONS[i].addEventListener("click", function() { loadPage(i); slideout.close(); }); From 1f050dad2e3257235dcb7e544b63eb06486157ce Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 14:32:21 +0100 Subject: [PATCH 020/154] Re-render when window size changes --- js/index.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 199fb85..b42d2b6 100644 --- a/js/index.js +++ b/js/index.js @@ -13,6 +13,7 @@ const DATE = new Date(); const MODULES = new ModuleManager(); let allowKeyNav = true; let firstScheduleLoad = true; +let scheduleResizeTimer = null; let scheduleWidth; let scheduleHeight; let scheduleMarginLeft; @@ -62,7 +63,17 @@ function init() { window.onresize = function() { checkDeviceType(); - // TODO: make schedule re-render when window is resized + + if (sessionStorage.getItem("currentView") === "neoschedule") { + const INPUT_FORM = document.getElementById("scheduleInputForm"); + if (scheduleResizeTimer !== null) { + window.clearTimeout(scheduleResizeTimer); + } + scheduleResizeTimer = window.setTimeout(function() { + updateNeoscheduleVars(); + handleRenderRequest(INPUT_FORM); + }, 150); + } }; for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { From 2a69fa9af8c3cdae34fe95070d2f7ac6dcee3199 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 15:41:39 +0100 Subject: [PATCH 021/154] Schedule now better aligns with browser window size --- js/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index b42d2b6..bb314d1 100644 --- a/js/index.js +++ b/js/index.js @@ -229,12 +229,13 @@ function updateNeoscheduleVars() { if (sessionStorage.getItem("currentView") === "neoschedule") { const NAV_HEIGHT = document.getElementsByTagName("nav")[0].offsetHeight; const INPUT_FORM = document.getElementById("scheduleInputForm"); - const INPUT_FORM_HEIGHT = INPUT_FORM.offsetHeight; + const MAIN_WRAPPER_HEIGHT = document.getElementById("wrapper").offsetHeight; + const OFFSET = 5; - scheduleWidth = INPUT_FORM.offsetWidth; - scheduleHeight = window.innerHeight - NAV_HEIGHT - INPUT_FORM_HEIGHT; + scheduleWidth = INPUT_FORM.offsetWidth - 1; + scheduleHeight = window.innerHeight - MAIN_WRAPPER_HEIGHT - NAV_HEIGHT - OFFSET - 1; scheduleMarginLeft = (INPUT_FORM.offsetWidth - window.innerWidth) / 2; - scheduleMarginTop = NAV_HEIGHT + INPUT_FORM_HEIGHT + 10; + scheduleMarginTop = MAIN_WRAPPER_HEIGHT + NAV_HEIGHT + OFFSET; } } From 06a0d1cff9438a59c52f6e5cb106f10265c00329 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 15:41:54 +0100 Subject: [PATCH 022/154] Revert seek selection to right side of schedule --- views/neoschedule.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/neoschedule.html b/views/neoschedule.html index d73a4c5..6c8ba96 100644 --- a/views/neoschedule.html +++ b/views/neoschedule.html @@ -2,7 +2,7 @@ - From d7e0625dd54d917be1d32b110f121fd190eedc07 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:02:08 +0100 Subject: [PATCH 023/154] Remove old caches --- sw.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sw.js b/sw.js index fba7093..52a1949 100644 --- a/sw.js +++ b/sw.js @@ -26,6 +26,24 @@ self.addEventListener("install", function(evnt) { ); }); +self.addEventListener("activate", function(evnt) { + const CACHE_WHITELIST = [ + CACHE_NAME + ]; + + evnt.waitUntil( + caches.keys().then(cacheNames => { + return Promise.all( + cacheNames.map(cacheName => { + if (CACHE_WHITELIST.indexOf(cacheName) === -1) { + return caches.delete(cacheName); + } + }) + ); + }) + ); +}); + self.addEventListener("fetch", function(evnt){ evnt.respondWith( caches.match(evnt.request) From 151abc2eb49fb25780d4ed6d6ca91f5bfddef4e3 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:13:24 +0100 Subject: [PATCH 024/154] Rework caching. Cache is now split into app cache and content cache. App cache contains code required to get the app upp and running, and content cache any CORS requests. The content cache currently only contains schedules, but in the future this will also contain the lunch menu. --- sw.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/sw.js b/sw.js index 52a1949..ab68daf 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,7 @@ "use strict"; -const CACHE_NAME = "berzanjs-cache-v1"; +const APP_CACHE = "berzanjs-app-cache-v1"; +const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", "/css/style.css", @@ -18,7 +19,7 @@ const URLS_TO_CACHE = [ self.addEventListener("install", function(evnt) { evnt.waitUntil( - caches.open(CACHE_NAME) + caches.open(APP_CACHE) .then(function(cache) { console.log("Opened cache"); return cache.addAll(URLS_TO_CACHE); @@ -28,7 +29,8 @@ self.addEventListener("install", function(evnt) { self.addEventListener("activate", function(evnt) { const CACHE_WHITELIST = [ - CACHE_NAME + APP_CACHE, + CONTENT_CACHE ]; evnt.waitUntil( @@ -71,11 +73,18 @@ self.addEventListener("fetch", function(evnt){ const RESPONSE_TO_CACHE = response.clone(); - caches.open(CACHE_NAME) + let cacheType; + if (response.type === "cors") { + cacheType = CONTENT_CACHE; + } else { + cacheType = APP_CACHE; + } + + caches.open(cacheType) .then(function(cache) { cache.put(evnt.request, RESPONSE_TO_CACHE); }); - + return response; } ); From 54adcb728bcf405c4a2e82536308a0083dc2195c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:14:01 +0100 Subject: [PATCH 025/154] Bump version --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index ab68daf..211d04e 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1"; +const APP_CACHE = "berzanjs-app-cache-v1.1"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", From e38b19a5fb1e1dff927bf886024e36a86b1f34ca Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:23:33 +0100 Subject: [PATCH 026/154] Reintroduce start page selection (was accidentally removed when removing redundant features) --- js/settings.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/js/settings.js b/js/settings.js index 674755e..48a902d 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,4 +1,5 @@ function setupSettings() { + const CHANGE_STARTPAGE_BUTTONS = document.getElementsByClassName("startPagePicker"); const CLASS_SAVE_FIELD = document.getElementById("defaultClass"); const CHANGE_SLIDEOUT_SIDE_BUTTONS = document.getElementsByClassName("slideoutSidePicker"); const STYLE_SELECTION = document.getElementById("styleSelection"); @@ -7,6 +8,29 @@ function setupSettings() { addToggle(STYLE_SELECTION, "newDesign", updateStyle); addToggle(SLIDEOUT_FAIL_SELECTION, "slideoutWarnDisable"); + for (let i = 0; i < CHANGE_STARTPAGE_BUTTONS.length; i++) { + CHANGE_STARTPAGE_BUTTONS[i].addEventListener("click", function() { + switch (i) { + case 0: + localStorage.setItem("startPage", "schedule"); + showSnackbar("Startsida bytt till schema"); + break; + case 1: + localStorage.setItem("startPage", "lunch"); + showSnackbar("Startsida bytt till lunch"); + break; + case 2: + localStorage.setItem("startPage", "etc"); + showSnackbar("Startsida bytt till övrigt"); + break; + default: + localStorage.setItem("startPage", "schedule"); + showSnackbar("Startsida bytt till schema"); + break; + } + }); + } + for (let i = 0; i < CHANGE_SLIDEOUT_SIDE_BUTTONS.length; i++) { CHANGE_SLIDEOUT_SIDE_BUTTONS[i].addEventListener("click", function() { switch (i) { From fd8eecc22b0c5557e39cdcc2a493704b46511a22 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:23:48 +0100 Subject: [PATCH 027/154] Remove HTML markup for redundant features --- views/settings.html | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/views/settings.html b/views/settings.html index 66d7b72..1aa7d6f 100644 --- a/views/settings.html +++ b/views/settings.html @@ -13,23 +13,9 @@ -
-

Språk

- -

Anpassning

-
-

Bildformat för schemat

- - -

Sida för mobilmenyn

From 9075570dd70045f2a1cc1aeb045a6f3ef70e04a8 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:26:25 +0100 Subject: [PATCH 028/154] Remove legacy code that no longer is used as I keep editing this rather than the right one when intending to edit the views. --- html/about.html | 26 ----------------------- html/etc.html | 17 --------------- html/schedule.html | 26 ----------------------- html/settings.html | 53 ---------------------------------------------- 4 files changed, 122 deletions(-) delete mode 100644 html/about.html delete mode 100644 html/etc.html delete mode 100644 html/schedule.html delete mode 100644 html/settings.html diff --git a/html/about.html b/html/about.html deleted file mode 100644 index 38dbc1c..0000000 --- a/html/about.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - Om - - -
-
-

Källkod

GitHub -
-
-

Kod använd för slideout-menyn

Slideout.js -
-
-

Feedback

Telegram -
-
-

Webbläsare som stöds

Lista -
-
- - \ No newline at end of file diff --git a/html/etc.html b/html/etc.html deleted file mode 100644 index 7ec0796..0000000 --- a/html/etc.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - Document - - -

Verktyg

-
    -
  • Kommer (relativt) snart
  • - -
- - \ No newline at end of file diff --git a/html/schedule.html b/html/schedule.html deleted file mode 100644 index c28c9ec..0000000 --- a/html/schedule.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - Schema - - -
- - - - - Schemat för den valda tidsperioden -
- - \ No newline at end of file diff --git a/html/settings.html b/html/settings.html deleted file mode 100644 index d2281e6..0000000 --- a/html/settings.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - Inställningar - - -
-
-

Schema

-
-
-

Val av förstasida

- - - -
-
-

Val av standardklass

- - -
-
-

Anpassning

-
-
-

Sida för mobilmenyn

- - -
-
-

Övrigt

-
-
-

Återställ inställningar

- -
-
-

Experiment

-
-
-

Val av design för Berzan.js

- -
-
- - \ No newline at end of file From 96aad0ebbcb3b06e8c2e27bcb3b7278f65e0e82b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 16:28:46 +0100 Subject: [PATCH 029/154] Remove markup for "extended service worker support" setting --- views/settings.html | 7 ------- 1 file changed, 7 deletions(-) diff --git a/views/settings.html b/views/settings.html index 1aa7d6f..def9a0c 100644 --- a/views/settings.html +++ b/views/settings.html @@ -45,11 +45,4 @@
-
-

Utökat service worker-stöd

- -
\ No newline at end of file From 358bf9d72485132ddab45f8c4687cfbee7735bcd Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 17:12:09 +0100 Subject: [PATCH 030/154] Add loading screen --- css/style.css | 6 ++++++ js/index.js | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/css/style.css b/css/style.css index e957670..a617422 100644 --- a/css/style.css +++ b/css/style.css @@ -350,6 +350,12 @@ nav, .mobileNavButton, #schedule, #wrapper { font-size: medium; } +#scheduleMount { + text-align: center; + font-size: 4em; + color: #222222; +} + #hiddenMenu { background-color: #EEEEEE; overflow: hidden; diff --git a/js/index.js b/js/index.js index bb314d1..afa4498 100644 --- a/js/index.js +++ b/js/index.js @@ -382,18 +382,30 @@ function handleRenderRequest(form) { SCHEDULE_MOUNT.firstChild.remove(); } + SCHEDULE_MOUNT.style.height = scheduleHeight + "px"; + SCHEDULE_MOUNT.style.lineHeight = scheduleHeight * 0.8 + "px"; + SCHEDULE_MOUNT.style.fontWeight = "lighter"; + SCHEDULE_MOUNT.textContent = "Laddar…"; + getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) .then(scheduleJSON => { + removeLoading(SCHEDULE_MOUNT); renderSchedule(scheduleJSON, SCHEDULE_MOUNT); if (!localStorage.getItem("defaultClass")) { localStorage.setItem("defaultClass", form[1].value); } }) .catch(error => { + removeLoading(SCHEDULE_MOUNT); showSnackbar(error); }); } +function removeLoading(scheduleMount) { + scheduleMount.textContent = ""; + scheduleMount.removeAttribute("style"); +} + function renderSchedule(scheduleJSON, schedule_mount) { const SCHEDULE_CONTAINER = document.createElement("DIV"); const BOXES = scheduleJSON.data.boxList; From e67a9914214cb1d1e2fc84ddafcae4c3614a8427 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 17:12:38 +0100 Subject: [PATCH 031/154] Use camelCase instead of snake_case --- js/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index afa4498..397f659 100644 --- a/js/index.js +++ b/js/index.js @@ -406,7 +406,7 @@ function removeLoading(scheduleMount) { scheduleMount.removeAttribute("style"); } -function renderSchedule(scheduleJSON, schedule_mount) { +function renderSchedule(scheduleJSON, scheduleMount) { const SCHEDULE_CONTAINER = document.createElement("DIV"); const BOXES = scheduleJSON.data.boxList; const TEXTS = scheduleJSON.data.textList; @@ -421,7 +421,7 @@ function renderSchedule(scheduleJSON, schedule_mount) { SCHEDULE_CONTAINER.appendChild(TEXT); } - schedule_mount.appendChild(SCHEDULE_CONTAINER); + scheduleMount.appendChild(SCHEDULE_CONTAINER); } function intoBox(obj) { From 3df1e19b171520795da4d7f007cb2faf60b85f4d Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 17:37:39 +0100 Subject: [PATCH 032/154] Make loading text smaller --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index a617422..59ac3e6 100644 --- a/css/style.css +++ b/css/style.css @@ -352,7 +352,7 @@ nav, .mobileNavButton, #schedule, #wrapper { #scheduleMount { text-align: center; - font-size: 4em; + font-size: 5vh; color: #222222; } From 1e0f4c74b3e575ed13e788ec019d90657a4d761f Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 17:41:12 +0100 Subject: [PATCH 033/154] Change text size again, and use em instead of vh as the latter would result in extremely large text on tall devices --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index 59ac3e6..92229fc 100644 --- a/css/style.css +++ b/css/style.css @@ -352,7 +352,7 @@ nav, .mobileNavButton, #schedule, #wrapper { #scheduleMount { text-align: center; - font-size: 5vh; + font-size: 2.5em; color: #222222; } From 23cf4ffbfd18ec7d5b3cdd0c97e10d7d521fbd82 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 17:44:52 +0100 Subject: [PATCH 034/154] Start work on next release; bump version number --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index 211d04e..c890575 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1.1"; +const APP_CACHE = "berzanjs-app-cache-v1.2"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", From ae5c03a682e892f084f426bee46b3e5e29e3a282 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 17:50:34 +0100 Subject: [PATCH 035/154] Remove redundant code --- html/customSchedule.html | 13 ------------- views/schedule.html | 14 -------------- views/test.html | 1 - 3 files changed, 28 deletions(-) delete mode 100644 html/customSchedule.html delete mode 100644 views/schedule.html delete mode 100644 views/test.html diff --git a/html/customSchedule.html b/html/customSchedule.html deleted file mode 100644 index b356e3f..0000000 --- a/html/customSchedule.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Anpassat schema - - - - - \ No newline at end of file diff --git a/views/schedule.html b/views/schedule.html deleted file mode 100644 index e2338a5..0000000 --- a/views/schedule.html +++ /dev/null @@ -1,14 +0,0 @@ -
- - - - -
-Schemat för den valda tidsperioden \ No newline at end of file diff --git a/views/test.html b/views/test.html deleted file mode 100644 index 660736e..0000000 --- a/views/test.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 6e62a4e0069b34fe80a81188e419d2e1dbe75f32 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 26 Feb 2020 20:41:03 +0100 Subject: [PATCH 036/154] Add version field --- manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/manifest.json b/manifest.json index 0e84b83..86c8a20 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,7 @@ { "short_name": "Berzan.js", "name": "Berzan.js", + "version": "1.2", "display": "standalone", "start_url": "/", "theme_color": "#490A3D", From 2ac220941fb82390e70155dbddcf08997cadf576 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 4 Mar 2020 12:14:11 +0100 Subject: [PATCH 037/154] Work on revamping design --- css/style.css | 60 ++++++++++++++++++++------------------------- js/settings.js | 32 ++++++++++-------------- views/about.html | 12 +++------ views/settings.html | 53 +++++++++++++++++++-------------------- 4 files changed, 70 insertions(+), 87 deletions(-) diff --git a/css/style.css b/css/style.css index 92229fc..44f0a22 100644 --- a/css/style.css +++ b/css/style.css @@ -1,3 +1,16 @@ +:root { + /*--nav-bg-colour:*/ + --nav-bg-colour-hover: #FFFFFF66; + + --global-bg-colour: #FFF; + --slideout-bg-colour: #FFF; + --snackbar-bg-colour: #333; + + --normal-text-colour: #212529; + --invert-text-colour: #FFF; + --nav-text-colour: #FFF; +} + *, *::before, *::after { @@ -27,9 +40,9 @@ body { font-size: 1rem; font-weight: 400; line-height: 1.5; - color: #212529; + color: var(--normal-text-colour); text-align: left; - background-color: #fff; + background-color: var(--global-bg-colour); width: 100%; height: 100%; user-select: none; @@ -219,40 +232,22 @@ nav, .mobileNavButton, #schedule, #wrapper { } .contentItem { - text-align: center; - background-color: #7F3571; - box-shadow: 0 0 5px 2px #888888; - color: #FFFFFF; - border-radius: 10px; - padding: 10px; - margin: 5px auto; + padding: 1em; + margin: auto; width: 97%; } -.contentItem:first-of-type { - margin-top: 3vw; -} - .contentItem a:link, #contentContainer div a:visited { color: #00bfa5; } -.divider { - width: 95%; - background-color: #DDDDDD; - height: 3px; - border-radius: 3px; - margin: 20px auto; +.contentSeparatorHeader { + width: 100%; + padding: 1em; + margin: auto; } -.divider p { - margin-right: auto; - margin-left: auto; - width: 30%; - display: block; - background-color: white; - margin-top: -10px; - text-align: center; +.contentHeader { } .mobileNavButton { @@ -266,7 +261,7 @@ nav, .mobileNavButton, #schedule, #wrapper { display: flex; align-items: center; background-color: #CCCCCC; - color: #000000; + color: var(--normal-text-colour); text-transform: uppercase; cursor: pointer; } @@ -395,7 +390,7 @@ nav, .mobileNavButton, #schedule, #wrapper { visibility: hidden; min-width: 250px; margin-left: -125px; - background-color: #333; + background-color: var(--snackbar-bg-colour); color: #fff; text-align: center; border-radius: 2px; @@ -439,7 +434,7 @@ nav, .mobileNavButton, #schedule, #wrapper { position: relative; z-index: 1; will-change: transform; - background-color: #FFF; /* A background-color is required */ + background-color: var(--slideout-bg-colour); /* A background-color is required */ min-height: 100vh; } @@ -479,7 +474,7 @@ nav, .mobileNavButton, #schedule, #wrapper { .navButton { transition: 0.5s; padding: 0 20px; - color: #FFFFFF; + color: var(--nav-text-colour); display: flex; align-items: center; background: inherit; @@ -488,14 +483,13 @@ nav, .mobileNavButton, #schedule, #wrapper { .navButton:hover, .navButtonFakeHover, .navButton:focus { transition: 0.5s; - background-color: #FFFFFF66; /* #123456 */ + background-color: var(--nav-bg-colour-hover); /* #123456 */ outline: 0; } .contentItem { width: 30%; margin: 0.7vh; - flex-grow: 10; } .contentItem:first-of-type { diff --git a/js/settings.js b/js/settings.js index 48a902d..e4f2cf2 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,6 +1,6 @@ function setupSettings() { const CHANGE_STARTPAGE_BUTTONS = document.getElementsByClassName("startPagePicker"); - const CLASS_SAVE_FIELD = document.getElementById("defaultClass"); + const DEFAULT_CLASS_FORM = document.getElementById("defaultClassForm"); const CHANGE_SLIDEOUT_SIDE_BUTTONS = document.getElementsByClassName("slideoutSidePicker"); const STYLE_SELECTION = document.getElementById("styleSelection"); const SLIDEOUT_FAIL_SELECTION = document.getElementById("slideoutFailWarn"); @@ -9,7 +9,7 @@ function setupSettings() { addToggle(SLIDEOUT_FAIL_SELECTION, "slideoutWarnDisable"); for (let i = 0; i < CHANGE_STARTPAGE_BUTTONS.length; i++) { - CHANGE_STARTPAGE_BUTTONS[i].addEventListener("click", function() { + CHANGE_STARTPAGE_BUTTONS[i].addEventListener("change", function() { switch (i) { case 0: localStorage.setItem("startPage", "schedule"); @@ -19,10 +19,6 @@ function setupSettings() { localStorage.setItem("startPage", "lunch"); showSnackbar("Startsida bytt till lunch"); break; - case 2: - localStorage.setItem("startPage", "etc"); - showSnackbar("Startsida bytt till övrigt"); - break; default: localStorage.setItem("startPage", "schedule"); showSnackbar("Startsida bytt till schema"); @@ -32,7 +28,7 @@ function setupSettings() { } for (let i = 0; i < CHANGE_SLIDEOUT_SIDE_BUTTONS.length; i++) { - CHANGE_SLIDEOUT_SIDE_BUTTONS[i].addEventListener("click", function() { + CHANGE_SLIDEOUT_SIDE_BUTTONS[i].addEventListener("change", function() { switch (i) { case 0: localStorage.setItem("slideoutSide", "left"); @@ -46,28 +42,26 @@ function setupSettings() { createSlideout(); showSnackbar("Mobilmenyn flyttad till höger"); break; + default: + break; } }); } - function saveDefaultClass() { - if (CLASS_SAVE_FIELD.value.length > 0) { - localStorage.setItem("defaultClass", CLASS_SAVE_FIELD.value); - showSnackbar(CLASS_SAVE_FIELD.value + " sparad som standardklass"); + function saveDefaultClass(evnt) { + const CLASS_TEXT = evnt.target[0].value; + if (CLASS_TEXT.length > 0) { + localStorage.setItem("defaultClass", CLASS_TEXT.value); + showSnackbar(CLASS_TEXT + " sparad som standardklass"); } else { localStorage.removeItem("defaultClass"); showSnackbar("Standardklass borttagen"); } } - CLASS_SAVE_FIELD.addEventListener("keydown", function(event) { - if (event.key === "Enter") { - saveDefaultClass(); - } - }); - - document.getElementById("saveButtonThingy").addEventListener("click", function() { - saveDefaultClass(); + DEFAULT_CLASS_FORM.addEventListener("submit", function(evnt) { + evnt.preventDefault(); + saveDefaultClass(evnt); }); document.getElementById("resetButton").addEventListener("click", function() { diff --git a/views/about.html b/views/about.html index 68245f7..588d63a 100644 --- a/views/about.html +++ b/views/about.html @@ -1,25 +1,19 @@
-
-

Kod-relaterat

-
+

Kod-relaterat

Källkod

GitHub

Bibliotek använt för slideout-menyn

Slideout.js
-
-

Övrigt

-
+

Övrigt

Återkoppling

Telegram

Webbläsarstöd

Lista
-
-

Juridiskt

-
+

Juridiskt

Berzan.js är licensierad enligt Mozilla Public License 2.0. Länk till denna finns nedan, samt i källkoden

MPL 2.0 diff --git a/views/settings.html b/views/settings.html index def9a0c..9c8126b 100644 --- a/views/settings.html +++ b/views/settings.html @@ -1,45 +1,46 @@
-
-

Schema

-
+

Schema

-

Val av förstasida

- - - +

Förstasida

+ +
-

Val av standardklass

- - -
-
-

Anpassning

+

Standardklass

+
+ + +
+

Anpassning

-

Sida för mobilmenyn

- - -
-
-

Övrigt

-
+

Sida för mobilmenyn

+ + +
+

Övrigt

-

Om Slideout.js inte kan laddas

+

Om Slideout.js inte kan laddas

-

Återställ inställningar

+

Återställ inställningar

-
-

Experiment

-
+

Experiment

-

Val av design för Berzan.js

+

Val av design för Berzan.js

- + +

Anpassning

+

Sida för mobilmenyn

Övrigt

+

Om Slideout.js inte kan laddas

- + + +
+
+

Rensa cache

+

Återställ inställningar

Experiment

+
-

Val av design för Berzan.js

- +

Tema

+ +
\ No newline at end of file From ea929b16ff4652fc4d38d08f1ee17a2468141be2 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 4 Mar 2020 16:53:06 +0100 Subject: [PATCH 040/154] About section rework more or less done --- views/about.html | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/views/about.html b/views/about.html index 588d63a..9603843 100644 --- a/views/about.html +++ b/views/about.html @@ -1,21 +1,46 @@

Kod-relaterat

+
-

Källkod

GitHub +

Källkod

+

Berzan.js klient

+ +

Berzan.js backend

+
-

Bibliotek använt för slideout-menyn

Slideout.js +

Bibliotek använt för slideout-menyn

+

Övrigt

+
-

Återkoppling

Telegram +

Buggar/Återkoppling

+
-

Webbläsarstöd

Lista +

Webbläsarstöd

+

Juridiskt

+
+

Licens

Berzan.js är licensierad enligt Mozilla Public License 2.0. Länk till denna finns nedan, samt i källkoden

- MPL 2.0 +
\ No newline at end of file From 5452f4d67c81426804218f2f50da30965c868117 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 4 Mar 2020 17:44:30 +0100 Subject: [PATCH 041/154] Removed "values" parameter from setupRadio() and instead use the value from the value attribute on the HTMLElement. --- js/settings.js | 28 +++++++++------------------- views/settings.html | 16 ++++++++-------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/js/settings.js b/js/settings.js index 037270a..9aa9f75 100644 --- a/js/settings.js +++ b/js/settings.js @@ -8,10 +8,6 @@ function setupSettings() { setupRadio( CHANGE_STARTPAGE_RADIO, - [ - "schedule", - "lunch" - ], "startPage", function(value) { switch (value) { @@ -26,10 +22,6 @@ function setupSettings() { ); setupRadio( CHANGE_SLIDEOUT_SIDE_RADIO, - [ - "left", - "right" - ], "slideoutSide", function(value) { slideout.destroy(); @@ -47,18 +39,10 @@ function setupSettings() { ); setupRadio( SLIDEOUT_FAIL_RADIO, - [ - "on", - "off" - ], "slideoutWarnDisable" ); setupRadio( STYLE_RADIO, - [ - "light", - "dark" - ], "theme" ); @@ -89,7 +73,13 @@ function setupSettings() { }); } -function setupRadio(elements, values, storageKey, onchangeCallback) { +function setupRadio(elementsCollection, storageKey, onchangeCallback) { + const elements = Array.prototype.slice.call(elementsCollection); + + const values = elements.map(element => { + return element.value; + }); + for (let i = 0; i < elements.length; i++) { const element = elements[i]; @@ -100,10 +90,10 @@ function setupRadio(elements, values, storageKey, onchangeCallback) { } element.addEventListener("change", function() { - localStorage.setItem(storageKey, values[i]); + localStorage.setItem(storageKey, element.value); if (typeof onchangeCallback === "function") { - onchangeCallback(values[i]); + onchangeCallback(element.value); } }) } diff --git a/views/settings.html b/views/settings.html index 9794fb8..713891c 100644 --- a/views/settings.html +++ b/views/settings.html @@ -4,10 +4,10 @@

Schema

Förstasida

@@ -22,10 +22,10 @@

Anpassning

Sida för mobilmenyn

Övrigt

@@ -33,10 +33,10 @@

Övrigt

Om Slideout.js inte kan laddas

@@ -52,10 +52,10 @@

Experiment

Tema

\ No newline at end of file From 8a791656aeb0a67769eeacb0b3d27528a124b0ae Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 4 Mar 2020 17:44:40 +0100 Subject: [PATCH 042/154] Remove redundant variable --- js/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/settings.js b/js/settings.js index 9aa9f75..5d93318 100644 --- a/js/settings.js +++ b/js/settings.js @@ -102,7 +102,7 @@ function setupRadio(elementsCollection, storageKey, onchangeCallback) { async function deleteCaches() { await caches.keys() .then(keys => { - keys.map((key, index) => { + keys.map(key => { caches.delete(key); }) }); From 4d2eefe36487fa72411592a88783e2a004034cfd Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 5 Mar 2020 11:34:14 +0100 Subject: [PATCH 043/154] Move schedule markup to more appropriate location --- views/settings.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/views/settings.html b/views/settings.html index 713891c..5c632ee 100644 --- a/views/settings.html +++ b/views/settings.html @@ -1,15 +1,6 @@

Schema

-
-

Förstasida

- - -

Standardklass

@@ -19,6 +10,15 @@

Standardklass

Anpassning

+
+

Förstasida

+ + +

Sida för mobilmenyn

diff --git a/views/neoschedule.html b/views/neoschedule.html index 9d68049..65f6ede 100644 --- a/views/neoschedule.html +++ b/views/neoschedule.html @@ -1,6 +1,6 @@
- - + +
-
\ No newline at end of file +
diff --git a/views/schedule-reimagined.html b/views/schedule-reimagined.html index a5767ee..c124e5e 100644 --- a/views/schedule-reimagined.html +++ b/views/schedule-reimagined.html @@ -1,6 +1,6 @@ -
Valda veckas schema
-
Valda veckans måndagsschema
-
Valda veckans tisdagssschema
-
Valda veckans onsdagsschema
-
Valda veckans torsdagsschema
-
Valda veckans fredagsschema
\ No newline at end of file +
Valda veckas schema
+
Valda veckans måndagsschema
+
Valda veckans tisdagssschema
+
Valda veckans onsdagsschema
+
Valda veckans torsdagsschema
+
Valda veckans fredagsschema
diff --git a/views/settings.html b/views/settings.html index ab0f297..57cde0e 100644 --- a/views/settings.html +++ b/views/settings.html @@ -4,15 +4,15 @@

Schema

Standardklass

- - + +

Schemat växlar till nästa dag vid …

- - + +

Anpassning

@@ -20,19 +20,19 @@

Anpassning

Förstasida

Sida för mobilmenyn

Övrigt

@@ -40,10 +40,10 @@

Övrigt

Om Slideout.js inte kan laddas

@@ -59,10 +59,10 @@

Experiment

Tema

-
\ No newline at end of file +
From bc51827f4b88e21cf56e932e2cd04177f8b5c640 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 22 Jun 2020 15:56:10 +0200 Subject: [PATCH 072/154] Convert spaces to tabs --- css/restyle.css | 336 ++++++++-------- css/style.css | 520 ++++++++++++------------ html/browsers.html | 58 +-- index.html | 118 +++--- js/debugMenu.js | 30 +- js/index.js | 980 ++++++++++++++++++++++----------------------- js/settings.js | 242 +++++------ js/utils.js | 32 +- manifest.json | 30 +- sw.js | 163 ++++---- 10 files changed, 1255 insertions(+), 1254 deletions(-) diff --git a/css/restyle.css b/css/restyle.css index aee894f..3eb396a 100644 --- a/css/restyle.css +++ b/css/restyle.css @@ -1,210 +1,210 @@ *, *::before, *::after { - box-sizing: border-box; + box-sizing: border-box; } html { - font-family: sans-serif; - line-height: 1.15; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - -ms-overflow-style: scrollbar; - -webkit-tap-highlight-color: transparent; + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; } @-ms-viewport { - width: device-width; + width: device-width; } article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { - display: block; + display: block; } body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - text-align: left; - background-color: #fff; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; } [tabindex="-1"]:focus { - outline: 0 !important; + outline: 0 !important; } hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; + height: 0; + overflow: visible; } h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: 0.5rem; + margin-top: 0; + margin-bottom: 0.5rem; } p { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } abbr[title], abbr[data-original-title] { - text-decoration: underline; - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - cursor: help; - border-bottom: 0; + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; } address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit; + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; } ol, ul, dl { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } ol ol, ul ul, ol ul, ul ol { - margin-bottom: 0; + margin-bottom: 0; } dt { - font-weight: 700; + font-weight: 700; } dd { - margin-bottom: .5rem; - margin-left: 0; + margin-bottom: .5rem; + margin-left: 0; } blockquote { - margin: 0 0 1rem; + margin: 0 0 1rem; } dfn { - font-style: italic; + font-style: italic; } b, strong { - font-weight: bolder; + font-weight: bolder; } small { - font-size: 80%; + font-size: 80%; } sub, sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; } sub { - bottom: -.25em; + bottom: -.25em; } sup { - top: -.5em; + top: -.5em; } a { - color: #007bff; - text-decoration: none; - background-color: transparent; - -webkit-text-decoration-skip: objects; + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; } a:hover { - color: #0056b3; - text-decoration: underline; + color: #0056b3; + text-decoration: underline; } a:not([href]):not([tabindex]) { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } a:not([href]):not([tabindex]):focus { - outline: 0; + outline: 0; } pre, code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; + font-size: 1em; } pre { - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; - -ms-overflow-style: scrollbar; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; } figure { - margin: 0 0 1rem; + margin: 0 0 1rem; } img { - vertical-align: middle; - border-style: none; + vertical-align: middle; + border-style: none; } svg:not(:root) { - overflow: hidden; + overflow: hidden; } table { - border-collapse: collapse; + border-collapse: collapse; } caption { - padding-top: 0.75rem; - padding-bottom: 0.75rem; - color: #6c757d; - text-align: left; - caption-side: bottom; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; } th { - text-align: inherit; + text-align: inherit; } label { - display: inline-block; - margin-bottom: .5rem; + display: inline-block; + margin-bottom: .5rem; } button { - border-radius: 0; + border-radius: 0; } button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; } input, @@ -212,176 +212,176 @@ button, select, optgroup, textarea { - margin: 0; - font-family: inherit; - font-size: inherit; - line-height: inherit; + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; } button, input { - overflow: visible; + overflow: visible; } button, select { - text-transform: none; + text-transform: none; } button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - padding: 0; - border-style: none; + padding: 0; + border-style: none; } input[type="radio"], input[type="checkbox"] { - box-sizing: border-box; - padding: 0; + box-sizing: border-box; + padding: 0; } input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] { - -webkit-appearance: listbox; + -webkit-appearance: listbox; } textarea { - overflow: auto; - resize: vertical; + overflow: auto; + resize: vertical; } fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0; + min-width: 0; + padding: 0; + margin: 0; + border: 0; } legend { - display: block; - width: 100%; - max-width: 100%; - padding: 0; - margin-bottom: .5rem; - font-size: 1.5rem; - line-height: inherit; - color: inherit; - white-space: normal; + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; } progress { - vertical-align: baseline; + vertical-align: baseline; } [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } [type="search"] { - outline-offset: -2px; - -webkit-appearance: none; + outline-offset: -2px; + -webkit-appearance: none; } [type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } ::-webkit-file-upload-button { - font: inherit; - -webkit-appearance: button; + font: inherit; + -webkit-appearance: button; } output { - display: inline-block; + display: inline-block; } summary { - display: list-item; - cursor: pointer; + display: list-item; + cursor: pointer; } template { - display: none; + display: none; } [hidden] { - display: none !important; + display: none !important; } nav { - width: 100%; - background-color: #FFFFFF; - border-color: #000000; - height: 50px; + width: 100%; + background-color: #FFFFFF; + border-color: #000000; + height: 50px; } #wrapper { - width: 95%; - margin-left: auto; - margin-right: auto; + width: 95%; + margin-left: auto; + margin-right: auto; } #contentIframe { - width: 100%; - height: 80vh; - border: none; + width: 100%; + height: 80vh; + border: none; } #desktopNav { - display: none; + display: none; } #snackbar { - position: fixed; - height: 30px; - width: 200px; - background-color: #BBBBBB; - z-index: 100; - bottom: 10px; - left: 10px; - display: flex; + position: fixed; + height: 30px; + width: 200px; + background-color: #BBBBBB; + z-index: 100; + bottom: 10px; + left: 10px; + display: flex; } @media screen and (min-width: 768px) { - .navButton, .identity { - height: 50px; - text-align: center; - display: inline-block; - } - - .navButton { - transition: 0.5s; - color: #000000; - text-align: center; - } - - .navButton:hover { - transition: 0.5s; - background-color: #33333333; - } - - #wrapper { - width: 80%; - } - - #desktopNav { - display: block; - } - - #mobileDiv, #hiddenMenu { - display: none; - } + .navButton, .identity { + height: 50px; + text-align: center; + display: inline-block; + } + + .navButton { + transition: 0.5s; + color: #000000; + text-align: center; + } + + .navButton:hover { + transition: 0.5s; + background-color: #33333333; + } + + #wrapper { + width: 80%; + } + + #desktopNav { + display: block; + } + + #mobileDiv, #hiddenMenu { + display: none; + } } \ No newline at end of file diff --git a/css/style.css b/css/style.css index a87f5f5..fa85a29 100644 --- a/css/style.css +++ b/css/style.css @@ -1,132 +1,132 @@ :root { - /*--nav-bg-colour:*/ - --nav-bg-colour-hover: #FFFFFF66; + /*--nav-bg-colour:*/ + --nav-bg-colour-hover: #FFFFFF66; - --global-bg-colour: #FFF; - --invert-bg-colour: #000; - --slideout-bg-colour: #FFF; - --snackbar-bg-colour: #333; + --global-bg-colour: #FFF; + --invert-bg-colour: #000; + --slideout-bg-colour: #FFF; + --snackbar-bg-colour: #333; - --normal-text-colour: #212529; - --invert-text-colour: #FFF; - --nav-text-colour: #FFF; + --normal-text-colour: #212529; + --invert-text-colour: #FFF; + --nav-text-colour: #FFF; } *, *::before, *::after { - box-sizing: border-box; + box-sizing: border-box; } html { - font-family: sans-serif; - line-height: 1.15; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - -ms-overflow-style: scrollbar; - -webkit-tap-highlight-color: transparent; + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; } @-ms-viewport { - width: device-width; + width: device-width; } article, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { - display: block; + display: block; } body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: var(--normal-text-colour); - text-align: left; - background-color: var(--global-bg-colour); - width: 100%; - height: 100%; - user-select: none; - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: var(--normal-text-colour); + text-align: left; + background-color: var(--global-bg-colour); + width: 100%; + height: 100%; + user-select: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; } [tabindex="-1"]:focus { - outline: 0 !important; + outline: 0 !important; } h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: 0.5rem; + margin-top: 0; + margin-bottom: 0.5rem; } p { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } ol, ul, dl { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } ol ol, ul ul, ol ul, ul ol { - margin-bottom: 0; + margin-bottom: 0; } b, strong { - font-weight: bolder; + font-weight: bolder; } a { - color: #007bff; - text-decoration: none; - background-color: transparent; - -webkit-text-decoration-skip: objects; + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; } a:hover { - color: #0056b3; - text-decoration: underline; + color: #0056b3; + text-decoration: underline; } a:not([href]):not([tabindex]) { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } a:not([href]):not([tabindex]):focus { - outline: 0; + outline: 0; } img { - vertical-align: middle; - border-style: none; + vertical-align: middle; + border-style: none; } svg:not(:root) { - overflow: hidden; + overflow: hidden; } button, input[type=submit] { - border-radius: 0; - cursor: pointer; + border-radius: 0; + cursor: pointer; } button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; } input, @@ -134,287 +134,287 @@ button, select, optgroup, textarea { - margin: 0; - font-family: inherit; - font-size: inherit; - line-height: inherit; + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; } button, input { - overflow: visible; + overflow: visible; } button, select { - text-transform: none; + text-transform: none; } button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; - -moz-appearance: button; + -webkit-appearance: button; + -moz-appearance: button; } button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - padding: 0; - border-style: none; + padding: 0; + border-style: none; } input[type="radio"], input[type="checkbox"] { - box-sizing: border-box; - padding: 0; + box-sizing: border-box; + padding: 0; } input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] { - -webkit-appearance: listbox; + -webkit-appearance: listbox; } [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } nav { - height: 60px; - background-color: #490A3D; /* "Berzan-färgen": #A1274C, den jag valde: #490A3D */ - position: absolute; - position: -webkit-sticky; - position: sticky; - top: 0; - box-shadow: 0 0 5px 2px #888888; + height: 60px; + background-color: #490A3D; /* "Berzan-färgen": #A1274C, den jag valde: #490A3D */ + position: absolute; + position: -webkit-sticky; + position: sticky; + top: 0; + box-shadow: 0 0 5px 2px #888888; } h1 { - letter-spacing: 2px; - padding-top: 33vh; - margin-top: 0; - margin-bottom: 30vh; - font-size: 10vh; + letter-spacing: 2px; + padding-top: 33vh; + margin-top: 0; + margin-bottom: 30vh; + font-size: 10vh; } input { - width: 20%; - max-width: 100px; + width: 20%; + max-width: 100px; } strong { - font-size: 5vh; + font-size: 5vh; } select { - height: 30px; - min-width: 55px; - background-color: #FFFFFF; - border: 1px solid #7A7A7A; + height: 30px; + min-width: 55px; + background-color: #FFFFFF; + border: 1px solid #7A7A7A; } button.field:hover { - background-color: #DDDDDD; - border-color: #7F357177; - transition: 0.5s; + background-color: #DDDDDD; + border-color: #7F357177; + transition: 0.5s; } nav, .mobileNavButton, #schedule, #wrapper { - width: 100%; + width: 100%; } .dropdown { - display: inline-block; + display: inline-block; } .separator { - width: 100%; - height: 0.05em; - background-color: var(--invert-bg-colour); - margin-bottom: 1.5em; + width: 100%; + height: 0.05em; + background-color: var(--invert-bg-colour); + margin-bottom: 1.5em; } .contentItem { - margin-bottom: 1.5em; - width: 100%; + margin-bottom: 1.5em; + width: 100%; } .contentItem .field { - width: 30%; + width: 30%; } .contentItem a:link, #contentContainer div a:visited { - color: #00bfa5; + color: #00bfa5; } .contentSeparatorHeader { - width: 100%; + width: 100%; } .mobileNavButton { - transition: 0.5s; - height: 10vh; - padding-top: 2vh; - padding-bottom: 2vh; - padding-left: 5%; - font-size: 4vh; - font-weight: lighter; - display: flex; - align-items: center; - background-color: #CCCCCC; - color: var(--normal-text-colour); - text-transform: uppercase; - cursor: pointer; + transition: 0.5s; + height: 10vh; + padding-top: 2vh; + padding-bottom: 2vh; + padding-left: 5%; + font-size: 4vh; + font-weight: lighter; + display: flex; + align-items: center; + background-color: #CCCCCC; + color: var(--normal-text-colour); + text-transform: uppercase; + cursor: pointer; } .mobileNavButton:hover { - transition: 0.5s; - background-color: #00000066; /* #123456 */ + transition: 0.5s; + background-color: #00000066; /* #123456 */ } .field { - transition: 0.5s; - height: 30px; - color: #000; - background-color: #FFF; - padding: 4px 6px; - margin: 0; - border: 1px solid #7A7A7A; - line-height: normal; + transition: 0.5s; + height: 30px; + color: #000; + background-color: #FFF; + padding: 4px 6px; + margin: 0; + border: 1px solid #7A7A7A; + line-height: normal; } .scheduleElement { - position: absolute; - z-index: -1; + position: absolute; + z-index: -1; } #identity { - padding-top: 8px; - font-size: 30px; - color: #FFFFFF; - font-weight: normal; - text-align: center; + padding-top: 8px; + font-size: 30px; + color: #FFFFFF; + font-weight: normal; + text-align: center; } #panel { - box-shadow: -5px 0 30px 10px #888888; + box-shadow: -5px 0 30px 10px #888888; } #hamburgerSvg { - position: absolute; - margin-top: 10px; - height: 39px; + position: absolute; + margin-top: 10px; + height: 39px; } #contentContainer { - display: flex; - flex-wrap: wrap; - margin: auto; - padding: 1em; - width: 97%; + display: flex; + flex-wrap: wrap; + margin: auto; + padding: 1em; + width: 97%; } #wrapper { - margin-left: auto; - margin-right: auto; - padding-top: 5px; - overscroll-behavior: none; + margin-left: auto; + margin-right: auto; + padding-top: 5px; + overscroll-behavior: none; } #contentIframe { - height: 90vh; - width: 95%; - margin-left: 2.5%; - margin-top: -5px; - border: none; + height: 90vh; + width: 95%; + margin-left: 2.5%; + margin-top: -5px; + border: none; } #contentIframe:after { - content: "URL " attr(src) " kunde inte laddas."; + content: "URL " attr(src) " kunde inte laddas."; } #schedule { - margin-top: 0.5vh; - display: none; - height: calc(100vh - 100px); - font-size: 0; + margin-top: 0.5vh; + display: none; + height: calc(100vh - 100px); + font-size: 0; } #schedule:after { - content: "Schemat kunde inte laddas :(\A Försäkra dig att du är inloggad på nätverket, att din adblocker / contentblocker inte blockerar novasoftware.se, samt att din klass/vecka inte innehåller < eller >.\A\A(URL: " attr(src) ")"; - white-space: pre-wrap; - text-align: center; - display: block; - color: #000000; - font-size: medium; + content: "Schemat kunde inte laddas :(\A Försäkra dig att du är inloggad på nätverket, att din adblocker / contentblocker inte blockerar novasoftware.se, samt att din klass/vecka inte innehåller < eller >.\A\A(URL: " attr(src) ")"; + white-space: pre-wrap; + text-align: center; + display: block; + color: #000000; + font-size: medium; } #scheduleMount { - text-align: center; - font-size: 2.5em; - color: #222222; + text-align: center; + font-size: 2.5em; + color: #222222; } #hiddenMenu { - background-color: #EEEEEE; - overflow: hidden; + background-color: #EEEEEE; + overflow: hidden; } #dayDropdown { - float: right; + float: right; } #desktopNav { - display: none; + display: none; } #weekNumberField { - min-width: 20px; + min-width: 20px; } #classNameField { - min-width: 60px; + min-width: 60px; } #weekNumberField:out-of-range { - color: #FF0000; - border: 2px solid #FF0000; - box-shadow: none; + color: #FF0000; + border: 2px solid #FF0000; + box-shadow: none; } #aboutInformationDiv { - margin-top: 3vh; + margin-top: 3vh; } #iframeBody { - margin-top: 10px; + margin-top: 10px; } #snackbar { - visibility: hidden; - min-width: 250px; - margin-left: -125px; - background-color: var(--snackbar-bg-colour); - color: #fff; - text-align: center; - border-radius: 2px; - padding: 16px; - position: fixed; - z-index: 1; - left: 50%; - bottom: 30px; - font-size: 17px; + visibility: hidden; + min-width: 250px; + margin-left: -125px; + background-color: var(--snackbar-bg-colour); + color: #fff; + text-align: center; + border-radius: 2px; + padding: 16px; + position: fixed; + z-index: 1; + left: 50%; + bottom: 30px; + font-size: 17px; } #snackbar.show { - visibility: visible; - -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s; - animation: fadein 0.5s, fadeout 0.5s 2.5s; + visibility: visible; + -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s; + animation: fadein 0.5s, fadeout 0.5s 2.5s; } /* start of Slideout.js CSS */ @@ -460,82 +460,82 @@ nav, .mobileNavButton, #schedule, #wrapper { /* end of Slideout.js CSS */ @-webkit-keyframes fadein { - from {bottom: 0; opacity: 0;} - to {bottom: 30px; opacity: 1;} + from {bottom: 0; opacity: 0;} + to {bottom: 30px; opacity: 1;} } @keyframes fadein { - from {bottom: 0; opacity: 0;} - to {bottom: 30px; opacity: 1;} + from {bottom: 0; opacity: 0;} + to {bottom: 30px; opacity: 1;} } @-webkit-keyframes fadeout { - from {bottom: 30px; opacity: 1;} - to {bottom: 0; opacity: 0;} + from {bottom: 30px; opacity: 1;} + to {bottom: 0; opacity: 0;} } @keyframes fadeout { - from {bottom: 30px; opacity: 1;} - to {bottom: 0; opacity: 0;} + from {bottom: 30px; opacity: 1;} + to {bottom: 0; opacity: 0;} } @media screen and (min-width: 768px) { - .navButton { - transition: 0.5s; - padding: 0 20px; - color: var(--nav-text-colour); - display: flex; - align-items: center; - background: inherit; - border: none; - } - - .navButton:hover, .navButtonFakeHover, .navButton:focus { - transition: 0.5s; - background-color: var(--nav-bg-colour-hover); /* #123456 */ - outline: 0; - } - - .contentItem { - width: 20em; - } - - .contentItem:first-of-type { - margin-top: 0.7vh; - } - - #identity { - margin-top: -63px; - position: absolute; - right: 1%; - } - - #hamburgerSvg { - display: none; - } - - #contentContainer { - justify-content: flex-start; - } - - #desktopNav { - height: 100%; - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: stretch; - } - - #contentIframe { - width: 100%; - margin-left: 0; - } - - #wrapper { - width: 80%; - } - - #schedule { - height: calc(100vh - 110px); - } + .navButton { + transition: 0.5s; + padding: 0 20px; + color: var(--nav-text-colour); + display: flex; + align-items: center; + background: inherit; + border: none; + } + + .navButton:hover, .navButtonFakeHover, .navButton:focus { + transition: 0.5s; + background-color: var(--nav-bg-colour-hover); /* #123456 */ + outline: 0; + } + + .contentItem { + width: 20em; + } + + .contentItem:first-of-type { + margin-top: 0.7vh; + } + + #identity { + margin-top: -63px; + position: absolute; + right: 1%; + } + + #hamburgerSvg { + display: none; + } + + #contentContainer { + justify-content: flex-start; + } + + #desktopNav { + height: 100%; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: stretch; + } + + #contentIframe { + width: 100%; + margin-left: 0; + } + + #wrapper { + width: 80%; + } + + #schedule { + height: calc(100vh - 110px); + } } diff --git a/html/browsers.html b/html/browsers.html index 0eb813e..24211e1 100644 --- a/html/browsers.html +++ b/html/browsers.html @@ -1,35 +1,35 @@  - - - - - - Webbläsare som stöds + + + + + Webbläsare som stöds + -

Webbläsarkompatebilitet med Berzan.js

-

Webbläsare som officiellt stöds av Berzan.js

- -

Buggar som uppstår när Berzan.js används i dessa webbläsare ska rapporteras på GitHub.

-

Webbläsare som inte stöds av Berzan.js

-

Dessa webbläsare stödjer inte modern JavaScript, och kommer därför inte förbi laddningskärmen.

-

Jag var inne på att försöka få Berzan.js att fungera i Internet Explorer 11 ett tag, men även när jag lyckades få Internet Explorer 11 att acceptera min JavaScript kod så visade det sig att problemen inte stannade där, så detta lär inte hända. Koden som används för att åstadkomma detta finns att tillgå på GitHub under grenen "ie11-experiment".

-
    -
  • Microsoft Internet Explorer
  • -
  • Wine Internet Explorer
  • -
+

Webbläsarkompatebilitet med Berzan.js

+

Webbläsare som officiellt stöds av Berzan.js

+ +

Buggar som uppstår när Berzan.js används i dessa webbläsare ska rapporteras på GitHub.

+

Webbläsare som inte stöds av Berzan.js

+

Dessa webbläsare stödjer inte modern JavaScript, och kommer därför inte förbi laddningskärmen.

+

Jag var inne på att försöka få Berzan.js att fungera i Internet Explorer 11 ett tag, men även när jag lyckades få Internet Explorer 11 att acceptera min JavaScript kod så visade det sig att problemen inte stannade där, så detta lär inte hända. Koden som används för att åstadkomma detta finns att tillgå på GitHub under grenen "ie11-experiment".

+
    +
  • Microsoft Internet Explorer
  • +
  • Wine Internet Explorer
  • +
- \ No newline at end of file + diff --git a/index.html b/index.html index 239808c..aae7052 100644 --- a/index.html +++ b/index.html @@ -1,72 +1,72 @@ - - - - - - - - - - - - - Berzan.js + + + + + + + + + + + + + Berzan.js
-

Berzan.js

- - Feedback - Webbläsare som stöds +

Berzan.js

+ + Feedback - Webbläsare som stöds
-
Schema
-
Lunch
-
Övrigt
-
Inställningar
-
Om
+
Schema
+
Lunch
+
Övrigt
+
Inställningar
+
Om
- -
-
+ +
+
diff --git a/js/debugMenu.js b/js/debugMenu.js index a43d8ac..e749826 100644 --- a/js/debugMenu.js +++ b/js/debugMenu.js @@ -1,20 +1,20 @@ function setupDebugMenu() { - const SET_ITEM_INPUT = document.getElementsByClassName("setItemInput"); - const SET_ITEM_BUTTON = document.getElementById("setItemButton"); - const GET_ITEM_INPUT = document.getElementById("getItemInput"); - const GET_ITEM_BUTTON = document.getElementById("getItemButton"); - const LOAD_URL_INPUT = document.getElementById("loadURLInput"); - const LOAD_URL_BUTTON = document.getElementById("loadURLButton"); + const SET_ITEM_INPUT = document.getElementsByClassName("setItemInput"); + const SET_ITEM_BUTTON = document.getElementById("setItemButton"); + const GET_ITEM_INPUT = document.getElementById("getItemInput"); + const GET_ITEM_BUTTON = document.getElementById("getItemButton"); + const LOAD_URL_INPUT = document.getElementById("loadURLInput"); + const LOAD_URL_BUTTON = document.getElementById("loadURLButton"); - SET_ITEM_BUTTON.addEventListener("click", function() { - localStorage.setItem(SET_ITEM_INPUT[0].value, SET_ITEM_INPUT[1].value); - }); + SET_ITEM_BUTTON.addEventListener("click", function() { + localStorage.setItem(SET_ITEM_INPUT[0].value, SET_ITEM_INPUT[1].value); + }); - GET_ITEM_BUTTON.addEventListener("click", function() { - showSnackbar(localStorage.getItem(GET_ITEM_INPUT.value)); - }); + GET_ITEM_BUTTON.addEventListener("click", function() { + showSnackbar(localStorage.getItem(GET_ITEM_INPUT.value)); + }); - LOAD_URL_BUTTON.addEventListener("click", function() { - loadPage(LOAD_URL_INPUT.value); - }); + LOAD_URL_BUTTON.addEventListener("click", function() { + loadPage(LOAD_URL_INPUT.value); + }); } diff --git a/js/index.js b/js/index.js index 320f64f..30ba284 100644 --- a/js/index.js +++ b/js/index.js @@ -1,8 +1,8 @@ "use strict"; Date.prototype.getWeek = function() { - const ONEJAN = new Date(this.getFullYear(), 0, 1); - return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); + const ONEJAN = new Date(this.getFullYear(), 0, 1); + return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); }; const DEFAULT_API_URL = "https://berzanjs-api.herokuapp.com/"; @@ -23,588 +23,588 @@ let slideout; let APIURL; function ModuleManager() { - this.modules = document.getElementById("modules"); - - this.load = function(name, callback) { - const PATH = "js/" + name + ".js"; - - for (let i = 0; i < this.modules.children.length; i++) { - if (this.modules.children[i].src.endsWith(PATH)) - return; // Module is already loaded, so return - } - - const SCRIPT = document.createElement("SCRIPT"); - SCRIPT.onload = callback; - SCRIPT.src = PATH; - - this.modules.appendChild(SCRIPT); - }; + this.modules = document.getElementById("modules"); + + this.load = function(name, callback) { + const PATH = "js/" + name + ".js"; + + for (let i = 0; i < this.modules.children.length; i++) { + if (this.modules.children[i].src.endsWith(PATH)) + return; // Module is already loaded, so return + } + + const SCRIPT = document.createElement("SCRIPT"); + SCRIPT.onload = callback; + SCRIPT.src = PATH; + + this.modules.appendChild(SCRIPT); + }; } function init() { - const SPLASH_SCREEN = document.getElementById("splashScreen"); - - if (localStorage.getItem("APIURLOverride") === null) - localStorage.setItem("APIURLOverride", DEFAULT_API_URL); - - if (localStorage.getItem(SETTINGS_KEY) === null) - localStorage.setItem(SETTINGS_KEY, - JSON.stringify({ - theme: "light", - switchoverTime: { - type: "global", - values: { - all: "00:00" - } - } - }) - ); - - updateDateObject(); - createSlideout(); - checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order - - document.getElementById("hamburgerSvg").addEventListener("click", function() { - slideout.toggle(); - }); - - document.addEventListener("keypress", function(event) { - const TAB_INDEX = parseInt(event.key); - if ( - !(isNaN(TAB_INDEX)) && - TAB_INDEX < NAVIGATION_BUTTONS.length + 1 && - TAB_INDEX > 0 && - allowKeyNav - ) changeTab(TAB_INDEX); - }); - - window.onresize = function() { - checkDeviceType(); - - if (sessionStorage.getItem("currentView") === "neoschedule") { - const INPUT_FORM = document.getElementById("scheduleInputForm"); - if (scheduleResizeTimer !== null) { - window.clearTimeout(scheduleResizeTimer); - } - scheduleResizeTimer = window.setTimeout(function() { - updateNeoscheduleVars(); - handleRenderRequest(INPUT_FORM); - }, 150); - } - }; - - for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { - NAVIGATION_BUTTONS[i].addEventListener("click", function() { - loadPage(i); - NAVIGATION_BUTTONS[i].blur(); - }); - MOBILE_NAV_BUTTONS[i].addEventListener("click", function() { - loadPage(i); - slideout.close(); - }); - } - - if (sessionStorage.getItem("currentTab")) { - loadPage(parseInt(sessionStorage.getItem("currentTab"))); - } else { - switch (localStorage.getItem("startPage")) { - case "schedule": - loadPage(0); - break; - case "lunch": - loadPage(1); - break; - case "etc": - loadPage(2); - break; - case "settings": - loadPage(3); - break; - default: - loadPage(0); - break; - } - } - - APIURL = localStorage.getItem("APIURLOverride"); - - if (location.hostname === "berzan.netlify.com") - document.getElementById("identity").textContent += " (Canary)"; - - SPLASH_SCREEN.style.opacity = "0"; - setTimeout(function() { - SPLASH_SCREEN.style.display = "none"; - }, 200); - - if ("serviceWorker" in navigator) { - navigator.serviceWorker.addEventListener("message", evnt => { - console.log("Message received: " + evnt); - const URI = evnt.data.URL.split("?")[0]; - - console.log(URI); - - switch (evnt.data.URL) { - case APIURL + "/schema": - break; - case APIURL + "/klasser": - break; - default: - break; - } - }); - console.log("[Service Worker] Installing service worker ..."); - navigator.serviceWorker.register("/sw.js").then(function(registration) { - console.log("[Service Worker] ... done (" + registration + ")"); - }).catch(function(error) { - console.log("[Service Worker] ... failed (" + error + ")"); - }); - } else { - console.log("[Service Worker] Service workers are not supported"); - } + const SPLASH_SCREEN = document.getElementById("splashScreen"); + + if (localStorage.getItem("APIURLOverride") === null) + localStorage.setItem("APIURLOverride", DEFAULT_API_URL); + + if (localStorage.getItem(SETTINGS_KEY) === null) + localStorage.setItem(SETTINGS_KEY, + JSON.stringify({ + theme: "light", + switchoverTime: { + type: "global", + values: { + all: "00:00" + } + } + }) + ); + + updateDateObject(); + createSlideout(); + checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order + + document.getElementById("hamburgerSvg").addEventListener("click", function() { + slideout.toggle(); + }); + + document.addEventListener("keypress", function(event) { + const TAB_INDEX = parseInt(event.key); + if ( + !(isNaN(TAB_INDEX)) && + TAB_INDEX < NAVIGATION_BUTTONS.length + 1 && + TAB_INDEX > 0 && + allowKeyNav + ) changeTab(TAB_INDEX); + }); + + window.onresize = function() { + checkDeviceType(); + + if (sessionStorage.getItem("currentView") === "neoschedule") { + const INPUT_FORM = document.getElementById("scheduleInputForm"); + if (scheduleResizeTimer !== null) { + window.clearTimeout(scheduleResizeTimer); + } + scheduleResizeTimer = window.setTimeout(function() { + updateNeoscheduleVars(); + handleRenderRequest(INPUT_FORM); + }, 150); + } + }; + + for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { + NAVIGATION_BUTTONS[i].addEventListener("click", function() { + loadPage(i); + NAVIGATION_BUTTONS[i].blur(); + }); + MOBILE_NAV_BUTTONS[i].addEventListener("click", function() { + loadPage(i); + slideout.close(); + }); + } + + if (sessionStorage.getItem("currentTab")) { + loadPage(parseInt(sessionStorage.getItem("currentTab"))); + } else { + switch (localStorage.getItem("startPage")) { + case "schedule": + loadPage(0); + break; + case "lunch": + loadPage(1); + break; + case "etc": + loadPage(2); + break; + case "settings": + loadPage(3); + break; + default: + loadPage(0); + break; + } + } + + APIURL = localStorage.getItem("APIURLOverride"); + + if (location.hostname === "berzan.netlify.com") + document.getElementById("identity").textContent += " (Canary)"; + + SPLASH_SCREEN.style.opacity = "0"; + setTimeout(function() { + SPLASH_SCREEN.style.display = "none"; + }, 200); + + if ("serviceWorker" in navigator) { + navigator.serviceWorker.addEventListener("message", evnt => { + console.log("Message received: " + evnt); + const URI = evnt.data.URL.split("?")[0]; + + console.log(URI); + + switch (evnt.data.URL) { + case APIURL + "/schema": + break; + case APIURL + "/klasser": + break; + default: + break; + } + }); + console.log("[Service Worker] Installing service worker ..."); + navigator.serviceWorker.register("/sw.js").then(function(registration) { + console.log("[Service Worker] ... done (" + registration + ")"); + }).catch(function(error) { + console.log("[Service Worker] ... failed (" + error + ")"); + }); + } else { + console.log("[Service Worker] Service workers are not supported"); + } } function AJAXRequest(URL) { - return new Promise(function(resolve, reject) { - const REQUEST = new XMLHttpRequest(); - REQUEST.open("GET", URL, true); - REQUEST.onload = function() { - resolve(REQUEST.responseText); - }; - REQUEST.onerror = function() { - reject(REQUEST.statusText); - }; - REQUEST.send(); - }); + return new Promise(function(resolve, reject) { + const REQUEST = new XMLHttpRequest(); + REQUEST.open("GET", URL, true); + REQUEST.onload = function() { + resolve(REQUEST.responseText); + }; + REQUEST.onerror = function() { + reject(REQUEST.statusText); + }; + REQUEST.send(); + }); } function APIFetch(query, options = {}) { - return fetch(APIURL + query, options); + return fetch(APIURL + query, options); } function changeTab(tabIndex) { - tabIndex--; - loadPage(tabIndex); - NAVIGATION_BUTTONS[tabIndex].classList.add("navButtonFakeHover"); - setTimeout(function() { - NAVIGATION_BUTTONS[tabIndex].classList.remove("navButtonFakeHover"); - }, 250); + tabIndex--; + loadPage(tabIndex); + NAVIGATION_BUTTONS[tabIndex].classList.add("navButtonFakeHover"); + setTimeout(function() { + NAVIGATION_BUTTONS[tabIndex].classList.remove("navButtonFakeHover"); + }, 250); } function createSlideout() { - if (window["Slideout"]) { - const slideoutMenu = document.getElementById("hiddenMenu"); - const hamburgerMenu = document.getElementById("hamburgerSvg"); - if (localStorage.getItem("slideoutSide") === null || localStorage.getItem("slideoutSide") === "left") { - slideoutMenu.classList.remove("slideout-menu-right"); - hamburgerMenu.style.removeProperty("right"); - hamburgerMenu.style.left = "5%"; - slideout = new Slideout({ - "panel": document.getElementById("panel"), - "menu": document.getElementById("hiddenMenu"), - "padding": 256, - "tolerance": 0 - }); - } else { - slideoutMenu.classList.remove("slideout-menu-left"); - hamburgerMenu.style.removeProperty("left"); - hamburgerMenu.style.right = "5%"; - slideout = new Slideout({ - "panel": document.getElementById("panel"), - "menu": document.getElementById("hiddenMenu"), - "padding": 256, - "tolerance": 0, - "side": "right" - }); - } - } else { - if (localStorage.getItem("slideoutWarnDisable") !== "on") - alert("Din webbläsare tycks blockera Slideout.js, ett bibliotek Berzan.js använder. Berzan.js bör fungera ändå, men vissa saker lär vara trasiga. Testa att stäng av din adblocker (eller liknande) och se om problemet kvarstår."); - document.getElementById("hiddenMenu").style.display = "none"; - slideout = { close() {} } - } + if (window["Slideout"]) { + const slideoutMenu = document.getElementById("hiddenMenu"); + const hamburgerMenu = document.getElementById("hamburgerSvg"); + if (localStorage.getItem("slideoutSide") === null || localStorage.getItem("slideoutSide") === "left") { + slideoutMenu.classList.remove("slideout-menu-right"); + hamburgerMenu.style.removeProperty("right"); + hamburgerMenu.style.left = "5%"; + slideout = new Slideout({ + "panel": document.getElementById("panel"), + "menu": document.getElementById("hiddenMenu"), + "padding": 256, + "tolerance": 0 + }); + } else { + slideoutMenu.classList.remove("slideout-menu-left"); + hamburgerMenu.style.removeProperty("left"); + hamburgerMenu.style.right = "5%"; + slideout = new Slideout({ + "panel": document.getElementById("panel"), + "menu": document.getElementById("hiddenMenu"), + "padding": 256, + "tolerance": 0, + "side": "right" + }); + } + } else { + if (localStorage.getItem("slideoutWarnDisable") !== "on") + alert("Din webbläsare tycks blockera Slideout.js, ett bibliotek Berzan.js använder. Berzan.js bör fungera ändå, men vissa saker lär vara trasiga. Testa att stäng av din adblocker (eller liknande) och se om problemet kvarstår."); + document.getElementById("hiddenMenu").style.display = "none"; + slideout = { close() {} } + } } function checkDeviceType() { - if (window.innerWidth > 768) { - slideout.close(); - isMobile = false; - } else { - isMobile = true; - } + if (window.innerWidth > 768) { + slideout.close(); + isMobile = false; + } else { + isMobile = true; + } } function showSnackbar(text) { - MODULES.load("utils", function() { - showSnackbar(text); - }); + MODULES.load("utils", function() { + showSnackbar(text); + }); } function updateDateObject() { - const SETTINGS = getSettingsObj(); + const SETTINGS = getSettingsObj(); - if (SETTINGS.hasOwnProperty("switchoverTime")) { - const NOW_DATE = new Date(); - const DATE_AND_TIME_ARR = SETTINGS.switchoverTime.values.all.split(":"); - console.log(DATE_AND_TIME_ARR); + if (SETTINGS.hasOwnProperty("switchoverTime")) { + const NOW_DATE = new Date(); + const DATE_AND_TIME_ARR = SETTINGS.switchoverTime.values.all.split(":"); + console.log(DATE_AND_TIME_ARR); - DATE.setHours(NOW_DATE.getHours() + parseInt(DATE_AND_TIME_ARR[0])); - DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); - } + DATE.setHours(NOW_DATE.getHours() + parseInt(DATE_AND_TIME_ARR[0])); + DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); + } } function updateNeoscheduleVars() { - if (sessionStorage.getItem("currentView") === "neoschedule") { - const NAV_HEIGHT = document.getElementsByTagName("nav")[0].offsetHeight; - const INPUT_FORM = document.getElementById("scheduleInputForm"); - const MAIN_WRAPPER_HEIGHT = document.getElementById("wrapper").offsetHeight; - const OFFSET = 5; - - // -1 is needed to not produce scollbars for some reason - scheduleWidth = INPUT_FORM.offsetWidth - 1; - scheduleHeight = window.innerHeight - MAIN_WRAPPER_HEIGHT - NAV_HEIGHT - OFFSET - 1; - scheduleMarginLeft = (INPUT_FORM.offsetWidth - window.innerWidth) / 2; - scheduleMarginTop = MAIN_WRAPPER_HEIGHT + NAV_HEIGHT + OFFSET; - } + if (sessionStorage.getItem("currentView") === "neoschedule") { + const NAV_HEIGHT = document.getElementsByTagName("nav")[0].offsetHeight; + const INPUT_FORM = document.getElementById("scheduleInputForm"); + const MAIN_WRAPPER_HEIGHT = document.getElementById("wrapper").offsetHeight; + const OFFSET = 5; + + // -1 is needed to not produce scollbars for some reason + scheduleWidth = INPUT_FORM.offsetWidth - 1; + scheduleHeight = window.innerHeight - MAIN_WRAPPER_HEIGHT - NAV_HEIGHT - OFFSET - 1; + scheduleMarginLeft = (INPUT_FORM.offsetWidth - window.innerWidth) / 2; + scheduleMarginTop = MAIN_WRAPPER_HEIGHT + NAV_HEIGHT + OFFSET; + } } function updateNavBlocking() { - const CONTENT_INPUT_FIELDS = document.getElementsByTagName("INPUT"); - for (let i = 0; i < CONTENT_INPUT_FIELDS.length; i++) { - CONTENT_INPUT_FIELDS[i].addEventListener("focus", function() { - allowKeyNav = false; - }); - CONTENT_INPUT_FIELDS[i].addEventListener("blur", function() { - allowKeyNav = true; - }); - } + const CONTENT_INPUT_FIELDS = document.getElementsByTagName("INPUT"); + for (let i = 0; i < CONTENT_INPUT_FIELDS.length; i++) { + CONTENT_INPUT_FIELDS[i].addEventListener("focus", function() { + allowKeyNav = false; + }); + CONTENT_INPUT_FIELDS[i].addEventListener("blur", function() { + allowKeyNav = true; + }); + } } function loadPage(page) { - switch(page) { - case 0: - putPage("neoschedule", "Schema", setupNeoschedule); - break; - case 1: - putPage("lunch", "Lunch"); - break; - case 2: - putPage("etc", "Övrigt"); - break; - case 3: - putPage("settings", "Inställningar", setupSettings); - break; - case 4: - putPage("about", "Om"); - break; - default: - if (typeof page === "string") { - createExternalPageViewer(page); - } else { - throw "Invalid argument \"" + page + "\" passed to loadPage()"; - } - return; - } - for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { - if (i !== page) { - MOBILE_NAV_BUTTONS[i].removeAttribute("style"); - NAVIGATION_BUTTONS[i].removeAttribute("style"); - } - } - MOBILE_NAV_BUTTONS[page].style.backgroundColor = "#00000066"; - NAVIGATION_BUTTONS[page].style.textShadow = "0 0 8px #FFF"; - sessionStorage.setItem("currentTab", page.toString()); + switch(page) { + case 0: + putPage("neoschedule", "Schema", setupNeoschedule); + break; + case 1: + putPage("lunch", "Lunch"); + break; + case 2: + putPage("etc", "Övrigt"); + break; + case 3: + putPage("settings", "Inställningar", setupSettings); + break; + case 4: + putPage("about", "Om"); + break; + default: + if (typeof page === "string") { + createExternalPageViewer(page); + } else { + throw "Invalid argument \"" + page + "\" passed to loadPage()"; + } + return; + } + for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { + if (i !== page) { + MOBILE_NAV_BUTTONS[i].removeAttribute("style"); + NAVIGATION_BUTTONS[i].removeAttribute("style"); + } + } + MOBILE_NAV_BUTTONS[page].style.backgroundColor = "#00000066"; + NAVIGATION_BUTTONS[page].style.textShadow = "0 0 8px #FFF"; + sessionStorage.setItem("currentTab", page.toString()); } function putPage(source, name, func) { - const PAGE_TITLE = document.getElementById("titleName"); - - loadHTML("views/" + source + ".html").then(function() { - if (name) { - PAGE_TITLE.innerHTML = name + " - Berzan.js"; - } else { - PAGE_TITLE.innerHTML = "Berzan.js"; - } - if (typeof func === "function") - func(); - updateNavBlocking(); - }); - sessionStorage.setItem("currentView", source); + const PAGE_TITLE = document.getElementById("titleName"); + + loadHTML("views/" + source + ".html").then(function() { + if (name) { + PAGE_TITLE.innerHTML = name + " - Berzan.js"; + } else { + PAGE_TITLE.innerHTML = "Berzan.js"; + } + if (typeof func === "function") + func(); + updateNavBlocking(); + }); + sessionStorage.setItem("currentView", source); } function loadHTML(URL) { - return new Promise(function(resolve) { - if (typeof URL === "string") { - AJAXRequest(URL).then(function(requestedHTML) { - CONTENT_DIV.innerHTML = requestedHTML; - resolve(); - }); - } else { - throw "Invalid argument passed to loadHTML()"; - } - }); + return new Promise(function(resolve) { + if (typeof URL === "string") { + AJAXRequest(URL).then(function(requestedHTML) { + CONTENT_DIV.innerHTML = requestedHTML; + resolve(); + }); + } else { + throw "Invalid argument passed to loadHTML()"; + } + }); } function createExternalPageViewer(URL) { - MODULES.load("utils", function() { - createExternalPageViewer(URL); - }); + MODULES.load("utils", function() { + createExternalPageViewer(URL); + }); } function setupNeoschedule() { - const SCHEDULE_INPUT_FORM = document.getElementById("scheduleInputForm"); - const INPUT_FIELDS = document.getElementsByClassName("inputField"); - const SUBMIT_BUTTON = SCHEDULE_INPUT_FORM[2]; - const DAY_DROPDOWN = SCHEDULE_INPUT_FORM[3]; - sessionStorage.setItem("inputField0", DATE.getWeek().toString()); - - for (let i = 0; i < INPUT_FIELDS.length; i++) { - if (sessionStorage.getItem("inputField" + i)) - INPUT_FIELDS[i].value = sessionStorage.getItem("inputField" + i); - } - - if ( - localStorage.getItem("defaultClass") && - INPUT_FIELDS[1].value.length === 0 - ) { - INPUT_FIELDS[1].value = localStorage.getItem("defaultClass"); - } - - if (isMobile) { - SUBMIT_BUTTON.textContent = "Visa"; - if (DATE.getDay() < 6) { - DAY_DROPDOWN.selectedIndex = DATE.getDay() === 0 ? 1 : DATE.getDay(); - } else { - DAY_DROPDOWN.selectedIndex = 1; - } - } else { - SUBMIT_BUTTON.textContent = "Visa schema"; - DAY_DROPDOWN.selectedIndex = 0; - } - - updateNeoscheduleVars(); - - if (INPUT_FIELDS[1].value.length !== 0) { - sessionStorage.setItem("inputField1", INPUT_FIELDS[1].value); - handleRenderRequest(SCHEDULE_INPUT_FORM); - } - - for (let i = 0; i < INPUT_FIELDS.length; i++) { - INPUT_FIELDS[i].addEventListener("blur", function() { - sessionStorage.setItem("inputField" + i, INPUT_FIELDS[i].value); - }); - } - - SCHEDULE_INPUT_FORM.addEventListener("submit", function(evnt) { - evnt.preventDefault(); - handleRenderRequest(SCHEDULE_INPUT_FORM); - }); - DAY_DROPDOWN.addEventListener("change", function() { - handleRenderRequest(SCHEDULE_INPUT_FORM); - }); - INPUT_FIELDS[0].addEventListener("change", function() { - handleRenderRequest(SCHEDULE_INPUT_FORM); - }); + const SCHEDULE_INPUT_FORM = document.getElementById("scheduleInputForm"); + const INPUT_FIELDS = document.getElementsByClassName("inputField"); + const SUBMIT_BUTTON = SCHEDULE_INPUT_FORM[2]; + const DAY_DROPDOWN = SCHEDULE_INPUT_FORM[3]; + sessionStorage.setItem("inputField0", DATE.getWeek().toString()); + + for (let i = 0; i < INPUT_FIELDS.length; i++) { + if (sessionStorage.getItem("inputField" + i)) + INPUT_FIELDS[i].value = sessionStorage.getItem("inputField" + i); + } + + if ( + localStorage.getItem("defaultClass") && + INPUT_FIELDS[1].value.length === 0 + ) { + INPUT_FIELDS[1].value = localStorage.getItem("defaultClass"); + } + + if (isMobile) { + SUBMIT_BUTTON.textContent = "Visa"; + if (DATE.getDay() < 6) { + DAY_DROPDOWN.selectedIndex = DATE.getDay() === 0 ? 1 : DATE.getDay(); + } else { + DAY_DROPDOWN.selectedIndex = 1; + } + } else { + SUBMIT_BUTTON.textContent = "Visa schema"; + DAY_DROPDOWN.selectedIndex = 0; + } + + updateNeoscheduleVars(); + + if (INPUT_FIELDS[1].value.length !== 0) { + sessionStorage.setItem("inputField1", INPUT_FIELDS[1].value); + handleRenderRequest(SCHEDULE_INPUT_FORM); + } + + for (let i = 0; i < INPUT_FIELDS.length; i++) { + INPUT_FIELDS[i].addEventListener("blur", function() { + sessionStorage.setItem("inputField" + i, INPUT_FIELDS[i].value); + }); + } + + SCHEDULE_INPUT_FORM.addEventListener("submit", function(evnt) { + evnt.preventDefault(); + handleRenderRequest(SCHEDULE_INPUT_FORM); + }); + DAY_DROPDOWN.addEventListener("change", function() { + handleRenderRequest(SCHEDULE_INPUT_FORM); + }); + INPUT_FIELDS[0].addEventListener("change", function() { + handleRenderRequest(SCHEDULE_INPUT_FORM); + }); } function handleRenderRequest(form) { - const SCHEDULE_MOUNT = document.getElementById("scheduleMount"); - - while (SCHEDULE_MOUNT.firstChild) { - SCHEDULE_MOUNT.firstChild.remove(); - } - - SCHEDULE_MOUNT.style.height = scheduleHeight + "px"; - SCHEDULE_MOUNT.style.lineHeight = scheduleHeight * 0.8 + "px"; - SCHEDULE_MOUNT.style.fontWeight = "lighter"; - SCHEDULE_MOUNT.textContent = "Laddar…"; - - getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) - .then(scheduleJSON => { - removeLoading(SCHEDULE_MOUNT); - renderSchedule(scheduleJSON, SCHEDULE_MOUNT); - if (!localStorage.getItem("defaultClass")) { - localStorage.setItem("defaultClass", form[1].value); - } - }) - .catch(error => { - removeLoading(SCHEDULE_MOUNT); - showSnackbar(error); - }); + const SCHEDULE_MOUNT = document.getElementById("scheduleMount"); + + while (SCHEDULE_MOUNT.firstChild) { + SCHEDULE_MOUNT.firstChild.remove(); + } + + SCHEDULE_MOUNT.style.height = scheduleHeight + "px"; + SCHEDULE_MOUNT.style.lineHeight = scheduleHeight * 0.8 + "px"; + SCHEDULE_MOUNT.style.fontWeight = "lighter"; + SCHEDULE_MOUNT.textContent = "Laddar…"; + + getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) + .then(scheduleJSON => { + removeLoading(SCHEDULE_MOUNT); + renderSchedule(scheduleJSON, SCHEDULE_MOUNT); + if (!localStorage.getItem("defaultClass")) { + localStorage.setItem("defaultClass", form[1].value); + } + }) + .catch(error => { + removeLoading(SCHEDULE_MOUNT); + showSnackbar(error); + }); } function removeLoading(scheduleMount) { - scheduleMount.textContent = ""; - scheduleMount.removeAttribute("style"); + scheduleMount.textContent = ""; + scheduleMount.removeAttribute("style"); } function renderSchedule(scheduleJSON, scheduleMount) { - const SCHEDULE_CONTAINER = document.createElement("DIV"); - const BOXES = scheduleJSON.data.boxList; - const TEXTS = scheduleJSON.data.textList; + const SCHEDULE_CONTAINER = document.createElement("DIV"); + const BOXES = scheduleJSON.data.boxList; + const TEXTS = scheduleJSON.data.textList; - for (let i = 0; i < BOXES.length; i++) { - const BOX = intoBox(BOXES[i]); - SCHEDULE_CONTAINER.appendChild(BOX); - } + for (let i = 0; i < BOXES.length; i++) { + const BOX = intoBox(BOXES[i]); + SCHEDULE_CONTAINER.appendChild(BOX); + } - for (let i = 0; i < TEXTS.length; i++) { - const TEXT = intoText(TEXTS[i]); - SCHEDULE_CONTAINER.appendChild(TEXT); - } + for (let i = 0; i < TEXTS.length; i++) { + const TEXT = intoText(TEXTS[i]); + SCHEDULE_CONTAINER.appendChild(TEXT); + } - scheduleMount.appendChild(SCHEDULE_CONTAINER); + scheduleMount.appendChild(SCHEDULE_CONTAINER); } function intoBox(obj) { - const BOX = document.createElement("DIV"); - BOX.classList.add("scheduleElement"); - BOX.style.boxSizing = "content-box"; - BOX.style.backgroundColor = obj.bcolor; - BOX.style.color = obj.fcolor; - BOX.style.height = obj.height.toString() + "px"; - BOX.style.width = obj.width.toString() + "px"; - BOX.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; - BOX.style.top = (obj.y + scheduleMarginTop).toString() + "px"; - BOX.style.border = "1px solid rgb(0, 0, 0)"; - return BOX; + const BOX = document.createElement("DIV"); + BOX.classList.add("scheduleElement"); + BOX.style.boxSizing = "content-box"; + BOX.style.backgroundColor = obj.bcolor; + BOX.style.color = obj.fcolor; + BOX.style.height = obj.height.toString() + "px"; + BOX.style.width = obj.width.toString() + "px"; + BOX.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; + BOX.style.top = (obj.y + scheduleMarginTop).toString() + "px"; + BOX.style.border = "1px solid rgb(0, 0, 0)"; + return BOX; } function intoText(obj) { - const TEXT = document.createElement("SPAN"); - TEXT.classList.add("scheduleElement"); - TEXT.style.color = obj.fcolor; - TEXT.style.fontSize = obj.fontsize.toString() + "px"; - TEXT.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; - TEXT.style.top = (obj.y + scheduleMarginTop).toString() + "px"; - TEXT.textContent = obj.text; - if (/\d+:\d+/.test(obj.text)) { - TEXT.style.lineHeight = "1.3"; - TEXT.style.marginLeft = "0.15em"; - } - return TEXT; + const TEXT = document.createElement("SPAN"); + TEXT.classList.add("scheduleElement"); + TEXT.style.color = obj.fcolor; + TEXT.style.fontSize = obj.fontsize.toString() + "px"; + TEXT.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; + TEXT.style.top = (obj.y + scheduleMarginTop).toString() + "px"; + TEXT.textContent = obj.text; + if (/\d+:\d+/.test(obj.text)) { + TEXT.style.lineHeight = "1.3"; + TEXT.style.marginLeft = "0.15em"; + } + return TEXT; } function getScheduleJSON(className, week, weekDay) { - return new Promise((resolve, reject) => { - getClassGUIDByName(className) - .then(classGUID => { - APIFetch("schema", { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: "{\"unit_guid\":\"" + classGUID + - "\",\"width\":" + parseInt(scheduleWidth) + - ",\"height\":" + parseInt(scheduleHeight) + - ",\"week\":" + parseInt(week) + - ",\"day\":" + parseInt(weekDay) + "}" - }).then(scheduleResp => { - return scheduleResp.json(); - }) - .then(scheduleJSON => { - resolve(scheduleJSON); - }) - .catch(error => { - reject(error); - }); - }) - .catch(error => reject(error)); - }); + return new Promise((resolve, reject) => { + getClassGUIDByName(className) + .then(classGUID => { + APIFetch("schema", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: "{\"unit_guid\":\"" + classGUID + + "\",\"width\":" + parseInt(scheduleWidth) + + ",\"height\":" + parseInt(scheduleHeight) + + ",\"week\":" + parseInt(week) + + ",\"day\":" + parseInt(weekDay) + "}" + }).then(scheduleResp => { + return scheduleResp.json(); + }) + .then(scheduleJSON => { + resolve(scheduleJSON); + }) + .catch(error => { + reject(error); + }); + }) + .catch(error => reject(error)); + }); } function getClassGUIDByName(className, retried) { - return new Promise((resolve, reject) => { - className = className.toLowerCase(); - - getAllClassGUIDs() - .then(classGUIDs => { - if (classGUIDs.hasOwnProperty(className)) { - resolve(classGUIDs[className]); - } else { - if (retried !== true) { - rebuildClassGUIDCache() - .then(() => { - getClassGUIDByName(className, true) - .then(newClassGUID => resolve(newClassGUID)) - .catch(error => reject(error)); - }); - } else { - reject("Klassen hittades inte :("); - } - } - }) - }); + return new Promise((resolve, reject) => { + className = className.toLowerCase(); + + getAllClassGUIDs() + .then(classGUIDs => { + if (classGUIDs.hasOwnProperty(className)) { + resolve(classGUIDs[className]); + } else { + if (retried !== true) { + rebuildClassGUIDCache() + .then(() => { + getClassGUIDByName(className, true) + .then(newClassGUID => resolve(newClassGUID)) + .catch(error => reject(error)); + }); + } else { + reject("Klassen hittades inte :("); + } + } + }) + }); } async function getAllClassGUIDs() { - const CLASSES = localStorage.getItem("classGUIDs"); - - if (typeof CLASSES === "string") { - let classGUIDObj; - - try { - classGUIDObj = JSON.parse(CLASSES); - } catch (error) { - console.log("Class GUID cache invalid, rebuilding …"); - await rebuildClassGUIDCache(); - return await getAllClassGUIDs(); - } - - if (typeof classGUIDObj === "object") { - return new Promise(resolve => resolve(classGUIDObj)); - } else { - await rebuildClassGUIDCache(); - return await getAllClassGUIDs(); - } - } else { - await rebuildClassGUIDCache(); - return await getAllClassGUIDs(); - } + const CLASSES = localStorage.getItem("classGUIDs"); + + if (typeof CLASSES === "string") { + let classGUIDObj; + + try { + classGUIDObj = JSON.parse(CLASSES); + } catch (error) { + console.log("Class GUID cache invalid, rebuilding …"); + await rebuildClassGUIDCache(); + return await getAllClassGUIDs(); + } + + if (typeof classGUIDObj === "object") { + return new Promise(resolve => resolve(classGUIDObj)); + } else { + await rebuildClassGUIDCache(); + return await getAllClassGUIDs(); + } + } else { + await rebuildClassGUIDCache(); + return await getAllClassGUIDs(); + } } function fetchClassGUIDsFromAPI() { - return APIFetch("klasser") - .then(response => { - return response.json(); - }); + return APIFetch("klasser") + .then(response => { + return response.json(); + }); } function rebuildClassGUIDCache() { - return new Promise(resolve => { - fetchClassGUIDsFromAPI() - .then(class_GUIDs => { - const NEAT_CLASS_GUIDS = getNeatClassGUIDsObject(class_GUIDs); - localStorage.setItem("classGUIDs", JSON.stringify(NEAT_CLASS_GUIDS)); - resolve(); - }); - }); + return new Promise(resolve => { + fetchClassGUIDsFromAPI() + .then(class_GUIDs => { + const NEAT_CLASS_GUIDS = getNeatClassGUIDsObject(class_GUIDs); + localStorage.setItem("classGUIDs", JSON.stringify(NEAT_CLASS_GUIDS)); + resolve(); + }); + }); } function getNeatClassGUIDsObject(untidyObject) { - const untidyGroups = untidyObject.data.classes; - const neatObject = {}; + const untidyGroups = untidyObject.data.classes; + const neatObject = {}; - for (let i = 0; i < untidyGroups.length; i++) { - neatObject[untidyGroups[i].groupName.toLowerCase()] = untidyGroups[i].groupGuid; - } + for (let i = 0; i < untidyGroups.length; i++) { + neatObject[untidyGroups[i].groupName.toLowerCase()] = untidyGroups[i].groupGuid; + } - return neatObject; + return neatObject; } function getSettingsObj() { - return JSON.parse(localStorage.getItem(SETTINGS_KEY)); + return JSON.parse(localStorage.getItem(SETTINGS_KEY)); } function setupSettings() { - MODULES.load("settings", function() { - setupSettings(); - }); + MODULES.load("settings", function() { + setupSettings(); + }); } function setupDebugMenu() { - MODULES.load("debugMenu", function() { - setupDebugMenu(); - }); + MODULES.load("debugMenu", function() { + setupDebugMenu(); + }); } init(); diff --git a/js/settings.js b/js/settings.js index 829c5ad..19a12f3 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,152 +1,152 @@ function setupSettings() { - const CHANGE_STARTPAGE_RADIO = document.getElementsByClassName("startPagePicker"); - const DEFAULT_CLASS_FORM = document.getElementById("defaultClassForm"); - const CHANGE_SLIDEOUT_SIDE_RADIO = document.getElementsByClassName("slideoutSidePicker"); - const SLIDEOUT_FAIL_RADIO = document.getElementsByClassName("slideoutBehaviourPicker"); - const STYLE_RADIO = document.getElementsByClassName("stylePicker"); - const DELETE_CACHES_BUTTON = document.getElementById("deleteCaches"); - const SWITCH_DAY_TIME_FORM = document.getElementById("switchDayTimeForm"); - - if (typeof localStorage.getItem("defaultClass") === "string") - DEFAULT_CLASS_FORM[0].value = localStorage.getItem("defaultClass"); - - setupRadio( - CHANGE_STARTPAGE_RADIO, - "startPage", - function(value) { - switch (value) { - case "schedule": - showSnackbar("Startsida bytt till schema"); - break; - case "lunch": - showSnackbar("Startsida bytt till lunch"); - break; - } - } - ); - setupRadio( - CHANGE_SLIDEOUT_SIDE_RADIO, - "slideoutSide", - function(value) { - slideout.destroy(); - createSlideout(); - - switch (value) { - case "left": - showSnackbar("Mobilmenyn flyttad till vänster"); - break; - case "right": - showSnackbar("Mobilmenyn flyttad till höger"); - break; - } - } - ); - setupRadio( - SLIDEOUT_FAIL_RADIO, - "slideoutWarnDisable" - ); - setupRadio( - STYLE_RADIO, - "theme" - ); - - SWITCH_DAY_TIME_FORM - .addEventListener("submit", saveDayTimeSwitch); - - DEFAULT_CLASS_FORM - .addEventListener("submit", saveDefaultClass); - - DELETE_CACHES_BUTTON - .addEventListener("click", deleteCaches); - - document.getElementById("resetButton") - .addEventListener("click", resetPreferences); + const CHANGE_STARTPAGE_RADIO = document.getElementsByClassName("startPagePicker"); + const DEFAULT_CLASS_FORM = document.getElementById("defaultClassForm"); + const CHANGE_SLIDEOUT_SIDE_RADIO = document.getElementsByClassName("slideoutSidePicker"); + const SLIDEOUT_FAIL_RADIO = document.getElementsByClassName("slideoutBehaviourPicker"); + const STYLE_RADIO = document.getElementsByClassName("stylePicker"); + const DELETE_CACHES_BUTTON = document.getElementById("deleteCaches"); + const SWITCH_DAY_TIME_FORM = document.getElementById("switchDayTimeForm"); + + if (typeof localStorage.getItem("defaultClass") === "string") + DEFAULT_CLASS_FORM[0].value = localStorage.getItem("defaultClass"); + + setupRadio( + CHANGE_STARTPAGE_RADIO, + "startPage", + function(value) { + switch (value) { + case "schedule": + showSnackbar("Startsida bytt till schema"); + break; + case "lunch": + showSnackbar("Startsida bytt till lunch"); + break; + } + } + ); + setupRadio( + CHANGE_SLIDEOUT_SIDE_RADIO, + "slideoutSide", + function(value) { + slideout.destroy(); + createSlideout(); + + switch (value) { + case "left": + showSnackbar("Mobilmenyn flyttad till vänster"); + break; + case "right": + showSnackbar("Mobilmenyn flyttad till höger"); + break; + } + } + ); + setupRadio( + SLIDEOUT_FAIL_RADIO, + "slideoutWarnDisable" + ); + setupRadio( + STYLE_RADIO, + "theme" + ); + + SWITCH_DAY_TIME_FORM + .addEventListener("submit", saveDayTimeSwitch); + + DEFAULT_CLASS_FORM + .addEventListener("submit", saveDefaultClass); + + DELETE_CACHES_BUTTON + .addEventListener("click", deleteCaches); + + document.getElementById("resetButton") + .addEventListener("click", resetPreferences); } function saveDefaultClass(evnt) { - evnt.preventDefault(); - const CLASS_TEXT = evnt.target[0].value; - if (CLASS_TEXT.length > 0) { - localStorage.setItem("defaultClass", CLASS_TEXT); - showSnackbar(CLASS_TEXT + " sparad som standardklass"); - } else { - localStorage.removeItem("defaultClass"); - showSnackbar("Standardklass borttagen"); - } + evnt.preventDefault(); + const CLASS_TEXT = evnt.target[0].value; + if (CLASS_TEXT.length > 0) { + localStorage.setItem("defaultClass", CLASS_TEXT); + showSnackbar(CLASS_TEXT + " sparad som standardklass"); + } else { + localStorage.removeItem("defaultClass"); + showSnackbar("Standardklass borttagen"); + } } function saveDayTimeSwitch(evnt) { - evnt.preventDefault(); - const SETTINGS = getSettingsObj(); + evnt.preventDefault(); + const SETTINGS = getSettingsObj(); - SETTINGS.switchoverTime.type = "global"; - SETTINGS.switchoverTime.values.all = evnt.target[0].value; + SETTINGS.switchoverTime.type = "global"; + SETTINGS.switchoverTime.values.all = evnt.target[0].value; - saveSettingsObj(SETTINGS); - updateDateObject(); + saveSettingsObj(SETTINGS); + updateDateObject(); } function setupRadio(elementsCollection, storageKey, onchangeCallback) { - const ELEMENTS = Array.prototype.slice.call(elementsCollection); + const ELEMENTS = Array.prototype.slice.call(elementsCollection); - const VALUES = ELEMENTS.map(element => { - return element.value; - }); + const VALUES = ELEMENTS.map(element => { + return element.value; + }); - const STORAGE_INDEX = VALUES.indexOf( - localStorage.getItem(storageKey)); + const STORAGE_INDEX = VALUES.indexOf( + localStorage.getItem(storageKey)); - if (STORAGE_INDEX !== -1) { - ELEMENTS[STORAGE_INDEX].checked = true; - } else { - ELEMENTS[0].checked = true; - } + if (STORAGE_INDEX !== -1) { + ELEMENTS[STORAGE_INDEX].checked = true; + } else { + ELEMENTS[0].checked = true; + } - for (let i = 0; i < ELEMENTS.length; i++) { - const ELEMENT = ELEMENTS[i]; + for (let i = 0; i < ELEMENTS.length; i++) { + const ELEMENT = ELEMENTS[i]; - ELEMENT.addEventListener("change", function() { - localStorage.setItem(storageKey, ELEMENT.value); + ELEMENT.addEventListener("change", function() { + localStorage.setItem(storageKey, ELEMENT.value); - if (typeof onchangeCallback === "function") { - onchangeCallback(ELEMENT.value); - } - }) - } + if (typeof onchangeCallback === "function") { + onchangeCallback(ELEMENT.value); + } + }) + } } async function deleteCaches() { - if (confirm("Detta kommer ta bort all cachelagrad data. Inga inställningar försvinner, men det kan ta längre tid att ladda saker eftersom allt behöver hämtas igen. Fortsätt?")) { - await caches.keys() - .then(keys => { - keys.map(key => { - caches.delete(key); - }) - }); - - reloadPage(); - } + if (confirm("Detta kommer ta bort all cachelagrad data. Inga inställningar försvinner, men det kan ta längre tid att ladda saker eftersom allt behöver hämtas igen. Fortsätt?")) { + await caches.keys() + .then(keys => { + keys.map(key => { + caches.delete(key); + }) + }); + + reloadPage(); + } } function saveSettingsObj(object) { - localStorage.setItem(SETTINGS_KEY, JSON.stringify(object)); + localStorage.setItem(SETTINGS_KEY, JSON.stringify(object)); } function resetPreferences() { - if (confirm("Är du säker att du vill återställa dina inställningar?")) { - sessionStorage.clear(); - localStorage.clear(); - if ("serviceWorker" in navigator) { - navigator.serviceWorker.getRegistrations().then(function(registrations) { - for (let i = 0; i < registrations.length; i++) { - registrations[i].unregister(); - } - }); - } - reloadPage(); - } + if (confirm("Är du säker att du vill återställa dina inställningar?")) { + sessionStorage.clear(); + localStorage.clear(); + if ("serviceWorker" in navigator) { + navigator.serviceWorker.getRegistrations().then(function(registrations) { + for (let i = 0; i < registrations.length; i++) { + registrations[i].unregister(); + } + }); + } + reloadPage(); + } } function reloadPage() { - location.reload(); + location.reload(); } diff --git a/js/utils.js b/js/utils.js index 56f45a9..a775a55 100644 --- a/js/utils.js +++ b/js/utils.js @@ -1,21 +1,21 @@ function createExternalPageViewer(URL) { - const EXT_PAGE_IFRAME = document.createElement("IFRAME"); - EXT_PAGE_IFRAME.src = URL; - EXT_PAGE_IFRAME.id = "contentIframe"; - CONTENT_DIV.innerHTML = ""; - CONTENT_DIV.appendChild(EXT_PAGE_IFRAME); - sessionStorage.setItem("currentView", "~external") + const EXT_PAGE_IFRAME = document.createElement("IFRAME"); + EXT_PAGE_IFRAME.src = URL; + EXT_PAGE_IFRAME.id = "contentIframe"; + CONTENT_DIV.innerHTML = ""; + CONTENT_DIV.appendChild(EXT_PAGE_IFRAME); + sessionStorage.setItem("currentView", "~external") } function showSnackbar(text) { - const SNACKBAR = document.getElementById("snackbar"); - if (SNACKBAR.className.includes("show")) { - SNACKBAR.textContent = text; - return; - } - SNACKBAR.textContent = text; - SNACKBAR.className = "show"; - setTimeout(function() { - SNACKBAR.className = SNACKBAR.className.replace("show", ""); - }, 3000); + const SNACKBAR = document.getElementById("snackbar"); + if (SNACKBAR.className.includes("show")) { + SNACKBAR.textContent = text; + return; + } + SNACKBAR.textContent = text; + SNACKBAR.className = "show"; + setTimeout(function() { + SNACKBAR.className = SNACKBAR.className.replace("show", ""); + }, 3000); } diff --git a/manifest.json b/manifest.json index 86c8a20..4e7f48b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,17 +1,17 @@ { - "short_name": "Berzan.js", - "name": "Berzan.js", - "version": "1.2", - "display": "standalone", - "start_url": "/", - "theme_color": "#490A3D", - "background_color": "#490A3D", - "lang": "Swedish", - "orientation": "portrait-primary", - "description": "Schema och lunch för Berzeliusskolan", - "icons": [{ - "src": "img/logo/logo-512.png", - "sizes": "512x512", - "type": "image/png" - }] + "short_name": "Berzan.js", + "name": "Berzan.js", + "version": "1.2", + "display": "standalone", + "start_url": "/", + "theme_color": "#490A3D", + "background_color": "#490A3D", + "lang": "Swedish", + "orientation": "portrait-primary", + "description": "Schema och lunch för Berzeliusskolan", + "icons": [{ + "src": "img/logo/logo-512.png", + "sizes": "512x512", + "type": "image/png" + }] } \ No newline at end of file diff --git a/sw.js b/sw.js index c890575..0101fc0 100644 --- a/sw.js +++ b/sw.js @@ -3,105 +3,106 @@ const APP_CACHE = "berzanjs-app-cache-v1.2"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ - "/", - "/css/style.css", - "/js/index.js", - "/js/settings.js", - "/js/utils.js", - "/views/neoschedule.html", - "/views/etc.html", - "/views/settings.html", - "/views/about.html", - "/manifest.json", - "/img/logo/logo-512.png", - "https://cdnjs.cloudflare.com/ajax/libs/slideout/1.0.1/slideout.js" + "/", + "/css/style.css", + "/js/index.js", + "/js/settings.js", + "/js/utils.js", + "/views/neoschedule.html", + "/views/etc.html", + "/views/settings.html", + "/views/about.html", + "/manifest.json", + "/img/logo/logo-512.png", + "https://cdnjs.cloudflare.com/ajax/libs/slideout/1.0.1/slideout.js" ]; self.addEventListener("install", function(evnt) { - evnt.waitUntil( - caches.open(APP_CACHE) - .then(function(cache) { - console.log("Opened cache"); - return cache.addAll(URLS_TO_CACHE); - }) - ); + evnt.waitUntil( + caches.open(APP_CACHE) + .then(function(cache) { + console.log("Opened cache"); + return cache.addAll(URLS_TO_CACHE); + }) + ); }); self.addEventListener("activate", function(evnt) { - const CACHE_WHITELIST = [ - APP_CACHE, - CONTENT_CACHE - ]; + const CACHE_WHITELIST = [ + APP_CACHE, + CONTENT_CACHE + ]; - evnt.waitUntil( - caches.keys().then(cacheNames => { - return Promise.all( - cacheNames.map(cacheName => { - if (CACHE_WHITELIST.indexOf(cacheName) === -1) { - return caches.delete(cacheName); - } - }) - ); - }) - ); + evnt.waitUntil( + caches.keys().then(cacheNames => { + return Promise.all( + cacheNames.map(cacheName => { + if (CACHE_WHITELIST.indexOf(cacheName) === -1) { + return caches.delete(cacheName); + } + }) + ); + }) + ); }); self.addEventListener("fetch", function(evnt){ - evnt.respondWith( - caches.match(evnt.request) - .then(function(response) { - if (response) { - // TODO: refresh caches - /* - if (response.type === "cors" && evnt.clientId) { - refreshCacheEntry(evnt.request, evnt.clientId); - } + evnt.respondWith( + caches.match(evnt.request) + .then(function(response) { + if (response) { + // TODO: refresh caches + /* + if (response.type === "cors" && evnt.clientId) { + refreshCacheEntry(evnt.request, evnt.clientId); + } - */ - return response; - } - return fetch(evnt.request).then( - function(response) { - if ( - !response || - response.status !== 200 || - (response.type !== "basic" && - response.type !== "cors") - ) { - return response; - } + */ + return response; + } + return fetch(evnt.request).then( + function(response) { + if ( + !response || + response.status !== 200 || + (response.type !== "basic" && + response.type !== "cors") + ) { + return response; + } - const RESPONSE_TO_CACHE = response.clone(); + const RESPONSE_TO_CACHE = response.clone(); - let cacheType; - if (response.type === "cors") { - cacheType = CONTENT_CACHE; - } else { - cacheType = APP_CACHE; - } + let cacheType; + if (response.type === "cors") { + cacheType = CONTENT_CACHE; + } else { + cacheType = APP_CACHE; + } - caches.open(cacheType) - .then(function(cache) { - cache.put(evnt.request, RESPONSE_TO_CACHE); - }); + caches.open(cacheType) + .then(function(cache) { + cache.put(evnt.request, RESPONSE_TO_CACHE); + }); - return response; - } - ); - }) - ); + return response; + } + ); + }) + ); }); async function refreshCacheEntry(request, clientID) { - fetch(request) - .then(async response => { + fetch(request) + .then(async response => { - const client = await self.clients.get(clientID); + const client = await self.clients.get(clientID); - client.postMessage({ - URL: request.url, - response: response - }); - //caches.match(request) - }) + client.postMessage({ + URL: request.url, + response: response + }); + //caches.match(request) + }) } + From 1a7adaa09f4038d4928d109bdaf3970b8d4539f5 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 22 Jun 2020 16:00:02 +0200 Subject: [PATCH 073/154] Schedule rendering now works again --- js/index.js | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/js/index.js b/js/index.js index 30ba284..6678524 100644 --- a/js/index.js +++ b/js/index.js @@ -413,34 +413,45 @@ function handleRenderRequest(form) { SCHEDULE_MOUNT.firstChild.remove(); } - SCHEDULE_MOUNT.style.height = scheduleHeight + "px"; - SCHEDULE_MOUNT.style.lineHeight = scheduleHeight * 0.8 + "px"; - SCHEDULE_MOUNT.style.fontWeight = "lighter"; - SCHEDULE_MOUNT.textContent = "Laddar…"; + setScheduleStatusText(SCHEDULE_MOUNT, "Laddar…"); getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) .then(scheduleJSON => { - removeLoading(SCHEDULE_MOUNT); + if (scheduleJSON.data.timetableJson === null) { + // FIXME: actually display error message + setScheduleStatusText(SCHEDULE_MOUNT, scheduleJSON); + return; + } + removeScheduleStatusText(SCHEDULE_MOUNT); renderSchedule(scheduleJSON, SCHEDULE_MOUNT); if (!localStorage.getItem("defaultClass")) { localStorage.setItem("defaultClass", form[1].value); } }) .catch(error => { - removeLoading(SCHEDULE_MOUNT); + removeScheduleStatusText(SCHEDULE_MOUNT); showSnackbar(error); }); } -function removeLoading(scheduleMount) { +function setScheduleStatusText(scheduleMount, text) { + scheduleMount.style.height = scheduleHeight + "px"; + scheduleMount.style.lineHeight = scheduleHeight * 0.8 + "px"; + scheduleMount.style.fontWeight = "lighter"; + scheduleMount.textContent = text; +} + +function removeScheduleStatusText(scheduleMount) { scheduleMount.textContent = ""; scheduleMount.removeAttribute("style"); } -function renderSchedule(scheduleJSON, scheduleMount) { +function renderSchedule(scheduleJSONString, scheduleMount) { const SCHEDULE_CONTAINER = document.createElement("DIV"); - const BOXES = scheduleJSON.data.boxList; - const TEXTS = scheduleJSON.data.textList; + console.log(scheduleJSONString); + const SCHEDULE_JSON = JSON.parse(scheduleJSONString.data.timetableJson); + const BOXES = SCHEDULE_JSON.boxList; + const TEXTS = SCHEDULE_JSON.textList; for (let i = 0; i < BOXES.length; i++) { const BOX = intoBox(BOXES[i]); From ada334501386f70507bab763d55bae64a2680aad Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 22 Jun 2020 17:25:12 +0200 Subject: [PATCH 074/154] Match API proxy interface changes --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 6678524..8769b2f 100644 --- a/js/index.js +++ b/js/index.js @@ -504,7 +504,7 @@ function getScheduleJSON(className, week, weekDay) { headers: { "Content-Type": "application/json" }, - body: "{\"unit_guid\":\"" + classGUID + + body: "{\"class_guid\":\"" + classGUID + "\",\"width\":" + parseInt(scheduleWidth) + ",\"height\":" + parseInt(scheduleHeight) + ",\"week\":" + parseInt(week) + From 225806a7e2300cc0e9570150b78a7b6bfb6c38a1 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 22 Jun 2020 17:25:46 +0200 Subject: [PATCH 075/154] Grammar updates --- views/settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/settings.html b/views/settings.html index 57cde0e..30d24d1 100644 --- a/views/settings.html +++ b/views/settings.html @@ -58,10 +58,10 @@

Experiment

Tema

-
From 99ebedb76ab427107eed9d2b317516ff8a5a3026 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 15 Jul 2020 17:27:49 +0200 Subject: [PATCH 076/154] Rebrand to Skola24 API Proxy in Rust to Eduprox --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f41a22..679393a 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ It is currently perpetually developed, with features being added and bugs fixed ## Related sources -Code used for proxying API calls: https://gitlab.com/Newbyte/berzanjs-api-rs +Code used for proxying API calls: https://gitlab.com/Newbyte/eduprox ## Guide to branches From 8139037deb5b5cc2eff5bcfdcfbe67093b94a057 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 15 Jul 2020 17:31:36 +0200 Subject: [PATCH 077/154] Update to match latest Eduprox schema --- js/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 8769b2f..7dd370a 100644 --- a/js/index.js +++ b/js/index.js @@ -6,6 +6,7 @@ Date.prototype.getWeek = function() { }; const DEFAULT_API_URL = "https://berzanjs-api.herokuapp.com/"; +const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzan.jsSettings"; const NAVIGATION_BUTTONS = document.getElementsByClassName("navButton"); const MOBILE_NAV_BUTTONS = document.getElementsByClassName("mobileNavButton"); @@ -504,9 +505,11 @@ function getScheduleJSON(className, week, weekDay) { headers: { "Content-Type": "application/json" }, - body: "{\"class_guid\":\"" + classGUID + + body: "{\"unit_guid\":\"" + BERZAN_UNIT_GUID + + "\",\"selection_guid\":\"" + classGUID + "\",\"width\":" + parseInt(scheduleWidth) + ",\"height\":" + parseInt(scheduleHeight) + + ",\"black_and_white\":" + true.toString() + ",\"week\":" + parseInt(week) + ",\"day\":" + parseInt(weekDay) + "}" }).then(scheduleResp => { From 33722b25d9d5f734b670ec57e4d21fa5bc705f70 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 15 Jul 2020 17:32:23 +0200 Subject: [PATCH 078/154] Add TODO --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 673bca1..93e7c43 100644 --- a/TODO +++ b/TODO @@ -15,6 +15,7 @@ TODO: - Notification about today's lunch (opt-in) - Searchable selection fields (in settings and schedule viewer) for classes as we now can enumerate them - Add support for other schools + - Improve handing of invalid responses for schedule DONE: - Update schedule viewer to use Skola24 instead of Novasoftware From cff7a9d59cd13c590da102467af6d2609c89f1f8 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 15 Jul 2020 21:58:20 +0200 Subject: [PATCH 079/154] Add link to source code in console --- js/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/index.js b/js/index.js index 7dd370a..e443396 100644 --- a/js/index.js +++ b/js/index.js @@ -137,6 +137,8 @@ function init() { SPLASH_SCREEN.style.display = "none"; }, 200); + console.info("%cNyfiken på källkoden? https://github.com/Newbytee/berzan", "font-size: 25px") + if ("serviceWorker" in navigator) { navigator.serviceWorker.addEventListener("message", evnt => { console.log("Message received: " + evnt); From 24e7c05f1f8f822856f7b36ba4953b32f7c30a46 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 13 Aug 2020 13:38:03 +0200 Subject: [PATCH 080/154] Change default API URL --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index e443396..29251dc 100644 --- a/js/index.js +++ b/js/index.js @@ -5,7 +5,7 @@ Date.prototype.getWeek = function() { return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); }; -const DEFAULT_API_URL = "https://berzanjs-api.herokuapp.com/"; +const DEFAULT_API_URL = "http://198.143.181.71:8080/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzan.jsSettings"; const NAVIGATION_BUTTONS = document.getElementsByClassName("navButton"); From 0c0ea3cdd8b9d8be3b9739250404b3144f94acf1 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 13 Aug 2020 13:54:45 +0200 Subject: [PATCH 081/154] Don't automatically set the API URL override to the default API URL --- js/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/js/index.js b/js/index.js index 29251dc..4b46f58 100644 --- a/js/index.js +++ b/js/index.js @@ -45,8 +45,6 @@ function ModuleManager() { function init() { const SPLASH_SCREEN = document.getElementById("splashScreen"); - if (localStorage.getItem("APIURLOverride") === null) - localStorage.setItem("APIURLOverride", DEFAULT_API_URL); if (localStorage.getItem(SETTINGS_KEY) === null) localStorage.setItem(SETTINGS_KEY, @@ -127,7 +125,7 @@ function init() { } } - APIURL = localStorage.getItem("APIURLOverride"); + APIURL = localStorage.getItem("APIURLOverride") || DEFAULT_API_URL; if (location.hostname === "berzan.netlify.com") document.getElementById("identity").textContent += " (Canary)"; From 29ae609276420860a49a4fe542804d721174d66b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sat, 22 Aug 2020 21:20:30 +0200 Subject: [PATCH 082/154] Work on new configuration infrastructure --- js/index.js | 96 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/js/index.js b/js/index.js index 4b46f58..cdfc28b 100644 --- a/js/index.js +++ b/js/index.js @@ -5,13 +5,15 @@ Date.prototype.getWeek = function() { return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); }; -const DEFAULT_API_URL = "http://198.143.181.71:8080/"; +const DEFAULT_API_URL = "http://198.143.181.71:8080/skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; -const SETTINGS_KEY = "berzan.jsSettings"; +const SETTINGS_KEY = "berzanjsConfig"; +const TIMESTAMP_PATTERN = /\d+:\d+/; const NAVIGATION_BUTTONS = document.getElementsByClassName("navButton"); const MOBILE_NAV_BUTTONS = document.getElementsByClassName("mobileNavButton"); const CONTENT_DIV = document.getElementById("wrapper"); const DATE = new Date(); +const CONFIG = new ConfigManager(); const MODULES = new ModuleManager(); let allowKeyNav = true; let scheduleResizeTimer = null; @@ -23,6 +25,75 @@ let isMobile; let slideout; let APIURL; +function ConfigManager() { + let config = localStorage.getItem(SETTINGS_KEY); + + if (typeof config !== "string") { + config = "{}"; + } + + try { + this.config = JSON.parse(config); + } catch (_) { + this.config = {}; + } + + this.getVar = function(varName) { + return this.config[varName]; + } + + this.setVar = function(varName, value) { + this.config[varName] = value; + this.saveVars(); + } + + this.saveVars = function() { + const configString = JSON.stringify(this.config); + localStorage.setItem(SETTINGS_KEY, configString); + } + + this.validateVar = function(varName, value) { + switch (varName) { + case "theme": + return value === "light" || value === "dark"; + case "switchoverTime": + const switchoverTime = this.getVar("switchoverTime"); + const switchoverTimeType = typeof switchoverTime; + + switch (switchoverTimeType) { + case "object": + for (const timeItem in switchoverTime) { + if (TIMESTAMP_PATTERN.test(timeItem)) { + return true; + } + } + + return false; + case "string": + return TIMESTAMP_PATTERN.test(switchoverTime); + default: + return false; + } + } + } + + this.validateVars = function() { + const currentTheme = this.getVar("theme"); + + if (!this.validateVar("theme", currentTheme)) { + this.setVar("theme", "light"); + } + + const switchoverTime = this.getVar("switchoverTime"); + + if (!this.validateVar("switchoverTime", switchoverTime)) { + this.setVar("switchoverTime", { + time: "00:00" + }); + } + } +} + function ModuleManager() { this.modules = document.getElementById("modules"); @@ -45,17 +116,13 @@ function ModuleManager() { function init() { const SPLASH_SCREEN = document.getElementById("splashScreen"); + CONFIG.validateVars(); if (localStorage.getItem(SETTINGS_KEY) === null) localStorage.setItem(SETTINGS_KEY, JSON.stringify({ theme: "light", - switchoverTime: { - type: "global", - values: { - all: "00:00" - } - } + switchoverTime: "00:00" }) ); @@ -241,16 +308,13 @@ function showSnackbar(text) { } function updateDateObject() { - const SETTINGS = getSettingsObj(); + const switchoverTime = CONFIG.getVar("switchoverTime"); - if (SETTINGS.hasOwnProperty("switchoverTime")) { - const NOW_DATE = new Date(); - const DATE_AND_TIME_ARR = SETTINGS.switchoverTime.values.all.split(":"); - console.log(DATE_AND_TIME_ARR); + const NOW_DATE = new Date(); + const DATE_AND_TIME_ARR = switchoverTime.time.split(":"); - DATE.setHours(NOW_DATE.getHours() + parseInt(DATE_AND_TIME_ARR[0])); - DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); - } + DATE.setHours(NOW_DATE.getHours() + parseInt(DATE_AND_TIME_ARR[0])); + DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); } function updateNeoscheduleVars() { From 0680c2410091980684ffc9118e2b4ce206f11962 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sat, 22 Aug 2020 21:23:47 +0200 Subject: [PATCH 083/154] Theme setting now use new configuration infrastructure --- js/settings.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/settings.js b/js/settings.js index 19a12f3..f8c61b2 100644 --- a/js/settings.js +++ b/js/settings.js @@ -94,7 +94,7 @@ function setupRadio(elementsCollection, storageKey, onchangeCallback) { }); const STORAGE_INDEX = VALUES.indexOf( - localStorage.getItem(storageKey)); + CONFIG.getVar(storageKey)); if (STORAGE_INDEX !== -1) { ELEMENTS[STORAGE_INDEX].checked = true; @@ -106,7 +106,9 @@ function setupRadio(elementsCollection, storageKey, onchangeCallback) { const ELEMENT = ELEMENTS[i]; ELEMENT.addEventListener("change", function() { - localStorage.setItem(storageKey, ELEMENT.value); + CONFIG.setVar(storageKey, ELEMENT.value); + + CONFIG.saveVars(); if (typeof onchangeCallback === "function") { onchangeCallback(ELEMENT.value); From f85e2246e489a77583bf289b1f81418b3c370e95 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:08:54 +0200 Subject: [PATCH 084/154] Start page and slideout side now use new settings infrastructure --- js/index.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index cdfc28b..a6938ed 100644 --- a/js/index.js +++ b/js/index.js @@ -56,6 +56,10 @@ function ConfigManager() { switch (varName) { case "theme": return value === "light" || value === "dark"; + case "slideoutSide": + return value === "left" || value === "right"; + case "startPage": + return value === "schedule" || value === "lunch"; case "switchoverTime": const switchoverTime = this.getVar("switchoverTime"); const switchoverTimeType = typeof switchoverTime; @@ -84,6 +88,18 @@ function ConfigManager() { this.setVar("theme", "light"); } + const slideoutSide = this.getVar("slideoutSide"); + + if (!this.validateVar("slideoutSide", slideoutSide)) { + this.setVar("slideoutSide", "left"); + } + + const startPage = this.getVar("startPage"); + + if (!this.validateVar("startPage", startPage)) { + this.setVar("startPage", "schedule") + } + const switchoverTime = this.getVar("switchoverTime"); if (!this.validateVar("switchoverTime", switchoverTime)) { @@ -173,7 +189,7 @@ function init() { if (sessionStorage.getItem("currentTab")) { loadPage(parseInt(sessionStorage.getItem("currentTab"))); } else { - switch (localStorage.getItem("startPage")) { + switch (CONFIG.getVar("startPage")) { case "schedule": loadPage(0); break; @@ -262,7 +278,7 @@ function createSlideout() { if (window["Slideout"]) { const slideoutMenu = document.getElementById("hiddenMenu"); const hamburgerMenu = document.getElementById("hamburgerSvg"); - if (localStorage.getItem("slideoutSide") === null || localStorage.getItem("slideoutSide") === "left") { + if (CONFIG.getVar("slideoutSide") === "left") { slideoutMenu.classList.remove("slideout-menu-right"); hamburgerMenu.style.removeProperty("right"); hamburgerMenu.style.left = "5%"; From 6c54abf4e113ff3aceeea1c66679d7d4115d4daf Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:12:20 +0200 Subject: [PATCH 085/154] Fix possibility of page reloading before service workers are registered --- js/settings.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/js/settings.js b/js/settings.js index f8c61b2..7f9697a 100644 --- a/js/settings.js +++ b/js/settings.js @@ -134,16 +134,17 @@ function saveSettingsObj(object) { localStorage.setItem(SETTINGS_KEY, JSON.stringify(object)); } -function resetPreferences() { +async function resetPreferences() { if (confirm("Är du säker att du vill återställa dina inställningar?")) { sessionStorage.clear(); localStorage.clear(); if ("serviceWorker" in navigator) { - navigator.serviceWorker.getRegistrations().then(function(registrations) { - for (let i = 0; i < registrations.length; i++) { - registrations[i].unregister(); - } - }); + const registrations = + await navigator.serviceWorker.getRegistrations() + + for (let i = 0; i < registrations.length; i++) { + registrations[i].unregister(); + } } reloadPage(); } From d46415d7fffb490e5d040b943207fb5023fd7d01 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:13:46 +0200 Subject: [PATCH 086/154] Log warning if variable lacks validation routine --- js/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/index.js b/js/index.js index a6938ed..990ff94 100644 --- a/js/index.js +++ b/js/index.js @@ -78,6 +78,9 @@ function ConfigManager() { default: return false; } + default: + console.warn("No validation routine for var " + varName + "!"); + break; } } From 5d68b01b3152031f84b2619a79fe06921cddf3dc Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:14:31 +0200 Subject: [PATCH 087/154] Use global TIMESTAMP_PATTERN instead of inline pattern --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 990ff94..1d150ef 100644 --- a/js/index.js +++ b/js/index.js @@ -572,7 +572,7 @@ function intoText(obj) { TEXT.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; TEXT.style.top = (obj.y + scheduleMarginTop).toString() + "px"; TEXT.textContent = obj.text; - if (/\d+:\d+/.test(obj.text)) { + if (TIMESTAMP_PATTERN.test(obj.text)) { TEXT.style.lineHeight = "1.3"; TEXT.style.marginLeft = "0.15em"; } From 22d024c5040173893cdb8c3c52bf57cd50fac4a6 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:14:49 +0200 Subject: [PATCH 088/154] Remove redundant logging --- js/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/index.js b/js/index.js index 1d150ef..d63f8c8 100644 --- a/js/index.js +++ b/js/index.js @@ -532,7 +532,6 @@ function removeScheduleStatusText(scheduleMount) { function renderSchedule(scheduleJSONString, scheduleMount) { const SCHEDULE_CONTAINER = document.createElement("DIV"); - console.log(scheduleJSONString); const SCHEDULE_JSON = JSON.parse(scheduleJSONString.data.timetableJson); const BOXES = SCHEDULE_JSON.boxList; const TEXTS = SCHEDULE_JSON.textList; From cc2c726526dc6dad0b714bdad757af2d7ef7750d Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:17:17 +0200 Subject: [PATCH 089/154] Remove dead code --- js/index.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/js/index.js b/js/index.js index d63f8c8..5c703cb 100644 --- a/js/index.js +++ b/js/index.js @@ -137,14 +137,6 @@ function init() { CONFIG.validateVars(); - if (localStorage.getItem(SETTINGS_KEY) === null) - localStorage.setItem(SETTINGS_KEY, - JSON.stringify({ - theme: "light", - switchoverTime: "00:00" - }) - ); - updateDateObject(); createSlideout(); checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order From a3b6c11f8763a21bc1bbab31b9894ebcb5155a90 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 15:24:21 +0200 Subject: [PATCH 090/154] Only commit config changes to localStorage before unloading page. This is fine as CONFIG.getVar() reads from memory, so it does not matter what is written to localStorage until the page is reloaded --- js/index.js | 5 ++++- js/settings.js | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/js/index.js b/js/index.js index 5c703cb..cf24208 100644 --- a/js/index.js +++ b/js/index.js @@ -38,13 +38,16 @@ function ConfigManager() { this.config = {}; } + window.addEventListener("beforeunload", () => { + this.saveVars(); + }); + this.getVar = function(varName) { return this.config[varName]; } this.setVar = function(varName, value) { this.config[varName] = value; - this.saveVars(); } this.saveVars = function() { diff --git a/js/settings.js b/js/settings.js index 7f9697a..b16704f 100644 --- a/js/settings.js +++ b/js/settings.js @@ -108,8 +108,6 @@ function setupRadio(elementsCollection, storageKey, onchangeCallback) { ELEMENT.addEventListener("change", function() { CONFIG.setVar(storageKey, ELEMENT.value); - CONFIG.saveVars(); - if (typeof onchangeCallback === "function") { onchangeCallback(ELEMENT.value); } From 7ba48ee236cdf52b3272ee46e5d239d637cd30ff Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 19:31:43 +0200 Subject: [PATCH 091/154] Add function to delete config vars --- js/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/index.js b/js/index.js index cf24208..aa47163 100644 --- a/js/index.js +++ b/js/index.js @@ -42,6 +42,10 @@ function ConfigManager() { this.saveVars(); }); + this.deleteVar = function(varName) { + delete this.config[varName]; + } + this.getVar = function(varName) { return this.config[varName]; } From 632718b1065508da39d98db135213f8d34ea36c6 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 19:32:20 +0200 Subject: [PATCH 092/154] Default class now uses new settings infrastructure --- js/index.js | 14 ++++++++++---- js/settings.js | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/js/index.js b/js/index.js index aa47163..25aa1a0 100644 --- a/js/index.js +++ b/js/index.js @@ -61,6 +61,10 @@ function ConfigManager() { this.validateVar = function(varName, value) { switch (varName) { + case "defaultClass": + const defaultClassType = typeof value; + return defaultClassType === "string" || + defaultClassType === "undefined"; case "theme": return value === "light" || value === "dark"; case "slideoutSide": @@ -445,11 +449,13 @@ function setupNeoschedule() { INPUT_FIELDS[i].value = sessionStorage.getItem("inputField" + i); } + const defaultClass = CONFIG.getVar("defaultClass"); + if ( - localStorage.getItem("defaultClass") && + defaultClass && INPUT_FIELDS[1].value.length === 0 ) { - INPUT_FIELDS[1].value = localStorage.getItem("defaultClass"); + INPUT_FIELDS[1].value = defaultClass; } if (isMobile) { @@ -507,8 +513,8 @@ function handleRenderRequest(form) { } removeScheduleStatusText(SCHEDULE_MOUNT); renderSchedule(scheduleJSON, SCHEDULE_MOUNT); - if (!localStorage.getItem("defaultClass")) { - localStorage.setItem("defaultClass", form[1].value); + if (!CONFIG.getVar("defaultClass")) { + CONFIG.setVar("defaultClass", form[1].value); } }) .catch(error => { diff --git a/js/settings.js b/js/settings.js index b16704f..dbd94cf 100644 --- a/js/settings.js +++ b/js/settings.js @@ -67,10 +67,10 @@ function saveDefaultClass(evnt) { evnt.preventDefault(); const CLASS_TEXT = evnt.target[0].value; if (CLASS_TEXT.length > 0) { - localStorage.setItem("defaultClass", CLASS_TEXT); + CONFIG.setVar("defaultClass", CLASS_TEXT); showSnackbar(CLASS_TEXT + " sparad som standardklass"); } else { - localStorage.removeItem("defaultClass"); + CONFIG.deleteVar("defaultClass"); showSnackbar("Standardklass borttagen"); } } From cc8017d7840d3ade786e33d7095ae42aa4bdc597 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 20:51:33 +0200 Subject: [PATCH 093/154] Fix default class not being displayed in settings --- js/settings.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/settings.js b/js/settings.js index dbd94cf..77b902e 100644 --- a/js/settings.js +++ b/js/settings.js @@ -7,8 +7,10 @@ function setupSettings() { const DELETE_CACHES_BUTTON = document.getElementById("deleteCaches"); const SWITCH_DAY_TIME_FORM = document.getElementById("switchDayTimeForm"); - if (typeof localStorage.getItem("defaultClass") === "string") - DEFAULT_CLASS_FORM[0].value = localStorage.getItem("defaultClass"); + const defaultClass = CONFIG.getVar("defaultClass"); + + if (typeof defaultClass === "string") + DEFAULT_CLASS_FORM[0].value = defaultClass; setupRadio( CHANGE_STARTPAGE_RADIO, From 25da9d070b197679d9a7483dc0cbc5425503fec3 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 20:58:42 +0200 Subject: [PATCH 094/154] Reduce complexity of storing switchover time --- js/index.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index 25aa1a0..94b9ef1 100644 --- a/js/index.js +++ b/js/index.js @@ -117,9 +117,7 @@ function ConfigManager() { const switchoverTime = this.getVar("switchoverTime"); if (!this.validateVar("switchoverTime", switchoverTime)) { - this.setVar("switchoverTime", { - time: "00:00" - }); + this.setVar("switchoverTime", "00:00"); } } } @@ -333,7 +331,7 @@ function updateDateObject() { const switchoverTime = CONFIG.getVar("switchoverTime"); const NOW_DATE = new Date(); - const DATE_AND_TIME_ARR = switchoverTime.time.split(":"); + const DATE_AND_TIME_ARR = switchoverTime.split(":"); DATE.setHours(NOW_DATE.getHours() + parseInt(DATE_AND_TIME_ARR[0])); DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); From addc8bacf53ef0e80ffe4181d112c117a77488a2 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 21:52:14 +0200 Subject: [PATCH 095/154] Load switchover time from config storage --- js/settings.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/settings.js b/js/settings.js index 77b902e..7c1217c 100644 --- a/js/settings.js +++ b/js/settings.js @@ -12,6 +12,8 @@ function setupSettings() { if (typeof defaultClass === "string") DEFAULT_CLASS_FORM[0].value = defaultClass; + SWITCH_DAY_TIME_FORM[0].value = CONFIG.getVar("switchoverTime"); + setupRadio( CHANGE_STARTPAGE_RADIO, "startPage", From b48811300b9a590d78529925d414fe2f80839e99 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 21:52:33 +0200 Subject: [PATCH 096/154] Make saving switchover time functional --- js/settings.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/js/settings.js b/js/settings.js index 7c1217c..a0c4ca4 100644 --- a/js/settings.js +++ b/js/settings.js @@ -81,13 +81,8 @@ function saveDefaultClass(evnt) { function saveDayTimeSwitch(evnt) { evnt.preventDefault(); - const SETTINGS = getSettingsObj(); - SETTINGS.switchoverTime.type = "global"; - SETTINGS.switchoverTime.values.all = evnt.target[0].value; - - saveSettingsObj(SETTINGS); - updateDateObject(); + CONFIG.setVar("switchoverTime", evnt.target[0].value); } function setupRadio(elementsCollection, storageKey, onchangeCallback) { From e4102f2410e8179c85e744bfff5a396687b35f73 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 23 Aug 2020 21:55:05 +0200 Subject: [PATCH 097/154] Remove old settings code --- js/index.js | 4 ---- js/settings.js | 4 ---- 2 files changed, 8 deletions(-) diff --git a/js/index.js b/js/index.js index 94b9ef1..6fd8d26 100644 --- a/js/index.js +++ b/js/index.js @@ -690,10 +690,6 @@ function getNeatClassGUIDsObject(untidyObject) { return neatObject; } -function getSettingsObj() { - return JSON.parse(localStorage.getItem(SETTINGS_KEY)); -} - function setupSettings() { MODULES.load("settings", function() { setupSettings(); diff --git a/js/settings.js b/js/settings.js index a0c4ca4..775ab3f 100644 --- a/js/settings.js +++ b/js/settings.js @@ -127,10 +127,6 @@ async function deleteCaches() { } } -function saveSettingsObj(object) { - localStorage.setItem(SETTINGS_KEY, JSON.stringify(object)); -} - async function resetPreferences() { if (confirm("Är du säker att du vill återställa dina inställningar?")) { sessionStorage.clear(); From 5125fc506541ec19bba1e2bdfd60d47571fd2c5b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 14:13:18 +0200 Subject: [PATCH 098/154] Read APIURLOverride from sessionStorage --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 6fd8d26..53145a8 100644 --- a/js/index.js +++ b/js/index.js @@ -212,7 +212,7 @@ function init() { } } - APIURL = localStorage.getItem("APIURLOverride") || DEFAULT_API_URL; + APIURL = sessionStorage.getItem("APIURLOverride") || DEFAULT_API_URL; if (location.hostname === "berzan.netlify.com") document.getElementById("identity").textContent += " (Canary)"; From e5a46ab0a9f1da57d555de0bb0ede2cd47917fca Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 14:45:16 +0200 Subject: [PATCH 099/154] Fix disabling Slideout.js warning setting not working with new config infrastructure --- js/index.js | 10 +++++++++- views/settings.html | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/js/index.js b/js/index.js index 53145a8..536cafb 100644 --- a/js/index.js +++ b/js/index.js @@ -69,6 +69,8 @@ function ConfigManager() { return value === "light" || value === "dark"; case "slideoutSide": return value === "left" || value === "right"; + case "slideoutWarnDisable": + return value === "on" || value === "off"; case "startPage": return value === "schedule" || value === "lunch"; case "switchoverTime": @@ -108,6 +110,12 @@ function ConfigManager() { this.setVar("slideoutSide", "left"); } + const slideoutWarnDisable = this.getVar("slideoutWarnDisable"); + + if (!this.validateVar("slideoutWarnDisable")) { + this.setVar("slideoutWarnDisable", "off"); + } + const startPage = this.getVar("startPage"); if (!this.validateVar("startPage", startPage)) { @@ -305,7 +313,7 @@ function createSlideout() { }); } } else { - if (localStorage.getItem("slideoutWarnDisable") !== "on") + if (CONFIG.getVar("slideoutWarnDisable") !== "on") alert("Din webbläsare tycks blockera Slideout.js, ett bibliotek Berzan.js använder. Berzan.js bör fungera ändå, men vissa saker lär vara trasiga. Testa att stäng av din adblocker (eller liknande) och se om problemet kvarstår."); document.getElementById("hiddenMenu").style.display = "none"; slideout = { close() {} } diff --git a/views/settings.html b/views/settings.html index 30d24d1..6ba8ccc 100644 --- a/views/settings.html +++ b/views/settings.html @@ -40,10 +40,10 @@

Övrigt

Om Slideout.js inte kan laddas

From 25fa999a17c03c924f32ca654facc12030669c9e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 15:23:28 +0200 Subject: [PATCH 100/154] Fix slideoutWarnDisable always failing validation --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 536cafb..0d1d2c4 100644 --- a/js/index.js +++ b/js/index.js @@ -112,7 +112,7 @@ function ConfigManager() { const slideoutWarnDisable = this.getVar("slideoutWarnDisable"); - if (!this.validateVar("slideoutWarnDisable")) { + if (!this.validateVar("slideoutWarnDisable", slideoutWarnDisable)) { this.setVar("slideoutWarnDisable", "off"); } From 01731b0d7102ab95f8c02f49052bc6972fab0ddc Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 17:29:07 +0200 Subject: [PATCH 101/154] Reworked to support Eduprox v0.1 --- js/index.js | 69 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/js/index.js b/js/index.js index 0d1d2c4..cc93f0e 100644 --- a/js/index.js +++ b/js/index.js @@ -5,7 +5,8 @@ Date.prototype.getWeek = function() { return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); }; -const DEFAULT_API_URL = "http://198.143.181.71:8080/skola24/v0/"; +const DEFAULT_API_URL = "http://198.143.181.71:8080/"; +const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; const TIMESTAMP_PATTERN = /\d+:\d+/; @@ -590,32 +591,39 @@ function intoText(obj) { } function getScheduleJSON(className, week, weekDay) { - return new Promise((resolve, reject) => { - getClassGUIDByName(className) - .then(classGUID => { - APIFetch("schema", { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: "{\"unit_guid\":\"" + BERZAN_UNIT_GUID + - "\",\"selection_guid\":\"" + classGUID + - "\",\"width\":" + parseInt(scheduleWidth) + - ",\"height\":" + parseInt(scheduleHeight) + - ",\"black_and_white\":" + true.toString() + - ",\"week\":" + parseInt(week) + - ",\"day\":" + parseInt(weekDay) + "}" - }).then(scheduleResp => { - return scheduleResp.json(); - }) - .then(scheduleJSON => { - resolve(scheduleJSON); - }) - .catch(error => { - reject(error); - }); + return new Promise(async (resolve, reject) => { + const [ + renderKeyResp, + classGUID + ] = await Promise.all([ + fetchRenderKeyFromAPI(), + getClassGUIDByName(className) + ]); + + const renderKey = renderKeyResp.data.key; + + APIFetch(SCHEDULE_API_PREFIX + "schedule", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: "{\"render_key\":\"" + renderKey + + "\",\"unit_guid\":\"" + BERZAN_UNIT_GUID + + "\",\"selection_signature\":\"" + classGUID + + "\",\"width\":" + parseInt(scheduleWidth) + + ",\"height\":" + parseInt(scheduleHeight) + + ",\"black_and_white\":" + true.toString() + + ",\"week\":" + parseInt(week) + + ",\"day\":" + parseInt(weekDay) + "}" + }).then(scheduleResp => { + return scheduleResp.json(); + }) + .then(scheduleJSON => { + resolve(scheduleJSON); }) - .catch(error => reject(error)); + .catch(error => { + reject(error); + }); }); } @@ -670,7 +678,14 @@ async function getAllClassGUIDs() { } function fetchClassGUIDsFromAPI() { - return APIFetch("klasser") + return APIFetch(SCHEDULE_API_PREFIX + "classes") + .then(response => { + return response.json(); + }); +} + +function fetchRenderKeyFromAPI() { + return APIFetch(SCHEDULE_API_PREFIX + "render-key") .then(response => { return response.json(); }); From b8d32849caf2a4e893be958c550bd239753bd960 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 19:15:59 +0200 Subject: [PATCH 102/154] Make separator 20% thicker --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index fa85a29..14653e0 100644 --- a/css/style.css +++ b/css/style.css @@ -234,7 +234,7 @@ nav, .mobileNavButton, #schedule, #wrapper { .separator { width: 100%; - height: 0.05em; + height: 0.06em; background-color: var(--invert-bg-colour); margin-bottom: 1.5em; } From a639220527ac8868664079ff2efbb0dfb5995fa7 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 21:03:51 +0200 Subject: [PATCH 103/154] Fix bug where config would persist even if localStorage was cleared --- js/index.js | 6 ++---- js/settings.js | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index cc93f0e..6206320 100644 --- a/js/index.js +++ b/js/index.js @@ -39,10 +39,6 @@ function ConfigManager() { this.config = {}; } - window.addEventListener("beforeunload", () => { - this.saveVars(); - }); - this.deleteVar = function(varName) { delete this.config[varName]; } @@ -60,6 +56,8 @@ function ConfigManager() { localStorage.setItem(SETTINGS_KEY, configString); } + window.addEventListener("beforeunload", this.saveVars); + this.validateVar = function(varName, value) { switch (varName) { case "defaultClass": diff --git a/js/settings.js b/js/settings.js index 775ab3f..018ab56 100644 --- a/js/settings.js +++ b/js/settings.js @@ -131,6 +131,7 @@ async function resetPreferences() { if (confirm("Är du säker att du vill återställa dina inställningar?")) { sessionStorage.clear(); localStorage.clear(); + window.removeEventListener("beforeunload", CONFIG.saveVars); if ("serviceWorker" in navigator) { const registrations = await navigator.serviceWorker.getRegistrations() From ff47692017ec9873411128da22ee3a3fce0a7f76 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 21:12:24 +0200 Subject: [PATCH 104/154] Fix bug where config always would be undefined (how did this ever work?) --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 6206320..5a7a880 100644 --- a/js/index.js +++ b/js/index.js @@ -51,7 +51,7 @@ function ConfigManager() { this.config[varName] = value; } - this.saveVars = function() { + this.saveVars = () => { const configString = JSON.stringify(this.config); localStorage.setItem(SETTINGS_KEY, configString); } From 7a1f319b1d0c648fc964200832518f654d5a092e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 25 Aug 2020 21:19:40 +0200 Subject: [PATCH 105/154] Implement switching between black and white and colourful schedule --- js/index.js | 14 +++++++++++++- js/settings.js | 6 ++++++ views/settings.html | 11 +++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 5a7a880..ef4fe87 100644 --- a/js/index.js +++ b/js/index.js @@ -66,6 +66,8 @@ function ConfigManager() { defaultClassType === "undefined"; case "theme": return value === "light" || value === "dark"; + case "scheduleColourMode": + return value === "colourful" || value === "blackAndWhite"; case "slideoutSide": return value === "left" || value === "right"; case "slideoutWarnDisable": @@ -103,6 +105,12 @@ function ConfigManager() { this.setVar("theme", "light"); } + const scheduleColourMode = this.getVar("scheduleColourMode"); + + if (!this.validateVar("scheduleColourMode", scheduleColourMode)) { + this.setVar("scheduleColourMode", "colourful"); + } + const slideoutSide = this.getVar("slideoutSide"); if (!this.validateVar("slideoutSide", slideoutSide)) { @@ -610,7 +618,7 @@ function getScheduleJSON(className, week, weekDay) { "\",\"selection_signature\":\"" + classGUID + "\",\"width\":" + parseInt(scheduleWidth) + ",\"height\":" + parseInt(scheduleHeight) + - ",\"black_and_white\":" + true.toString() + + ",\"black_and_white\":" + getScheduleColourMode() + ",\"week\":" + parseInt(week) + ",\"day\":" + parseInt(weekDay) + "}" }).then(scheduleResp => { @@ -625,6 +633,10 @@ function getScheduleJSON(className, week, weekDay) { }); } +function getScheduleColourMode() { + return (CONFIG.getVar("scheduleColourMode") === "blackAndWhite").toString(); +} + function getClassGUIDByName(className, retried) { return new Promise((resolve, reject) => { className = className.toLowerCase(); diff --git a/js/settings.js b/js/settings.js index 018ab56..2609b45 100644 --- a/js/settings.js +++ b/js/settings.js @@ -4,6 +4,8 @@ function setupSettings() { const CHANGE_SLIDEOUT_SIDE_RADIO = document.getElementsByClassName("slideoutSidePicker"); const SLIDEOUT_FAIL_RADIO = document.getElementsByClassName("slideoutBehaviourPicker"); const STYLE_RADIO = document.getElementsByClassName("stylePicker"); + const SCHEDULE_COLOUR_MODE_RADIO = + document.getElementsByClassName("scheduleColourModePicker"); const DELETE_CACHES_BUTTON = document.getElementById("deleteCaches"); const SWITCH_DAY_TIME_FORM = document.getElementById("switchDayTimeForm"); @@ -53,6 +55,10 @@ function setupSettings() { STYLE_RADIO, "theme" ); + setupRadio( + SCHEDULE_COLOUR_MODE_RADIO, + "scheduleColourMode" + ) SWITCH_DAY_TIME_FORM .addEventListener("submit", saveDayTimeSwitch); diff --git a/views/settings.html b/views/settings.html index 6ba8ccc..6c85452 100644 --- a/views/settings.html +++ b/views/settings.html @@ -8,6 +8,17 @@

Standardklass

+
+

Schemats färger

+ + +

Schemat växlar till nästa dag vid …

From 1da1c2dd915a9b6dfc206aa7dca0cb6651049bd6 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 27 Aug 2020 17:28:39 +0200 Subject: [PATCH 106/154] Update default API URL --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index ef4fe87..a5a242b 100644 --- a/js/index.js +++ b/js/index.js @@ -5,7 +5,7 @@ Date.prototype.getWeek = function() { return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); }; -const DEFAULT_API_URL = "http://198.143.181.71:8080/"; +const DEFAULT_API_URL = "https://eduprox.tn.dedyn.io/"; const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; From a64bea0b02e81f8fe5b44af4083ca08220e30aef Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 27 Aug 2020 17:37:18 +0200 Subject: [PATCH 107/154] Fix loading text being positioned weirdly every other resize --- js/index.js | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/js/index.js b/js/index.js index a5a242b..3aeee63 100644 --- a/js/index.js +++ b/js/index.js @@ -179,20 +179,7 @@ function init() { ) changeTab(TAB_INDEX); }); - window.onresize = function() { - checkDeviceType(); - - if (sessionStorage.getItem("currentView") === "neoschedule") { - const INPUT_FORM = document.getElementById("scheduleInputForm"); - if (scheduleResizeTimer !== null) { - window.clearTimeout(scheduleResizeTimer); - } - scheduleResizeTimer = window.setTimeout(function() { - updateNeoscheduleVars(); - handleRenderRequest(INPUT_FORM); - }, 150); - } - }; + window.onresize = resizeNeoschedule; for (let i = 0; i < NAVIGATION_BUTTONS.length; i++) { NAVIGATION_BUTTONS[i].addEventListener("click", function() { @@ -352,6 +339,21 @@ function updateDateObject() { DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); } +function resizeNeoschedule() { + checkDeviceType(); + + if (sessionStorage.getItem("currentView") === "neoschedule") { + const INPUT_FORM = document.getElementById("scheduleInputForm"); + if (scheduleResizeTimer !== null) { + window.clearTimeout(scheduleResizeTimer); + } + scheduleResizeTimer = window.setTimeout(function() { + updateNeoscheduleVars(); + handleRenderRequest(INPUT_FORM); + }, 150); + } +} + function updateNeoscheduleVars() { if (sessionStorage.getItem("currentView") === "neoschedule") { const NAV_HEIGHT = document.getElementsByTagName("nav")[0].offsetHeight; @@ -361,9 +363,10 @@ function updateNeoscheduleVars() { // -1 is needed to not produce scollbars for some reason scheduleWidth = INPUT_FORM.offsetWidth - 1; - scheduleHeight = window.innerHeight - MAIN_WRAPPER_HEIGHT - NAV_HEIGHT - OFFSET - 1; + scheduleHeight = window.innerHeight - NAV_HEIGHT - OFFSET - + INPUT_FORM.offsetHeight - 6; scheduleMarginLeft = (INPUT_FORM.offsetWidth - window.innerWidth) / 2; - scheduleMarginTop = MAIN_WRAPPER_HEIGHT + NAV_HEIGHT + OFFSET; + scheduleMarginTop = INPUT_FORM.offsetHeight + NAV_HEIGHT + OFFSET + 5; } } From 357614882320531c74bee259f3444ac1e652618b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 27 Aug 2020 18:18:28 +0200 Subject: [PATCH 108/154] Do not bother caching CORS requests for now --- sw.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sw.js b/sw.js index 0101fc0..f067174 100644 --- a/sw.js +++ b/sw.js @@ -65,8 +65,7 @@ self.addEventListener("fetch", function(evnt){ if ( !response || response.status !== 200 || - (response.type !== "basic" && - response.type !== "cors") + response.type !== "basic" ) { return response; } @@ -105,4 +104,3 @@ async function refreshCacheEntry(request, clientID) { //caches.match(request) }) } - From dd1bc96785ea81e0567110ba3d5e7d5eea63121a Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 28 Aug 2020 14:36:57 +0200 Subject: [PATCH 109/154] Remove redundant code --- css/style.css | 1 - 1 file changed, 1 deletion(-) diff --git a/css/style.css b/css/style.css index 14653e0..aebd910 100644 --- a/css/style.css +++ b/css/style.css @@ -43,7 +43,6 @@ body { line-height: 1.5; color: var(--normal-text-colour); text-align: left; - background-color: var(--global-bg-colour); width: 100%; height: 100%; user-select: none; From e8df9fbde21ac7493de7474bf31d12e4aa2669a0 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 28 Aug 2020 16:06:09 +0200 Subject: [PATCH 110/154] Change clear cache button label text to better reflect what it does --- views/settings.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/settings.html b/views/settings.html index 6c85452..0de7726 100644 --- a/views/settings.html +++ b/views/settings.html @@ -59,7 +59,8 @@

Om Slideout.js inte kan laddas

Rensa cache

- +

Återställ inställningar

From f5dd4745518b2b9f8ef2a0d691d0404d0a9293e7 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 28 Aug 2020 16:10:01 +0200 Subject: [PATCH 111/154] Initial dark theme implementation --- css/style.css | 7 ++++--- js/index.js | 10 ++++++++++ js/settings.js | 11 ++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/css/style.css b/css/style.css index aebd910..caaf34e 100644 --- a/css/style.css +++ b/css/style.css @@ -279,8 +279,8 @@ nav, .mobileNavButton, #schedule, #wrapper { .field { transition: 0.5s; height: 30px; - color: #000; - background-color: #FFF; + color: var(--normal-text-colour); + background-color: var(--global-bg-colour); padding: 4px 6px; margin: 0; border: 1px solid #7A7A7A; @@ -442,8 +442,9 @@ nav, .mobileNavButton, #schedule, #wrapper { position: relative; z-index: 1; will-change: transform; - background-color: var(--slideout-bg-colour); /* A background-color is required */ + background-color: var(--global-bg-colour); /* A background-color is required */ min-height: 100vh; + transition: 0.5s; } .slideout-open, diff --git a/js/index.js b/js/index.js index 3aeee63..3d09206 100644 --- a/js/index.js +++ b/js/index.js @@ -161,6 +161,10 @@ function init() { CONFIG.validateVars(); + if (CONFIG.getVar("theme") === "dark") { + applyDarkTheme(); + } + updateDateObject(); createSlideout(); checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order @@ -271,6 +275,12 @@ function APIFetch(query, options = {}) { return fetch(APIURL + query, options); } +function applyDarkTheme() { + document.documentElement.style.setProperty("--normal-text-colour", "#FFF"); + document.documentElement.style.setProperty("--global-bg-colour", "#000"); + document.documentElement.style.setProperty("--invert-bg-colour", "#FFF"); +} + function changeTab(tabIndex) { tabIndex--; loadPage(tabIndex); diff --git a/js/settings.js b/js/settings.js index 2609b45..c72e1ec 100644 --- a/js/settings.js +++ b/js/settings.js @@ -53,7 +53,8 @@ function setupSettings() { ); setupRadio( STYLE_RADIO, - "theme" + "theme", + applyTheme ); setupRadio( SCHEDULE_COLOUR_MODE_RADIO, @@ -91,6 +92,14 @@ function saveDayTimeSwitch(evnt) { CONFIG.setVar("switchoverTime", evnt.target[0].value); } +function applyTheme() { + if (CONFIG.getVar("theme") === "dark") { + applyDarkTheme(); + } else { + document.documentElement.removeAttribute("style"); + } +} + function setupRadio(elementsCollection, storageKey, onchangeCallback) { const ELEMENTS = Array.prototype.slice.call(elementsCollection); From 8f654311be10e93cea5a3163aa14029a3527d4a5 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 31 Aug 2020 11:04:38 +0200 Subject: [PATCH 112/154] Fix regression causing schedule to visibly load forever if class was not found --- js/index.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/js/index.js b/js/index.js index 3d09206..1376c7d 100644 --- a/js/index.js +++ b/js/index.js @@ -611,13 +611,19 @@ function intoText(obj) { function getScheduleJSON(className, week, weekDay) { return new Promise(async (resolve, reject) => { - const [ - renderKeyResp, - classGUID - ] = await Promise.all([ - fetchRenderKeyFromAPI(), - getClassGUIDByName(className) - ]); + let renderKeyResp, classGUID; + + try { + const resp = await Promise.all([ + fetchRenderKeyFromAPI(), + getClassGUIDByName(className) + ]); + + renderKeyResp = resp[0]; + classGUID = resp[1]; + } catch (error) { + return reject(error); + } const renderKey = renderKeyResp.data.key; From fca2889d5334ea0daf5c6f84264fc5916c8fd85e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 31 Aug 2020 11:05:29 +0200 Subject: [PATCH 113/154] Update Canary hostname --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 1376c7d..082f168 100644 --- a/js/index.js +++ b/js/index.js @@ -220,7 +220,7 @@ function init() { APIURL = sessionStorage.getItem("APIURLOverride") || DEFAULT_API_URL; - if (location.hostname === "berzan.netlify.com") + if (location.hostname === "berzan.netlify.app") document.getElementById("identity").textContent += " (Canary)"; SPLASH_SCREEN.style.opacity = "0"; From 53ddca271d65c1e05d7abdc9adb5cf8860a4457d Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 31 Aug 2020 11:51:40 +0200 Subject: [PATCH 114/154] Fix schedule attempting to render when it should not --- js/index.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/js/index.js b/js/index.js index 082f168..ad600b3 100644 --- a/js/index.js +++ b/js/index.js @@ -18,6 +18,7 @@ const CONFIG = new ConfigManager(); const MODULES = new ModuleManager(); let allowKeyNav = true; let scheduleResizeTimer = null; +let scheduleInit = false; let scheduleWidth; let scheduleHeight; let scheduleMarginLeft; @@ -359,7 +360,9 @@ function resizeNeoschedule() { } scheduleResizeTimer = window.setTimeout(function() { updateNeoscheduleVars(); - handleRenderRequest(INPUT_FORM); + if (scheduleInit) { + handleRenderRequest(INPUT_FORM); + } }, 150); } } @@ -469,6 +472,7 @@ function setupNeoschedule() { const SUBMIT_BUTTON = SCHEDULE_INPUT_FORM[2]; const DAY_DROPDOWN = SCHEDULE_INPUT_FORM[3]; sessionStorage.setItem("inputField0", DATE.getWeek().toString()); + scheduleInit = false; for (let i = 0; i < INPUT_FIELDS.length; i++) { if (sessionStorage.getItem("inputField" + i)) @@ -514,15 +518,22 @@ function setupNeoschedule() { handleRenderRequest(SCHEDULE_INPUT_FORM); }); DAY_DROPDOWN.addEventListener("change", function() { - handleRenderRequest(SCHEDULE_INPUT_FORM); + renderIfReasonable(SCHEDULE_INPUT_FORM); }); INPUT_FIELDS[0].addEventListener("change", function() { - handleRenderRequest(SCHEDULE_INPUT_FORM); + renderIfReasonable(SCHEDULE_INPUT_FORM); }); } +function renderIfReasonable(inputForm) { + if (inputForm[1].value.length !== 0) { + handleRenderRequest(inputForm); + } +} + function handleRenderRequest(form) { const SCHEDULE_MOUNT = document.getElementById("scheduleMount"); + scheduleInit = true; while (SCHEDULE_MOUNT.firstChild) { SCHEDULE_MOUNT.firstChild.remove(); From 862fd692dab699f10025d72133566ea2c3df6e2e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 31 Aug 2020 12:02:55 +0200 Subject: [PATCH 115/154] Made time fields wider to hopefully accomodate for people using PM/AM --- css/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/css/style.css b/css/style.css index caaf34e..fbb01cb 100644 --- a/css/style.css +++ b/css/style.css @@ -287,6 +287,11 @@ nav, .mobileNavButton, #schedule, #wrapper { line-height: normal; } +.field[type="time"] { + width: 7.5em; + max-width: unset; +} + .scheduleElement { position: absolute; z-index: -1; From e0a47348e21eb6596525e9159630526bd130f75e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 31 Aug 2020 13:50:22 +0200 Subject: [PATCH 116/154] Rework switchover time implementation --- js/index.js | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/js/index.js b/js/index.js index ad600b3..626985b 100644 --- a/js/index.js +++ b/js/index.js @@ -166,7 +166,6 @@ function init() { applyDarkTheme(); } - updateDateObject(); createSlideout(); checkDeviceType(); // Check orientation fails if slideout hasn't been created, please keep them this order @@ -340,16 +339,6 @@ function showSnackbar(text) { }); } -function updateDateObject() { - const switchoverTime = CONFIG.getVar("switchoverTime"); - - const NOW_DATE = new Date(); - const DATE_AND_TIME_ARR = switchoverTime.split(":"); - - DATE.setHours(NOW_DATE.getHours() + parseInt(DATE_AND_TIME_ARR[0])); - DATE.setMinutes(NOW_DATE.getMinutes() + parseInt(DATE_AND_TIME_ARR[1])); -} - function resizeNeoschedule() { checkDeviceType(); @@ -490,11 +479,34 @@ function setupNeoschedule() { if (isMobile) { SUBMIT_BUTTON.textContent = "Visa"; - if (DATE.getDay() < 6) { - DAY_DROPDOWN.selectedIndex = DATE.getDay() === 0 ? 1 : DATE.getDay(); + + const currentDay = DATE.getDay(); + + if (currentDay < 6) { + DAY_DROPDOWN.selectedIndex = currentDay === 0 ? 1 : currentDay; } else { DAY_DROPDOWN.selectedIndex = 1; } + + const [ + switchoverHourString, + switchoverMinuteString + ] = CONFIG.getVar("switchoverTime").split(":"); + + const switchoverHour = parseInt(switchoverHourString); + const switchoverMinute = parseInt(switchoverMinuteString); + + const currentHour = DATE.getHours(); + + if ( + !((switchoverHour === currentHour && + switchoverMinute >= DATE.getMinutes()) || + switchoverHour > currentHour) && + currentDay !== 0 && + currentDay !== 6 + ) { + DAY_DROPDOWN.selectedIndex++; + } } else { SUBMIT_BUTTON.textContent = "Visa schema"; DAY_DROPDOWN.selectedIndex = 0; From 0da36b337488a053d3a794aed523cb137e6d0337 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 1 Sep 2020 21:26:55 +0200 Subject: [PATCH 117/154] Fix bug where default configuration would cause tomorrow's schedule to be shown rather than today's --- js/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index 626985b..dbcbdbd 100644 --- a/js/index.js +++ b/js/index.js @@ -488,10 +488,12 @@ function setupNeoschedule() { DAY_DROPDOWN.selectedIndex = 1; } + const switchoverTime = CONFIG.getVar("switchoverTime"); + const [ switchoverHourString, switchoverMinuteString - ] = CONFIG.getVar("switchoverTime").split(":"); + ] = switchoverTime.split(":"); const switchoverHour = parseInt(switchoverHourString); const switchoverMinute = parseInt(switchoverMinuteString); @@ -499,7 +501,8 @@ function setupNeoschedule() { const currentHour = DATE.getHours(); if ( - !((switchoverHour === currentHour && + !(switchoverTime === "00:00" || + (switchoverHour === currentHour && switchoverMinute >= DATE.getMinutes()) || switchoverHour > currentHour) && currentDay !== 0 && From 559eee72d726534e730520ae24a4998a36366e95 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 30 Sep 2020 20:22:32 +0200 Subject: [PATCH 118/154] Update to support eduprox v0.2.0 --- js/index.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index dbcbdbd..603bc19 100644 --- a/js/index.js +++ b/js/index.js @@ -637,21 +637,34 @@ function intoText(obj) { function getScheduleJSON(className, week, weekDay) { return new Promise(async (resolve, reject) => { - let renderKeyResp, classGUID; + let renderKeyResp; + let selectionSignatureResp; try { const resp = await Promise.all([ fetchRenderKeyFromAPI(), - getClassGUIDByName(className) + fetchSignatureFromAPI(className) ]); renderKeyResp = resp[0]; - classGUID = resp[1]; + selectionSignatureResp = resp[1]; } catch (error) { return reject(error); } const renderKey = renderKeyResp.data.key; + const selectionSignature = selectionSignatureResp.data.signature; + + const springAutumnSwitchoverWeek = 25; + const currentYear = DATE.getFullYear(); + const selectedYear = + DATE.getWeek() > springAutumnSwitchoverWeek && + week < springAutumnSwitchoverWeek ? + currentYear + 1 : currentYear; + // I'll explain myself: + // If we're in Autumn term, add one year to current year if requesting + // schedule for Spring term. I did it this way since you probably don't + // want to see last year's Spring term during Autumn term. APIFetch(SCHEDULE_API_PREFIX + "schedule", { method: "POST", @@ -660,10 +673,11 @@ function getScheduleJSON(className, week, weekDay) { }, body: "{\"render_key\":\"" + renderKey + "\",\"unit_guid\":\"" + BERZAN_UNIT_GUID + - "\",\"selection_signature\":\"" + classGUID + + "\",\"selection_signature\":\"" + selectionSignature + "\",\"width\":" + parseInt(scheduleWidth) + ",\"height\":" + parseInt(scheduleHeight) + ",\"black_and_white\":" + getScheduleColourMode() + + ",\"year\":" + selectedYear + ",\"week\":" + parseInt(week) + ",\"day\":" + parseInt(weekDay) + "}" }).then(scheduleResp => { @@ -746,6 +760,19 @@ function fetchRenderKeyFromAPI() { }); } +function fetchSignatureFromAPI(to_sign) { + return APIFetch(SCHEDULE_API_PREFIX + "signature", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: "\"" + to_sign + "\"" + }) + .then(response => { + return response.json(); + }); +} + function rebuildClassGUIDCache() { return new Promise(resolve => { fetchClassGUIDsFromAPI() From 25c51996962f70e366b86dea128a8afe6ab57d70 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Wed, 30 Sep 2020 21:18:22 +0200 Subject: [PATCH 119/154] Bump version (oops) --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index f067174..1646c77 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1.2"; +const APP_CACHE = "berzanjs-app-cache-v1.2.1a"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", From bd2e835d9acd4fc02b1b4d9b72bf0e315c4d5860 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 20 Oct 2020 14:17:29 +0200 Subject: [PATCH 120/154] Improve workaround for weird timestamp placement in schedule --- js/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index 603bc19..1aff18d 100644 --- a/js/index.js +++ b/js/index.js @@ -629,8 +629,8 @@ function intoText(obj) { TEXT.style.top = (obj.y + scheduleMarginTop).toString() + "px"; TEXT.textContent = obj.text; if (TIMESTAMP_PATTERN.test(obj.text)) { - TEXT.style.lineHeight = "1.3"; - TEXT.style.marginLeft = "0.15em"; + TEXT.style.lineHeight = "1.6"; + TEXT.style.marginLeft = "0.25em"; } return TEXT; } From 542c5798db87527bf50e6bcf805c6de1d656af8b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 22 Oct 2020 12:58:23 +0200 Subject: [PATCH 121/154] Update README to reflect current development status --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 679393a..6866af5 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Berzan.js ## Introduction + Berzan.js is a specialised frontend for Skola24's schedule viewer and skolmaten.se's lunch viewer. -It is currently perpetually developed, with features being added and bugs fixed - as I find the motivation and inspiration to. The goal is to make it work across - as many devices as well as possible while maintaining its stability, speed, and - features. +As I don't have a lot of use for this personally any more I primarily fix bugs + and add features per request. I do, however, intend to keep it functioning as + long as there is interest in it doing so. ## Features @@ -37,6 +37,7 @@ Code used for proxying API calls: https://gitlab.com/Newbyte/eduprox * This was a branch I used when working on improving the broken hackjob that was my old service worker implementation. ## Third party code used + * Slideout.js * Bootstrap's Reboot was used as base for the stylesheet. From 3a6e45cc6b3eb49a69bab656b5d413693f43b29c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 22 Oct 2020 13:18:02 +0200 Subject: [PATCH 122/154] Show a text explaining what to do if no default class is saved --- js/index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index 1aff18d..a21fa11 100644 --- a/js/index.js +++ b/js/index.js @@ -470,11 +470,15 @@ function setupNeoschedule() { const defaultClass = CONFIG.getVar("defaultClass"); - if ( - defaultClass && - INPUT_FIELDS[1].value.length === 0 - ) { + if (defaultClass && INPUT_FIELDS[1].value.length === 0) { INPUT_FIELDS[1].value = defaultClass; + } else { + const scheduleMount = document.getElementById("scheduleMount"); + updateNeoscheduleVars(); + setScheduleStatusText( + scheduleMount, + "Välj klass för att visa ditt schema" + ); } if (isMobile) { From 162f9b41715646fcd8b9fcfbcce06444c5433f02 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 22 Oct 2020 13:23:07 +0200 Subject: [PATCH 123/154] Display validation error provided by Skola24 instead of [object Object] when schedule fetching fails --- js/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index a21fa11..78dceba 100644 --- a/js/index.js +++ b/js/index.js @@ -564,7 +564,8 @@ function handleRenderRequest(form) { .then(scheduleJSON => { if (scheduleJSON.data.timetableJson === null) { // FIXME: actually display error message - setScheduleStatusText(SCHEDULE_MOUNT, scheduleJSON); + const message = scheduleJSON.validation[0].message; + setScheduleStatusText(SCHEDULE_MOUNT, message); return; } removeScheduleStatusText(SCHEDULE_MOUNT); From 3cba367ef0b3f825c3d40d2358bcff92697b68f8 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 22 Oct 2020 13:28:01 +0200 Subject: [PATCH 124/154] Remove FIXME regarding error display as it was resolved in 162f9b41715646fcd8b9fcfbcce06444c5433f02 --- js/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/index.js b/js/index.js index 78dceba..916bbb3 100644 --- a/js/index.js +++ b/js/index.js @@ -563,7 +563,6 @@ function handleRenderRequest(form) { getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) .then(scheduleJSON => { if (scheduleJSON.data.timetableJson === null) { - // FIXME: actually display error message const message = scheduleJSON.validation[0].message; setScheduleStatusText(SCHEDULE_MOUNT, message); return; From 9a3c1e6328fffa0e22f0c7f1135f26f67c264d3a Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 22 Oct 2020 13:29:02 +0200 Subject: [PATCH 125/154] Remove dead code used for getting class GUIDs --- js/index.js | 79 ----------------------------------------------------- 1 file changed, 79 deletions(-) diff --git a/js/index.js b/js/index.js index 916bbb3..05f13c0 100644 --- a/js/index.js +++ b/js/index.js @@ -700,63 +700,6 @@ function getScheduleColourMode() { return (CONFIG.getVar("scheduleColourMode") === "blackAndWhite").toString(); } -function getClassGUIDByName(className, retried) { - return new Promise((resolve, reject) => { - className = className.toLowerCase(); - - getAllClassGUIDs() - .then(classGUIDs => { - if (classGUIDs.hasOwnProperty(className)) { - resolve(classGUIDs[className]); - } else { - if (retried !== true) { - rebuildClassGUIDCache() - .then(() => { - getClassGUIDByName(className, true) - .then(newClassGUID => resolve(newClassGUID)) - .catch(error => reject(error)); - }); - } else { - reject("Klassen hittades inte :("); - } - } - }) - }); -} - -async function getAllClassGUIDs() { - const CLASSES = localStorage.getItem("classGUIDs"); - - if (typeof CLASSES === "string") { - let classGUIDObj; - - try { - classGUIDObj = JSON.parse(CLASSES); - } catch (error) { - console.log("Class GUID cache invalid, rebuilding …"); - await rebuildClassGUIDCache(); - return await getAllClassGUIDs(); - } - - if (typeof classGUIDObj === "object") { - return new Promise(resolve => resolve(classGUIDObj)); - } else { - await rebuildClassGUIDCache(); - return await getAllClassGUIDs(); - } - } else { - await rebuildClassGUIDCache(); - return await getAllClassGUIDs(); - } -} - -function fetchClassGUIDsFromAPI() { - return APIFetch(SCHEDULE_API_PREFIX + "classes") - .then(response => { - return response.json(); - }); -} - function fetchRenderKeyFromAPI() { return APIFetch(SCHEDULE_API_PREFIX + "render-key") .then(response => { @@ -777,28 +720,6 @@ function fetchSignatureFromAPI(to_sign) { }); } -function rebuildClassGUIDCache() { - return new Promise(resolve => { - fetchClassGUIDsFromAPI() - .then(class_GUIDs => { - const NEAT_CLASS_GUIDS = getNeatClassGUIDsObject(class_GUIDs); - localStorage.setItem("classGUIDs", JSON.stringify(NEAT_CLASS_GUIDS)); - resolve(); - }); - }); -} - -function getNeatClassGUIDsObject(untidyObject) { - const untidyGroups = untidyObject.data.classes; - const neatObject = {}; - - for (let i = 0; i < untidyGroups.length; i++) { - neatObject[untidyGroups[i].groupName.toLowerCase()] = untidyGroups[i].groupGuid; - } - - return neatObject; -} - function setupSettings() { MODULES.load("settings", function() { setupSettings(); From 3fef05553ba82684ec8a665b42d18ca11feb4652 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 22 Oct 2020 16:29:31 +0200 Subject: [PATCH 126/154] Store and re-use render keys for 5 seconds to reduce amount of requests --- js/index.js | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/js/index.js b/js/index.js index 05f13c0..e702eea 100644 --- a/js/index.js +++ b/js/index.js @@ -23,6 +23,7 @@ let scheduleWidth; let scheduleHeight; let scheduleMarginLeft; let scheduleMarginTop; +let storedRenderKey = null; let isMobile; let slideout; let APIURL; @@ -641,24 +642,31 @@ function intoText(obj) { function getScheduleJSON(className, week, weekDay) { return new Promise(async (resolve, reject) => { - let renderKeyResp; - let selectionSignatureResp; + const noStoredKey = storedRenderKey === null; + let renderKey; + let selectionSignature; + + const requests = [ fetchSignatureFromAPI(className) ]; + + if (noStoredKey) { + requests.push(fetchRenderKeyFromAPI()); + } try { - const resp = await Promise.all([ - fetchRenderKeyFromAPI(), - fetchSignatureFromAPI(className) - ]); + const resp = await Promise.all(requests); - renderKeyResp = resp[0]; - selectionSignatureResp = resp[1]; + selectionSignature = resp[0].data.signature; + + if (noStoredKey) { + renderKey = resp[1].data.key; + storeRenderKey(renderKey); + } else { + renderKey = storedRenderKey; + } } catch (error) { return reject(error); } - const renderKey = renderKeyResp.data.key; - const selectionSignature = selectionSignatureResp.data.signature; - const springAutumnSwitchoverWeek = 25; const currentYear = DATE.getFullYear(); const selectedYear = @@ -696,6 +704,14 @@ function getScheduleJSON(className, week, weekDay) { }); } +function storeRenderKey(renderKey) { + storedRenderKey = renderKey; + + setTimeout(function() { + storedRenderKey = null; + }, 5000); +} + function getScheduleColourMode() { return (CONFIG.getVar("scheduleColourMode") === "blackAndWhite").toString(); } From 6c4dd81ac6ba50f17154c4bac3e00c46a4e2e99f Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 8 Nov 2020 22:38:25 +0100 Subject: [PATCH 127/154] Use new Eduprox URL --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index e702eea..1d08629 100644 --- a/js/index.js +++ b/js/index.js @@ -5,7 +5,7 @@ Date.prototype.getWeek = function() { return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); }; -const DEFAULT_API_URL = "https://eduprox.tn.dedyn.io/"; +const DEFAULT_API_URL = "https://eduprox.vt.dedyn.io/"; const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; From a6a476566ea270c6c731f16579134535bfb52262 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 8 Nov 2020 22:47:25 +0100 Subject: [PATCH 128/154] Service Worker: skip waiting --- sw.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sw.js b/sw.js index 1646c77..8f6239f 100644 --- a/sw.js +++ b/sw.js @@ -17,7 +17,11 @@ const URLS_TO_CACHE = [ "https://cdnjs.cloudflare.com/ajax/libs/slideout/1.0.1/slideout.js" ]; +let refreshing = false; + self.addEventListener("install", function(evnt) { + skipWaiting(); + evnt.waitUntil( caches.open(APP_CACHE) .then(function(cache) { @@ -91,6 +95,16 @@ self.addEventListener("fetch", function(evnt){ ); }); +self.addEventListener("controllerchange", () => { + if (refreshing) { + return; // Prevent infinite refresh loops + } + + refreshing = true; + + window.location.reload(); +}); + async function refreshCacheEntry(request, clientID) { fetch(request) .then(async response => { From e056b3daa8dfe2be92cef763cdbde61d995c9950 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 3 Dec 2020 09:21:59 +0100 Subject: [PATCH 129/154] Update eduprox link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6866af5..2e1c818 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ As I don't have a lot of use for this personally any more I primarily fix bugs ## Related sources -Code used for proxying API calls: https://gitlab.com/Newbyte/eduprox +Code used for proxying API calls: https://gitlab.com/libredu/eduprox ## Guide to branches From 5bdace655e7b02e97f5a153cfc28a433f14a3d3c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 18 Dec 2020 12:00:37 +0100 Subject: [PATCH 130/154] Ensure that class name is not 0 characters before requesting --- js/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 1d08629..0bb5350 100644 --- a/js/index.js +++ b/js/index.js @@ -561,7 +561,15 @@ function handleRenderRequest(form) { setScheduleStatusText(SCHEDULE_MOUNT, "Laddar…"); - getScheduleJSON(form[1].value, form[0].value, form[3].selectedIndex) + const className = form[1].value; + + if (className.length === 0) { + showSnackbar("Välj en klass först"); + removeScheduleStatusText(SCHEDULE_MOUNT); + return; + } + + getScheduleJSON(className, form[0].value, form[3].selectedIndex) .then(scheduleJSON => { if (scheduleJSON.data.timetableJson === null) { const message = scheduleJSON.validation[0].message; From 2129eea4aebc6f2dc8d947df6b6e79870625de2e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 18 Dec 2020 12:01:56 +0100 Subject: [PATCH 131/154] Show schedule errors via setScheduleStatusText instead of showSnackbar --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 0bb5350..b050d85 100644 --- a/js/index.js +++ b/js/index.js @@ -584,7 +584,7 @@ function handleRenderRequest(form) { }) .catch(error => { removeScheduleStatusText(SCHEDULE_MOUNT); - showSnackbar(error); + setScheduleStatusText(SCHEDULE_MOUNT, error); }); } From 9e71cf93d2692e39022ba98b283afc9dbd5b915c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 18 Dec 2020 12:02:15 +0100 Subject: [PATCH 132/154] Bump Berzan.js app cache version --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index 8f6239f..701651f 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1.2.1a"; +const APP_CACHE = "berzanjs-app-cache-v1.2.3"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", From 1eaca73ff2a52d6514db0974f05b8264640317d3 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 18 Dec 2020 12:18:51 +0100 Subject: [PATCH 133/154] Hopefully fix bug where renderKey sometimes would be null --- js/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/js/index.js b/js/index.js index b050d85..dba69da 100644 --- a/js/index.js +++ b/js/index.js @@ -650,13 +650,12 @@ function intoText(obj) { function getScheduleJSON(className, week, weekDay) { return new Promise(async (resolve, reject) => { - const noStoredKey = storedRenderKey === null; let renderKey; let selectionSignature; const requests = [ fetchSignatureFromAPI(className) ]; - if (noStoredKey) { + if (storedRenderKey === null) { requests.push(fetchRenderKeyFromAPI()); } @@ -665,7 +664,7 @@ function getScheduleJSON(className, week, weekDay) { selectionSignature = resp[0].data.signature; - if (noStoredKey) { + if (storedRenderKey === null) { renderKey = resp[1].data.key; storeRenderKey(renderKey); } else { From 1c0e358fd6c15d82bc27fb18562ccbf0ba125ba4 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 18 Dec 2020 12:19:07 +0100 Subject: [PATCH 134/154] Add assertion that will fail if render key is null --- js/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/index.js b/js/index.js index dba69da..c5000b7 100644 --- a/js/index.js +++ b/js/index.js @@ -685,6 +685,8 @@ function getScheduleJSON(className, week, weekDay) { // schedule for Spring term. I did it this way since you probably don't // want to see last year's Spring term during Autumn term. + console.assert(renderKey !== null, "Render key was null"); + APIFetch(SCHEDULE_API_PREFIX + "schedule", { method: "POST", headers: { From c847237edde4a8b3677b81ed993776d82cd923be Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sat, 9 Jan 2021 11:08:48 +0100 Subject: [PATCH 135/154] Change to a hopefully better getWeek() implementation --- js/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index c5000b7..db49872 100644 --- a/js/index.js +++ b/js/index.js @@ -1,8 +1,11 @@ "use strict"; Date.prototype.getWeek = function() { - const ONEJAN = new Date(this.getFullYear(), 0, 1); - return Math.ceil((((this - ONEJAN) / 86400000) + ONEJAN.getDay() + 1) / 7); + // Taken from https://stackoverflow.com/a/6117889 + const date = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate())); + date.setUTCDate(date.getUTCDate() + 4 - (date.getUTCDay() || 7)); + const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1)); + return Math.ceil((((date - yearStart) / 86400000) + 1) / 7); }; const DEFAULT_API_URL = "https://eduprox.vt.dedyn.io/"; From eb5a47bba8194e17b0bea35d88c2e84e8f785a24 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sat, 9 Jan 2021 14:19:10 +0100 Subject: [PATCH 136/154] Rework to use new schedule schema --- css/style.css | 6 ---- js/index.js | 96 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/css/style.css b/css/style.css index fbb01cb..2ab2d3e 100644 --- a/css/style.css +++ b/css/style.css @@ -292,11 +292,6 @@ nav, .mobileNavButton, #schedule, #wrapper { max-width: unset; } -.scheduleElement { - position: absolute; - z-index: -1; -} - #identity { padding-top: 8px; font-size: 30px; @@ -360,7 +355,6 @@ nav, .mobileNavButton, #schedule, #wrapper { #scheduleMount { text-align: center; - font-size: 2.5em; color: #222222; } diff --git a/js/index.js b/js/index.js index db49872..83ca971 100644 --- a/js/index.js +++ b/js/index.js @@ -12,6 +12,7 @@ const DEFAULT_API_URL = "https://eduprox.vt.dedyn.io/"; const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; +const SVG_XMLNS = "http://www.w3.org/2000/svg"; const TIMESTAMP_PATTERN = /\d+:\d+/; const NAVIGATION_BUTTONS = document.getElementsByClassName("navButton"); const MOBILE_NAV_BUTTONS = document.getElementsByClassName("mobileNavButton"); @@ -594,6 +595,7 @@ function handleRenderRequest(form) { function setScheduleStatusText(scheduleMount, text) { scheduleMount.style.height = scheduleHeight + "px"; scheduleMount.style.lineHeight = scheduleHeight * 0.8 + "px"; + scheduleMount.style.fontSize = "2.5em"; scheduleMount.style.fontWeight = "lighter"; scheduleMount.textContent = text; } @@ -603,52 +605,80 @@ function removeScheduleStatusText(scheduleMount) { scheduleMount.removeAttribute("style"); } -function renderSchedule(scheduleJSONString, scheduleMount) { - const SCHEDULE_CONTAINER = document.createElement("DIV"); - const SCHEDULE_JSON = JSON.parse(scheduleJSONString.data.timetableJson); - const BOXES = SCHEDULE_JSON.boxList; - const TEXTS = SCHEDULE_JSON.textList; +function renderSchedule(scheduleJsonString, scheduleMount) { + const scheduleJson = scheduleJsonString.data; - for (let i = 0; i < BOXES.length; i++) { - const BOX = intoBox(BOXES[i]); - SCHEDULE_CONTAINER.appendChild(BOX); + const scheduleSvg = document.createElementNS(SVG_XMLNS, "svg"); + scheduleSvg.setAttributeNS(null, "viewBox", "0 0 " + scheduleWidth + " " + scheduleHeight); + scheduleSvg.setAttributeNS(null, "shape-rendering", "crispEdges"); + scheduleSvg.setAttributeNS(null, "width", scheduleWidth); + scheduleSvg.setAttributeNS(null, "height", scheduleHeight); + + const boxes = scheduleJson.boxList; + const lines = scheduleJson.lineList; + const texts = scheduleJson.textList; + + for (let i = 0; i < boxes.length; i++) { + const box = intoBox(boxes[i]); + scheduleSvg.appendChild(box); + } + + for (let i = 0; i < lines.length; i++) { + const line = intoLine(lines[i]); + scheduleSvg.appendChild(line); } - for (let i = 0; i < TEXTS.length; i++) { - const TEXT = intoText(TEXTS[i]); - SCHEDULE_CONTAINER.appendChild(TEXT); + for (let i = 0; i < texts.length; i++) { + const text = intoText(texts[i]); + scheduleSvg.appendChild(text); } - scheduleMount.appendChild(SCHEDULE_CONTAINER); + scheduleMount.appendChild(scheduleSvg); } function intoBox(obj) { - const BOX = document.createElement("DIV"); - BOX.classList.add("scheduleElement"); - BOX.style.boxSizing = "content-box"; - BOX.style.backgroundColor = obj.bcolor; - BOX.style.color = obj.fcolor; - BOX.style.height = obj.height.toString() + "px"; - BOX.style.width = obj.width.toString() + "px"; - BOX.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; - BOX.style.top = (obj.y + scheduleMarginTop).toString() + "px"; - BOX.style.border = "1px solid rgb(0, 0, 0)"; - return BOX; + const box = document.createElementNS(SVG_XMLNS, "rect"); + box.style.fill = obj.bColor; + box.style.stroke = obj.fColor; + box.setAttributeNS(null, "height", obj.height); + box.setAttributeNS(null, "width", obj.width); + box.setAttributeNS(null, "x", obj.x); + box.setAttributeNS(null, "y", obj.y); + return box; +} + +function intoLine(obj) { + const line = document.createElementNS(SVG_XMLNS, "line"); + line.setAttributeNS(null, "x1", obj.p1x); + line.setAttributeNS(null, "x2", obj.p2x); + line.setAttributeNS(null, "y1", obj.p1y); + line.setAttributeNS(null, "y2", obj.p2y); + line.setAttributeNS(null, "stroke", obj.color); + return line; } function intoText(obj) { - const TEXT = document.createElement("SPAN"); - TEXT.classList.add("scheduleElement"); - TEXT.style.color = obj.fcolor; - TEXT.style.fontSize = obj.fontsize.toString() + "px"; - TEXT.style.left = (obj.x - scheduleMarginLeft).toString() + "px"; - TEXT.style.top = (obj.y + scheduleMarginTop).toString() + "px"; - TEXT.textContent = obj.text; + const text = document.createElementNS(SVG_XMLNS, "text"); + text.style.fontSize = obj.fontsize + "px"; + text.style.fontFamily = "Open Sans"; + text.style.fill = obj.fColor; + text.style.pointerEvents = "none"; + text.setAttributeNS(null, "x", obj.x + 1); + text.setAttributeNS(null, "y", obj.y + 14); + text.textContent = obj.text; + if (obj.bold) { + text.style.fontWeight = "bold"; + } + if (obj.italic) { + text.style.fontStyle = "italic"; + } + /* if (TIMESTAMP_PATTERN.test(obj.text)) { - TEXT.style.lineHeight = "1.6"; - TEXT.style.marginLeft = "0.25em"; + text.style.lineheight = "1.6"; + text.style.marginLeft = "0.25em"; } - return TEXT; + */ + return text; } function getScheduleJSON(className, week, weekDay) { From 1175efddab8b56f3e50a867b4ec722f93d85b13d Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 18 Jan 2021 15:28:33 +0100 Subject: [PATCH 137/154] Add comment about arbitary addition in intoText() --- js/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/index.js b/js/index.js index 83ca971..6e17189 100644 --- a/js/index.js +++ b/js/index.js @@ -663,6 +663,7 @@ function intoText(obj) { text.style.fontFamily = "Open Sans"; text.style.fill = obj.fColor; text.style.pointerEvents = "none"; + // Why is it necessary to add these arbitary numbers? Ask Skola24 text.setAttributeNS(null, "x", obj.x + 1); text.setAttributeNS(null, "y", obj.y + 14); text.textContent = obj.text; From 1d296ff3605b3fe7bd68067529c591206afa2fa5 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 18 Jan 2021 15:28:41 +0100 Subject: [PATCH 138/154] Remove zombie code --- js/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/js/index.js b/js/index.js index 6e17189..cdebce4 100644 --- a/js/index.js +++ b/js/index.js @@ -673,12 +673,6 @@ function intoText(obj) { if (obj.italic) { text.style.fontStyle = "italic"; } - /* - if (TIMESTAMP_PATTERN.test(obj.text)) { - text.style.lineheight = "1.6"; - text.style.marginLeft = "0.25em"; - } - */ return text; } From 264b34ad09069ef4cd7703aa83ff78e3a9918edf Mon Sep 17 00:00:00 2001 From: Newbyte Date: Mon, 18 Jan 2021 15:55:18 +0100 Subject: [PATCH 139/154] Fix display of validation errors --- js/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index cdebce4..9309739 100644 --- a/js/index.js +++ b/js/index.js @@ -575,9 +575,9 @@ function handleRenderRequest(form) { getScheduleJSON(className, form[0].value, form[3].selectedIndex) .then(scheduleJSON => { - if (scheduleJSON.data.timetableJson === null) { + if (scheduleJSON.validation.length !== 0) { const message = scheduleJSON.validation[0].message; - setScheduleStatusText(SCHEDULE_MOUNT, message); + setScheduleStatusText(SCHEDULE_MOUNT, "Något gick snett: " + message); return; } removeScheduleStatusText(SCHEDULE_MOUNT); From a386437699fab214cba9d9114c8670acd2f8102b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 2 Mar 2021 11:15:53 +0100 Subject: [PATCH 140/154] Update links to point to new GitLab organisation --- views/about.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/about.html b/views/about.html index f7326a5..ca875f7 100644 --- a/views/about.html +++ b/views/about.html @@ -6,11 +6,11 @@

Källkod

Berzan.js klient

-

Berzan.js backend

+

Berzan.js backend (Eduprox)

From eeca7cb962864925c30d3a1bf19f10115ebf4e01 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Tue, 2 Mar 2021 11:17:44 +0100 Subject: [PATCH 141/154] Bump app cache version to v1.2.4 --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index 701651f..fb94646 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1.2.3"; +const APP_CACHE = "berzanjs-app-cache-v1.2.4"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", From b8ca745389527dc8974548daa131093bb76d032a Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 25 Apr 2021 12:20:37 +0200 Subject: [PATCH 142/154] Switch to new host for Eduprox --- js/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index 9309739..d86f48f 100644 --- a/js/index.js +++ b/js/index.js @@ -8,7 +8,7 @@ Date.prototype.getWeek = function() { return Math.ceil((((date - yearStart) / 86400000) + 1) / 7); }; -const DEFAULT_API_URL = "https://eduprox.vt.dedyn.io/"; +const DEFAULT_API_URL = "https://eduprox.k11m1.eu/"; const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; @@ -704,10 +704,12 @@ function getScheduleJSON(className, week, weekDay) { const springAutumnSwitchoverWeek = 25; const currentYear = DATE.getFullYear(); - const selectedYear = + const selectedYear = 2018; + /* DATE.getWeek() > springAutumnSwitchoverWeek && week < springAutumnSwitchoverWeek ? currentYear + 1 : currentYear; + */ // I'll explain myself: // If we're in Autumn term, add one year to current year if requesting // schedule for Spring term. I did it this way since you probably don't From dd2bcb3c8f8a70f62fb0c84bb37bbc5332057f35 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 25 Apr 2021 12:22:04 +0200 Subject: [PATCH 143/154] Revert "Switch to new host for Eduprox" This reverts commit b8ca745389527dc8974548daa131093bb76d032a. I had apparently included some unintended changes with this, so revert for now. --- js/index.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/js/index.js b/js/index.js index d86f48f..9309739 100644 --- a/js/index.js +++ b/js/index.js @@ -8,7 +8,7 @@ Date.prototype.getWeek = function() { return Math.ceil((((date - yearStart) / 86400000) + 1) / 7); }; -const DEFAULT_API_URL = "https://eduprox.k11m1.eu/"; +const DEFAULT_API_URL = "https://eduprox.vt.dedyn.io/"; const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; @@ -704,12 +704,10 @@ function getScheduleJSON(className, week, weekDay) { const springAutumnSwitchoverWeek = 25; const currentYear = DATE.getFullYear(); - const selectedYear = 2018; - /* + const selectedYear = DATE.getWeek() > springAutumnSwitchoverWeek && week < springAutumnSwitchoverWeek ? currentYear + 1 : currentYear; - */ // I'll explain myself: // If we're in Autumn term, add one year to current year if requesting // schedule for Spring term. I did it this way since you probably don't From af45fbe66450b620bfb8657b2778481bd0672772 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 25 Apr 2021 12:23:17 +0200 Subject: [PATCH 144/154] Switch to new host for Eduprox Current host will be going down tomorrow (26th of April), time to move! --- js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/index.js b/js/index.js index 9309739..b9da222 100644 --- a/js/index.js +++ b/js/index.js @@ -8,7 +8,7 @@ Date.prototype.getWeek = function() { return Math.ceil((((date - yearStart) / 86400000) + 1) / 7); }; -const DEFAULT_API_URL = "https://eduprox.vt.dedyn.io/"; +const DEFAULT_API_URL = "https://eduprox.k11m1.eu/"; const SCHEDULE_API_PREFIX = "skola24/v0/"; const BERZAN_UNIT_GUID = "ODUzZGRmNmMtYzdiNy1mZTA3LThlMTctNzIyNDY2Mjk1Y2I2"; const SETTINGS_KEY = "berzanjsConfig"; From 86480687961dc4e429f3eba1ab4590fbd361c04e Mon Sep 17 00:00:00 2001 From: Newbyte Date: Sun, 25 Apr 2021 12:29:43 +0200 Subject: [PATCH 145/154] Bump app cache version to v1.2.5 --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index fb94646..8c32c84 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1.2.4"; +const APP_CACHE = "berzanjs-app-cache-v1.2.5"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/", From 5d01cc0e2e310dad4619b5658810dfc999db4c9f Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 4 Aug 2022 16:51:59 -0400 Subject: [PATCH 146/154] Update featureset in readme to reflect current status The caching strategy I went with was broken by the render token system that Skola24 implemented, and I don't think I will fix it. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2e1c818..2982643 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ As I don't have a lot of use for this personally any more I primarily fix bugs * Schedule viewer * Lunch viewer -* Offline viewing of schedule (and soon lunch) * Ability to set default class for schedule viewer * User interface adapts to whatever device you're using From 678a0746371a585550e68985c556188fe40c6c1d Mon Sep 17 00:00:00 2001 From: Newbyte Date: Thu, 4 Aug 2022 16:53:55 -0400 Subject: [PATCH 147/154] Update link to Eduprox Eduprox was moved to Codeberg due to GitLab.com's upcoming data retention policy: https://www.theregister.com/2022/08/04/gitlab_data_retention_policy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2982643..dcd49c1 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ As I don't have a lot of use for this personally any more I primarily fix bugs ## Related sources -Code used for proxying API calls: https://gitlab.com/libredu/eduprox +Code used for proxying API calls: https://codeberg.org/libredu/eduprox ## Guide to branches From 33e05dbfbf7ca0c4af8ab95fb3894d8f49270afc Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 13:57:24 -0400 Subject: [PATCH 148/154] Update feedback link on loading screen to point to GitHub issues --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index aae7052..9754e29 100644 --- a/index.html +++ b/index.html @@ -31,7 +31,7 @@

Berzan.js

- Feedback - Webbläsare som stöds + Feedback - Webbläsare som stöds
Schema
From bb5473d7fa75b584a9dce83357c200702e2b2939 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 14:00:02 -0400 Subject: [PATCH 149/154] Remove link to GitLab mirror in about view It will probably automatically be deleted by GitLab.com due to inactivity eventually, so let's stop linking to it already. See https://www.theregister.com/2022/08/04/gitlab_data_retention_policy --- views/about.html | 1 - 1 file changed, 1 deletion(-) diff --git a/views/about.html b/views/about.html index ca875f7..0f666cd 100644 --- a/views/about.html +++ b/views/about.html @@ -6,7 +6,6 @@

Källkod

Berzan.js klient

Berzan.js backend (Eduprox)

    From 49aaf74904498ecb97b9a3eb729f0dd507e78ad3 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 14:00:55 -0400 Subject: [PATCH 150/154] Link to Eduprox on Codeberg instead of GitLab in about view The active development repository for Eduprox has been moved to Codeberg due to GitLab's upcoming data retention policy. See https://www.theregister.com/2022/08/04/gitlab_data_retention_policy --- views/about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/about.html b/views/about.html index 0f666cd..dc70e37 100644 --- a/views/about.html +++ b/views/about.html @@ -9,7 +9,7 @@

    Berzan.js klient

Berzan.js backend (Eduprox)

From 686ef648b80326b45da226ffad428ce24b770e4c Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 14:16:23 -0400 Subject: [PATCH 151/154] Revert "Link to Eduprox on Codeberg instead of GitLab in about view" GitLab has responded to the backlash and decided against removing inactive projects from GitLab.com, so let's not move things needlessly. See https://twitter.com/gitlab/status/1555325376687226883 This reverts commit 49aaf74904498ecb97b9a3eb729f0dd507e78ad3. --- views/about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/about.html b/views/about.html index dc70e37..0f666cd 100644 --- a/views/about.html +++ b/views/about.html @@ -9,7 +9,7 @@

Berzan.js klient

Berzan.js backend (Eduprox)

From 0dc7b6cbb27b12886c21c787065c447f1541b23b Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 14:17:29 -0400 Subject: [PATCH 152/154] Revert "Remove link to GitLab mirror in about view" GitLab went back on their new data retention policy, so let's keep linking to this mirror. See https://twitter.com/gitlab/status/1555325376687226883 This reverts commit bb5473d7fa75b584a9dce83357c200702e2b2939. --- views/about.html | 1 + 1 file changed, 1 insertion(+) diff --git a/views/about.html b/views/about.html index 0f666cd..ca875f7 100644 --- a/views/about.html +++ b/views/about.html @@ -6,6 +6,7 @@

Källkod

Berzan.js klient

Berzan.js backend (Eduprox)

    From 1aba84d1eeaa99b3a5349d179ad50a77f7bf6ee7 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 14:18:23 -0400 Subject: [PATCH 153/154] Revert "Update link to Eduprox" GitLab changed their minds about deleting inactive repos, so let's not move things needlessly. See https://twitter.com/gitlab/status/1555325376687226883 This reverts commit 678a0746371a585550e68985c556188fe40c6c1d. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dcd49c1..2982643 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ As I don't have a lot of use for this personally any more I primarily fix bugs ## Related sources -Code used for proxying API calls: https://codeberg.org/libredu/eduprox +Code used for proxying API calls: https://gitlab.com/libredu/eduprox ## Guide to branches From 6f9ff311586a0ad08d3a63fc48a16f40d7d27fb0 Mon Sep 17 00:00:00 2001 From: Newbyte Date: Fri, 5 Aug 2022 14:42:10 -0400 Subject: [PATCH 154/154] Bump app cache version to v1.2.6 --- sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw.js b/sw.js index 8c32c84..3fc53ed 100644 --- a/sw.js +++ b/sw.js @@ -1,6 +1,6 @@ "use strict"; -const APP_CACHE = "berzanjs-app-cache-v1.2.5"; +const APP_CACHE = "berzanjs-app-cache-v1.2.6"; const CONTENT_CACHE = "berzanjs-schedule-cache-v1"; const URLS_TO_CACHE = [ "/",