summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2021-05-16 17:05:33 +0200
committerAnton Luka Šijanec <anton@sijanec.eu>2021-05-16 17:05:33 +0200
commitf289d32c979cccc6626932575cf15d65c0562885 (patch)
tree297222608598dae2478c79f4e82b655c6c497292
parentMerge pull request '1.0.16.4-beta' (#2) from dev into master (diff)
parent1.0.17.0-beta (diff)
downloadbeziapp-f289d32c979cccc6626932575cf15d65c0562885.tar
beziapp-f289d32c979cccc6626932575cf15d65c0562885.tar.gz
beziapp-f289d32c979cccc6626932575cf15d65c0562885.tar.bz2
beziapp-f289d32c979cccc6626932575cf15d65c0562885.tar.lz
beziapp-f289d32c979cccc6626932575cf15d65c0562885.tar.xz
beziapp-f289d32c979cccc6626932575cf15d65c0562885.tar.zst
beziapp-f289d32c979cccc6626932575cf15d65c0562885.zip
-rw-r--r--assets/js/colors.js46
-rw-r--r--assets/js/gradings.js20
-rw-r--r--assets/js/gsec.js4
-rw-r--r--assets/js/lang/bundle.js.bvr10
-rw-r--r--assets/js/settings.js21
-rw-r--r--assets/js/setup-storage.js.bvr1
-rw-r--r--assets/js/timetable.js40
-rw-r--r--assets/pages-src/changelog.bvr17
-rw-r--r--assets/pages-src/gradings.bvr3
-rw-r--r--assets/pages-src/settings.bvr13
-rw-r--r--assets/pages-src/timetable.bvr1
-rwxr-xr-xdist/cache_name.txt2
-rwxr-xr-xdist/js/app.js4
-rwxr-xr-xdist/js/colors.js10
-rwxr-xr-xdist/js/gradings.js5
-rwxr-xr-xdist/js/gsec.js2
-rwxr-xr-xdist/js/lang/bundle.js10
-rwxr-xr-xdist/js/settings.js8
-rwxr-xr-xdist/js/setup-storage.js1
-rwxr-xr-xdist/js/timetable.js12
-rwxr-xr-xdist/pages/about.html4
-rwxr-xr-xdist/pages/changelog.html17
-rwxr-xr-xdist/pages/gradings.html3
-rwxr-xr-xdist/pages/settings.html13
-rwxr-xr-xdist/pages/timetable.html1
-rwxr-xr-xdist/sw.js4
-rw-r--r--global.bvr2
-rw-r--r--server/glasovanje/index.php183
28 files changed, 380 insertions, 77 deletions
diff --git a/assets/js/colors.js b/assets/js/colors.js
new file mode 100644
index 0000000..d06861a
--- /dev/null
+++ b/assets/js/colors.js
@@ -0,0 +1,46 @@
+/* adapted from https://git.šijanec.eu/siska/beziapp-sam-lepo */
+
+function linMap(c, mn, mx) {
+ return c*(mx-mn)+mn;
+}
+function getDecimal(n) {
+ return (n-Math.floor(n));
+}
+function mapColorPalete(c, palete) {
+ let poz = c*(palete.length-1);
+ let col1 = palete[Math.floor(poz)]; /* https://git.šijanec.eu/siska/beziapp-sam-lepo */
+ let col2 = palete[Math.ceil(poz)]; /* made by siska */
+ return (Math.floor(linMap(getDecimal(poz),col1[0],col2[0])).toString(16).padStart(2,0)+
+ Math.floor(linMap(getDecimal(poz),col1[1],col2[1])).toString(16).padStart(2,0)+
+ Math.floor(linMap(getDecimal(poz),col1[2],col2[2])).toString(16).padStart(2,0)).toUpperCase();
+}
+/**
+ *
+ * Convert last 3 bytes of an integer to RGB color
+ * @param {integer} input_integer Integer that will be converted to RGB color
+ * @returns {string} Hex color code
+ *
+ */
+function intToRGB(i, palete = null) {
+ if (palete == null) {
+ var c = (i & 0x00FFFFFF)
+ .toString(16)
+ .toUpperCase();
+
+ return "00000".substring(0, 6 - c.length) + c;
+ } else return mapColorPalete((i & 0xFF) / 0xFF, palete);
+}
+
+
+/**
+ *
+ * Convert a given string to hex color
+ * @param {string} input_string Input string
+ * @returns {string} Hex RGB color
+ */
+function getHexColorFromString(str) {
+ if (urnikTheme == "privzeta")
+ return "#" + intToRGB(hashCode(str));
+ else
+ return "#" + intToRGB(hashCode(str), [[38, 70, 83], [42, 157, 143], [233, 196, 106], [244, 162, 97], [231, 111, 81]]);
+}
diff --git a/assets/js/gradings.js b/assets/js/gradings.js
index 92e696d..7db4c98 100644
--- a/assets/js/gradings.js
+++ b/assets/js/gradings.js
@@ -32,14 +32,6 @@ function hashCode(str) { // java String#hashCode
return hash;
}
-function intToRGB(i) {
- var c = (i & 0x00FFFFFF)
- .toString(16)
- .toUpperCase();
-
- return "00000".substring(0, 6 - c.length) + c;
-}
-
// http://www.w3.org/TR/AERT#color-contrast
function getForegroundFromBackground(background_color) {
let color_hex = background_color.replace("#", "");
@@ -56,11 +48,6 @@ function getForegroundFromBackground(background_color) {
}
}
-function getHexColorFromString(str) {
- return "#" + intToRGB(hashCode(str));
-}
-// --------------------------------------------------
-
function getDateString() {
let date = new Date();
@@ -171,9 +158,12 @@ function setupPickers() {
instances = M.Datepicker.init(elems, options);
}
+var urnikTheme = "privzeta";
-
-document.addEventListener("DOMContentLoaded", () => {
+document.addEventListener("DOMContentLoaded", async function () {
+ urnikTheme = await localforage.getItem("urnikTheme");
+ if (urnikTheme == null || urnikTheme == undefined || urnikTheme == false)
+ urnikTheme = "privzeta";
checkLogin();
// Calendar setup
var calendarEl = document.getElementById("calendar");
diff --git a/assets/js/gsec.js b/assets/js/gsec.js
index 3dcde88..2f5400d 100644
--- a/assets/js/gsec.js
+++ b/assets/js/gsec.js
@@ -236,12 +236,14 @@ class gsec {
var razred = desc[2];
var teacher = desc[3];
var place = desc[4];
+ var nadomescanje = urnikElement.parentElement.classList.contains("flagS");
urnik[day][period] = {
"subject": subject,
"acronym": abkurzung,
"class": razred,
"teacher": teacher,
- "place": place
+ "place": place,
+ "substitution": nadomescanje
};
}
resolve(urnik);
diff --git a/assets/js/lang/bundle.js.bvr b/assets/js/lang/bundle.js.bvr
index 125d3c6..c75e965 100644
--- a/assets/js/lang/bundle.js.bvr
+++ b/assets/js/lang/bundle.js.bvr
@@ -159,6 +159,7 @@ var langstrings = {
settings: "settings",
// timetable
noPeriods: "no periods in selected week",
+ substitution: "substitution",
// gradings
date: "date",
description: "description",
@@ -244,7 +245,7 @@ var langstrings = {
mealsUsageNote: "click on a date to open the collapsible menu with choices and click on a specific meal to select it. Reload the meals when you're done and check the entries.",
lunchesNote: "app was not tested with lunches in mind. Meals probably won't work with lunches and having a lunch subscription may even break its functionality.",
mealNotShownNote: "editable meals are highlighted in gold, read-only meals are highlighted in grey and cannot be changed. Meals that provide no options for menus are not shown for clarity, same applies for days where there are no meals",
- mealsContributeNote: "you are welcome to contribute to the LopolisAPI project and add features, such as checkouts.",
+ mealsContributeNote: "you are welcome to contribute to the BežiApp project.",
authenticationError: "authentication error",
lopolisAPIConnectionError: "LopolisAPI server connection error",
errorGettingMenus: "error getting menus",
@@ -315,6 +316,7 @@ var langstrings = {
on: "on",
off: "off",
selectErrorReporting: "should error reports be submitted to the developers?",
+ urnikTheme: "timetable theme",
// gsec
gsecErrNet: "GimSIS connection error",
gsecErrLogin: "GimSIS login error (bad password?), try logging out",
@@ -361,6 +363,7 @@ var langstrings = {
browserNotSupported: "BežiApp ne bo deloval na vaši napravi, če ne posodobite vašega Internetnega brskalnika",
// timetable
noPeriods: "ni ur v izbranem tednu",
+ substitution: "nadomeščanje",
// index
timetable: "urnik",
gradings: "ocenjevanja",
@@ -457,7 +460,7 @@ var langstrings = {
mealsUsageNote: "kliknite na datum za prikaz menijev, nato pa si enega izberite s klikom na ime menija. Po nastavitvi menijev ponovno naložite menije in se prepričajte o pravilnih nastavitvah.",
lunchesNote: "aplikacija ni testirana za naročanje na kosila, zato verjetno to ne deluje. Če ste naročeni na kosila lahko naročanje na menije sploh ne deluje ali pa deluje narobe.",
mealNotShownNote: "obroki, označeni z zlato so nastavljivi, tisti, označeni s sivo, niso, če pa pri kakšnem dnevu obroka ni, pa pomeni, da ga ni moč nastaviti ali pa da ne obrok ne obstaja",
- mealsContributeNote: "vabimo vas k urejanju LopolisAPI programa za upravljanje z meniji.",
+ mealsContributeNote: "vabimo vas k urejanju BežiApp programa.",
authenticationError: "napaka avtentikacije",
lopolisAPIConnectionError: "napaka povezave na LopolisAPI strežnik",
errorGettingMenus: "napaka branja menijev",
@@ -517,7 +520,7 @@ var langstrings = {
themeLight: "svetel izgled (privzeto)",
themeDark: "temen izgled",
themeNight: "nočni izgled",
- themeSet: "izgled nastavljen, odprite neko drugo stran da se spremembe uveljavijo",
+ themeSet: "izgled nastavljen, odprite neko drugo stran, da se spremembe uveljavijo",
selectTheme: "izberite željen izgled",
errorReportingSet: "nastavitev pošiljanja napak izbrana",
errorReporting: "pošiljanje napak",
@@ -528,6 +531,7 @@ var langstrings = {
triggerAgreement: "strinjam se z zgoraj navedenimi pogoji",
triggerWarningSet: "spremenili ste stanje dodatnih nastavitev",
additionalOptions: "dodatne nastavitve",
+ urnikTheme: "izgled urnika",
// gsec
gsecErrNet: "napaka povezave na GimSIS",
gsecErrLogin: "prijava v GimSIS ni uspela (napačno geslo?), poskusite se odjaviti",
diff --git a/assets/js/settings.js b/assets/js/settings.js
index 3106f14..2a721d7 100644
--- a/assets/js/settings.js
+++ b/assets/js/settings.js
@@ -14,6 +14,13 @@ async function setTheme(targetTheme) {
});
}
+async function setUrnikTheme(targetTheme) {
+ localforage.setItem("urnikTheme", targetTheme).then((value) => {
+ console.log("Urnik theme set" + value);
+ UIAlert(D("themeSet"), "setUrnikTheme(): themeSet")
+ });
+}
+
async function setErrorReporting(targetE) {
localforage.setItem("errorReporting", targetE).then((value) => {
console.log("ErrorReporing set: " + value);
@@ -82,7 +89,9 @@ document.addEventListener("DOMContentLoaded", async () => {
$("#select-errorreporting").on("change", function() {
setErrorReporting($(this).find(":selected").val());
});
-
+ $("#select-urniktheme").on("change", function() {
+ setUrnikTheme($(this).find(":selected").val());
+ });
localforage.getItem("chosenLang").then((value) => {
let selectedLanguage = value;
if(value == null || value.length < 1) {
@@ -90,7 +99,12 @@ document.addEventListener("DOMContentLoaded", async () => {
}
$(`#option-${selectedLanguage}`).attr("selected", true);
}).catch(() => {});
-
+ localforage.getItem("urnikTheme").then((value) => {
+ if (value == null || value.length < 1) {
+ value = "privzeta";
+ }
+ $(`#option-${value}`).attr("selected", true);
+ }).catch(()=>{});
localforage.getItem("theme").then((value) => {
let selectedTheme = value;
if(value == null || value.length < 1) {
@@ -124,6 +138,9 @@ document.addEventListener("DOMContentLoaded", async () => {
var elems = document.querySelectorAll(".errorreporting-select");
M.FormSelect.init(elems, {});
+ var elems = document.querySelectorAll(".urniktheme-select");
+ M.FormSelect.init(elems, {});
+
// Setup language select dropdown
var elems = document.querySelectorAll(".lang-select");
M.FormSelect.init(elems, {});
diff --git a/assets/js/setup-storage.js.bvr b/assets/js/setup-storage.js.bvr
index 3d3b554..75dfdf8 100644
--- a/assets/js/setup-storage.js.bvr
+++ b/assets/js/setup-storage.js.bvr
@@ -21,6 +21,7 @@ async function setupStorage(force = false) {
localforage.setItem("directory", {}), //\\ well I could remember my own code but I didn't.
localforage.setItem("meals", {}),
localforage.setItem("lastUpdate", 0),
+ localforage.setItem("urnikTheme", "privzeta"),
localforage.setItem("triggerWarningAccepted", false)
];
diff --git a/assets/js/timetable.js b/assets/js/timetable.js
index 85c555a..f4fa01d 100644
--- a/assets/js/timetable.js
+++ b/assets/js/timetable.js
@@ -42,21 +42,6 @@ function hashCode(str) { // java String#hashCode
return hash;
}
-/**
- *
- * Convert last 3 bytes of an integer to RGB color
- * @param {integer} input_integer Integer that will be converted to RGB color
- * @returns {string} Hex color code
- *
- */
-function intToRGB(i) {
- var c = (i & 0x00FFFFFF)
- .toString(16)
- .toUpperCase();
-
- return "00000".substring(0, 6 - c.length) + c;
-}
-
// http://www.w3.org/TR/AERT#color-contrast
/**
*
@@ -78,16 +63,6 @@ function getForegroundFromBackground(background_color) {
return "#ffffff";
}
}
-
-/**
- *
- * Convert a given string to hex color
- * @param {string} input_string Input string
- * @returns {string} Hex RGB color
- */
-function getHexColorFromString(str) {
- return "#" + intToRGB(hashCode(str));
-}
// --------------------------------------------------
// ---------DATE FUNCTION-------------
@@ -214,6 +189,7 @@ function displayTimetable(weekly_timetable, date_object) {
class: lesson["class"],
teacher: lesson["teacher"],
classroom: lesson["place"],
+ substitution: lesson["substitution"],
start: lesson_times[0].substring(0, 5),
end: lesson_times[1].substring(0, 5)
}
@@ -224,9 +200,10 @@ function displayTimetable(weekly_timetable, date_object) {
start: date_string + " " + lesson_times[0],
end: date_string + " " + lesson_times[1],
backgroundColor: bg_color,
- textColor: fg_color
+ textColor: fg_color,
};
-
+ if (lesson["substitution"])
+ lesson_object.borderColor = "red";
transformed_timetable.push(lesson_object);
});
@@ -246,7 +223,7 @@ function eventClickHandler(eventClickInfo) {
let lesson_class = lesson_metadata["class"];
let lesson_duration = lesson_metadata["start"] + " - " + lesson_metadata["end"];
- $("#lesson-subject").text(lesson_subject);
+ $("#lesson-subject").text(lesson_subject + (lesson_metadata["substitution"] ? (" (" + s("substitution") + ")") : ""));
$("#lesson-teacher").text(lesson_teacher);
$("#lesson-class").text(lesson_class);
$("#lesson-classroom").text(lesson_classroom);
@@ -256,10 +233,13 @@ function eventClickHandler(eventClickInfo) {
M.Sidenav.getInstance(modal).open();
}
+var urnikTheme = "privzeta";
-document.addEventListener("DOMContentLoaded", () => {
+document.addEventListener("DOMContentLoaded", async function() {
+ urnikTheme = await localforage.getItem("urnikTheme");
+ if (urnikTheme == null || urnikTheme == undefined || urnikTheme == false)
+ urnikTheme = "privzeta";
checkLogin();
-
let calendarEl = document.getElementById("calendar");
calendar_obj = new FullCalendar.Calendar(calendarEl, {
plugins: ["timeGrid"],
diff --git a/assets/pages-src/changelog.bvr b/assets/pages-src/changelog.bvr
index e112765..5593c59 100644
--- a/assets/pages-src/changelog.bvr
+++ b/assets/pages-src/changelog.bvr
@@ -54,6 +54,23 @@
<ul class="collapsible">
<li>
+ <div class="collapsible-header">Version 1.0.17-beta</div>
+ <div class="collapsible-body">
+ <ul class="collection">
+ <li
+ class="collection-item">Added
+ substitutions</li>
+ <li
+ class="collection-item">Added
+ urnik
+ theme
+ selection
+ (Thanks to
+ a dijak from
+ Vegova's G2B)</li>
+ </ul>
+ </div>
+
<div class="collapsible-header">Version 1.0.16-beta</div>
<div class="collapsible-body">
<ul class="collection">
diff --git a/assets/pages-src/gradings.bvr b/assets/pages-src/gradings.bvr
index 9a18dae..0c12dd0 100644
--- a/assets/pages-src/gradings.bvr
+++ b/assets/pages-src/gradings.bvr
@@ -26,6 +26,7 @@
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<script type="text/javascript" src="/js/gsec.js"></script> <!-- gimsisextclient -->
+ <script src=/js/colors.js></script>
<script type="text/javascript" src="/js/gradings.js"></script>
<link rel="manifest" href="/manifest.json">
@@ -87,4 +88,4 @@
</body>
- </html> \ No newline at end of file
+ </html>
diff --git a/assets/pages-src/settings.bvr b/assets/pages-src/settings.bvr
index e3ebb9c..a364f40 100644
--- a/assets/pages-src/settings.bvr
+++ b/assets/pages-src/settings.bvr
@@ -83,6 +83,19 @@
</div>
</div>
+ <div class="row">
+ <div class="col s12">
+ <h5 class="general-text"><x-su>urnikTheme</x-su></h5>
+ </div>
+ <div class="input-field col s12">
+ <i class="material-icons prefix">palette</i>
+ <select class="urniktheme-select input-select" id="select-urniktheme">
+ <option value="privzeta" id="option-privzeta" data-urniktheme="privzeta" selected>GimB</option>
+ <option value="poletna" id="option-poletna" data-urniktheme="poletna">Summer / poletna</option>
+ </select>
+ <label><x-su>selectTheme</x-su></label>
+ </div>
+ </div>
<div class="row">
<div class="col s12">
diff --git a/assets/pages-src/timetable.bvr b/assets/pages-src/timetable.bvr
index 171a595..47457c0 100644
--- a/assets/pages-src/timetable.bvr
+++ b/assets/pages-src/timetable.bvr
@@ -27,6 +27,7 @@
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<script type="text/javascript" src="/js/gsec.js"></script> <!-- gimsisextclient -->
+ <script src=/js/colors.js></script> <!-- colors by šiška -->
<script type="text/javascript" src="/js/timetable.js"></script>
<link rel="manifest" href="/manifest.json">
diff --git a/dist/cache_name.txt b/dist/cache_name.txt
index 5466678..2cc6cc9 100755
--- a/dist/cache_name.txt
+++ b/dist/cache_name.txt
@@ -3,4 +3,4 @@
-///site-static-1.0.16.4-beta-80550d8|||
+///site-static-1.0.17.0-beta-93d4479|||
diff --git a/dist/js/app.js b/dist/js/app.js
index 623213f..c50b72d 100755
--- a/dist/js/app.js
+++ b/dist/js/app.js
@@ -4,8 +4,8 @@
// @begin=js@
-const app_version = "1.0.16.4-beta";
-const previous_commit = "80550d8cad189982bf607549b6b5d3977602b91b";
+const app_version = "1.0.17.0-beta";
+const previous_commit = "93d44790e9175f898c2f50b5bfe8e1d3a197ee53";
const BEZIAPP_UPDATE_INTERVAL = 300; // update vsakih 300 sekund
if (location.protocol !== 'https:') {
diff --git a/dist/js/colors.js b/dist/js/colors.js
new file mode 100755
index 0000000..057b0c9
--- /dev/null
+++ b/dist/js/colors.js
@@ -0,0 +1,10 @@
+
+function linMap(c,mn,mx){return c*(mx-mn)+mn;}
+function getDecimal(n){return(n-Math.floor(n));}
+function mapColorPalete(c,palete){let poz=c*(palete.length-1);let col1=palete[Math.floor(poz)];let col2=palete[Math.ceil(poz)];return(Math.floor(linMap(getDecimal(poz),col1[0],col2[0])).toString(16).padStart(2,0)+
+Math.floor(linMap(getDecimal(poz),col1[1],col2[1])).toString(16).padStart(2,0)+
+Math.floor(linMap(getDecimal(poz),col1[2],col2[2])).toString(16).padStart(2,0)).toUpperCase();}
+function intToRGB(i,palete=null){if(palete==null){var c=(i&0x00FFFFFF).toString(16).toUpperCase();return"00000".substring(0,6-c.length)+c;}else return mapColorPalete((i&0xFF)/0xFF,palete);}
+function getHexColorFromString(str){if(urnikTheme=="privzeta")
+return"#"+intToRGB(hashCode(str));else
+return"#"+intToRGB(hashCode(str),[[38,70,83],[42,157,143],[233,196,106],[244,162,97],[231,111,81]]);} \ No newline at end of file
diff --git a/dist/js/gradings.js b/dist/js/gradings.js
index 713ea20..1e21acd 100755
--- a/dist/js/gradings.js
+++ b/dist/js/gradings.js
@@ -3,9 +3,7 @@ var calendar_obj=null;var gradings;async function checkLogin(){localforage.getIt
function setLoading(state){if(state){$("#loading-bar").removeClass("hidden");}else{$("#loading-bar").addClass("hidden");}}
function hashCode(str){var hash=0;for(var i=0;i<str.length;i++){hash=str.charCodeAt(i)+((hash<<5)-hash);}
return hash;}
-function intToRGB(i){var c=(i&0x00FFFFFF).toString(16).toUpperCase();return"00000".substring(0,6-c.length)+c;}
function getForegroundFromBackground(background_color){let color_hex=background_color.replace("#","");let rgb=[parseInt(color_hex.substring(0,2),16),parseInt(color_hex.substring(2,4),16),parseInt(color_hex.substring(4,6),16)];let o=Math.round(((parseInt(rgb[0])*299)+(parseInt(rgb[1])*587)+(parseInt(rgb[2])*114))/1000);if(o>180){return"#000000";}else{return"#ffffff";}}
-function getHexColorFromString(str){return"#"+intToRGB(hashCode(str));}
function getDateString(){let date=new Date();let year_str=date.getFullYear();let month_str=date.getMonth()+1
month_str=month_str.toString().padStart(2,"0");let day_str=date.getDate();day_str=day_str.toString().padStart(2,"0");let date_string=year_str+"-"+month_str+"-"+day_str;return date_string;}
async function loadGradings(force_refresh=false){setLoading(true);let promises_to_run=[localforage.getItem("username").then((value)=>{username=value;}),localforage.getItem("password").then((value)=>{password=value;}),localforage.getItem("gradings").then((value)=>{gradings=value;})];await Promise.all(promises_to_run);if(gradings==null||gradings==[]||gradings==-1||force_refresh){try{let gsecInstance=new gsec();await gsecInstance.login(username,password);gsecInstance.fetchGradings().then((value)=>{gradings=value;localforage.setItem("gradings",value).then(()=>{displayData();setLoading(false);});setLoading(false);}).catch((err)=>{gsecErrorHandlerUI(err);setLoading(false);});}catch(err){gsecErrorHandlerUI(err);setLoading(false);}}else{displayData();setLoading(false);}}
@@ -14,4 +12,5 @@ async function validateInputs(){if($("#input-grading-name").val()!=null&&$("#inp
function gradingClickHandler(eventClickInfo){let grading_id=parseInt(eventClickInfo.event.id);let grading_subject=gradings[grading_id]["subject"];let grading_date_obj=gradings[grading_id]["date"];let grading_date=dateString.longFormatted(grading_date_obj);let grading_description=gradings[grading_id]["description"];$("#grading-subject").text(grading_subject);$("#grading-date").text(grading_date);$("#grading-description").text(grading_description);const modal=document.querySelectorAll(".side-modal")[0];M.Sidenav.getInstance(modal).open();}
function setupPickers(){var date_object=new Date();let elems=document.querySelectorAll('#datepicker-add');let options={autoClose:true,format:"dd.mm.yyyy",defaultDate:date_object,setDefaultDate:true,firstDay:1}
instances=M.Datepicker.init(elems,options);}
-document.addEventListener("DOMContentLoaded",()=>{checkLogin();var calendarEl=document.getElementById("calendar");calendar_obj=new FullCalendar.Calendar(calendarEl,{firstDay:1,plugins:["dayGrid"],defaultDate:getDateString(),navLinks:false,editable:false,events:[],eventClick:gradingClickHandler,height:"parent"});calendar_obj.render();loadGradings(true);$("#refresh-icon").click(()=>{loadGradings(true);});const menus=document.querySelectorAll(".side-menu");M.Sidenav.init(menus,{edge:"right",draggable:true});const modals=document.querySelectorAll('.side-modal');M.Sidenav.init(modals,{edge:'left',draggable:false});}); \ No newline at end of file
+var urnikTheme="privzeta";document.addEventListener("DOMContentLoaded",async function(){urnikTheme=await localforage.getItem("urnikTheme");if(urnikTheme==null||urnikTheme==undefined||urnikTheme==false)
+urnikTheme="privzeta";checkLogin();var calendarEl=document.getElementById("calendar");calendar_obj=new FullCalendar.Calendar(calendarEl,{firstDay:1,plugins:["dayGrid"],defaultDate:getDateString(),navLinks:false,editable:false,events:[],eventClick:gradingClickHandler,height:"parent"});calendar_obj.render();loadGradings(true);$("#refresh-icon").click(()=>{loadGradings(true);});const menus=document.querySelectorAll(".side-menu");M.Sidenav.init(menus,{edge:"right",draggable:true});const modals=document.querySelectorAll('.side-modal');M.Sidenav.init(modals,{edge:'left',draggable:false});}); \ No newline at end of file
diff --git a/dist/js/gsec.js b/dist/js/gsec.js
index be98853..ab60875 100755
--- a/dist/js/gsec.js
+++ b/dist/js/gsec.js
@@ -15,7 +15,7 @@ login(usernameToLogin,passwordToLogin){return new Promise((resolve,reject)=>{var
fetchSessionData(){return new Promise((resolve,reject)=>{$.ajax({xhrFields:{withCredentials:true},crossDomain:true,url:GSE_URL+"WS_Gim/wsGimSisUtils.asmx/GetSessionData",type:"POST",dataType:"json",cache:false,contentType:"application/json",data:"{}",processData:false,success:(data,textStatus,xhr)=>{var podatki={};podatki[0]=data.d.split(", ")[0];podatki[1]=data.d.split(", ")[1];podatki["username"]=data.d.split(", ")[1];podatki[2]=data.d.split(", ")[2];podatki[3]=data.d.split(", ")[3];podatki["sessionCookie"]=data.d.split(", ")[3];podatki[4]=data.d.split(", ")[4];resolve({"data":podatki,"textStatus":textStatus,"code":xhr.status});},error:()=>{reject(new Error(false));}});});}
fetchTeachersDirectory(){return new Promise((resolve,reject)=>{var currentDate=new Date();var letnica=currentDate.getFullYear();if(currentDate.getMonth()<7){letnica--;}
$.ajax({xhrFields:{withCredentials:true},crossDomain:true,url:GSE_URL+"Page_Gim/Uporabnik/modSporociloPrejemniki.aspx/NajdiOsebePrejemniki",type:"POST",dataType:"json",contentType:"application/json",cache:false,data:JSON.stringify({"aIdOsebeRe":"","aIdSolskoLeto":Number(letnica).toString(),"aMsgType":"null","aIdType":"null","aIdUcitelj":"","aFilter":null}),processData:false,success:(data)=>{var teachersDirectory=data.d.split(";");teachersDirectory.pop();var formatted={};teachersDirectory.forEach((v)=>{formatted[v.split("=")[1].split(" (")[0]]=v.split("=")[0];});resolve(formatted);},error:()=>{reject(new Error(false));}});});}
-fetchTimetable(datum=null){const SUBJECT_REGEX=/\((.+?)\)/;const ABKURZUNG_REGEX=/^(.+?) \(/;var dataToSend=datum==null?{}:{"ctl00$ContentPlaceHolder1$wkgDnevnik_edtGridSelectDate":`${datum.getDate()}.${Number(datum.getMonth()+1)}.${datum.getFullYear()}`};return new Promise((resolve)=>{var urnik={0:{},1:{},2:{},3:{},4:{},5:{},6:{}};this.postback(GSE_URL+"Page_Gim/Ucenec/DnevnikUcenec.aspx",dataToSend,null,true).then((response)=>{let parser=new DOMParser();let parsed=parser.parseFromString(response.data,"text/html");for(const urnikElement of parsed.querySelectorAll('*[id^="ctl00_ContentPlaceHolder1_wkgDnevnik_btnCell_"]')){var subFields=urnikElement.id.split("_");var period=subFields[4];var day=subFields[5];var desc=$(urnikElement).attr("title").split("\n");var subject=SUBJECT_REGEX.exec(desc[1])[1];var abkurzung=ABKURZUNG_REGEX.exec(desc[1])[1];var razred=desc[2];var teacher=desc[3];var place=desc[4];urnik[day][period]={"subject":subject,"acronym":abkurzung,"class":razred,"teacher":teacher,"place":place};}
+fetchTimetable(datum=null){const SUBJECT_REGEX=/\((.+?)\)/;const ABKURZUNG_REGEX=/^(.+?) \(/;var dataToSend=datum==null?{}:{"ctl00$ContentPlaceHolder1$wkgDnevnik_edtGridSelectDate":`${datum.getDate()}.${Number(datum.getMonth()+1)}.${datum.getFullYear()}`};return new Promise((resolve)=>{var urnik={0:{},1:{},2:{},3:{},4:{},5:{},6:{}};this.postback(GSE_URL+"Page_Gim/Ucenec/DnevnikUcenec.aspx",dataToSend,null,true).then((response)=>{let parser=new DOMParser();let parsed=parser.parseFromString(response.data,"text/html");for(const urnikElement of parsed.querySelectorAll('*[id^="ctl00_ContentPlaceHolder1_wkgDnevnik_btnCell_"]')){var subFields=urnikElement.id.split("_");var period=subFields[4];var day=subFields[5];var desc=$(urnikElement).attr("title").split("\n");var subject=SUBJECT_REGEX.exec(desc[1])[1];var abkurzung=ABKURZUNG_REGEX.exec(desc[1])[1];var razred=desc[2];var teacher=desc[3];var place=desc[4];var nadomescanje=urnikElement.parentElement.classList.contains("flagS");urnik[day][period]={"subject":subject,"acronym":abkurzung,"class":razred,"teacher":teacher,"place":place,"substitution":nadomescanje};}
resolve(urnik);});});}
fetchGradings(){const DESC_REGEX=/\((.+?)\)/m;const SUBJECT_REGEX=/^(.+?) \(/m;return new Promise((resolve)=>{var gradings=[];this.postback(GSE_URL+"Page_Gim/Ucenec/IzpitiUcenec.aspx",{},null,true).then((response)=>{let parser=new DOMParser();let parsed=parser.parseFromString(response.data,"text/html");var rowElements=parsed.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0].getElementsByTagName("tr");for(const row of rowElements){var subFields=row.getElementsByTagName("td");var date=subFields[0].innerHTML.trim().split(".");var dateObj=new Date(date[2]+"-"+date[1]+"-"+date[0]);var rowSpan=subFields[1].getElementsByTagName("span")[0];var abkurzung="";if(rowSpan){abkurzung=rowSpan.innerHTML.trim();}
rowSpan.remove();var subject=SUBJECT_REGEX.exec(subFields[1].innerHTML);if(subject==null){continue;}
diff --git a/dist/js/lang/bundle.js b/dist/js/lang/bundle.js
index 41567f3..6b99566 100755
--- a/dist/js/lang/bundle.js
+++ b/dist/js/lang/bundle.js
@@ -163,6 +163,7 @@ var langstrings = {
settings: "settings",
// timetable
noPeriods: "no periods in selected week",
+ substitution: "substitution",
// gradings
date: "date",
description: "description",
@@ -248,7 +249,7 @@ var langstrings = {
mealsUsageNote: "click on a date to open the collapsible menu with choices and click on a specific meal to select it. Reload the meals when you're done and check the entries.",
lunchesNote: "app was not tested with lunches in mind. Meals probably won't work with lunches and having a lunch subscription may even break its functionality.",
mealNotShownNote: "editable meals are highlighted in gold, read-only meals are highlighted in grey and cannot be changed. Meals that provide no options for menus are not shown for clarity, same applies for days where there are no meals",
- mealsContributeNote: "you are welcome to contribute to the LopolisAPI project and add features, such as checkouts.",
+ mealsContributeNote: "you are welcome to contribute to the BežiApp project.",
authenticationError: "authentication error",
lopolisAPIConnectionError: "LopolisAPI server connection error",
errorGettingMenus: "error getting menus",
@@ -319,6 +320,7 @@ var langstrings = {
on: "on",
off: "off",
selectErrorReporting: "should error reports be submitted to the developers?",
+ urnikTheme: "timetable theme",
// gsec
gsecErrNet: "GimSIS connection error",
gsecErrLogin: "GimSIS login error (bad password?), try logging out",
@@ -365,6 +367,7 @@ var langstrings = {
browserNotSupported: "BežiApp ne bo deloval na vaši napravi, če ne posodobite vašega Internetnega brskalnika",
// timetable
noPeriods: "ni ur v izbranem tednu",
+ substitution: "nadomeščanje",
// index
timetable: "urnik",
gradings: "ocenjevanja",
@@ -461,7 +464,7 @@ var langstrings = {
mealsUsageNote: "kliknite na datum za prikaz menijev, nato pa si enega izberite s klikom na ime menija. Po nastavitvi menijev ponovno naložite menije in se prepričajte o pravilnih nastavitvah.",
lunchesNote: "aplikacija ni testirana za naročanje na kosila, zato verjetno to ne deluje. Če ste naročeni na kosila lahko naročanje na menije sploh ne deluje ali pa deluje narobe.",
mealNotShownNote: "obroki, označeni z zlato so nastavljivi, tisti, označeni s sivo, niso, če pa pri kakšnem dnevu obroka ni, pa pomeni, da ga ni moč nastaviti ali pa da ne obrok ne obstaja",
- mealsContributeNote: "vabimo vas k urejanju LopolisAPI programa za upravljanje z meniji.",
+ mealsContributeNote: "vabimo vas k urejanju BežiApp programa.",
authenticationError: "napaka avtentikacije",
lopolisAPIConnectionError: "napaka povezave na LopolisAPI strežnik",
errorGettingMenus: "napaka branja menijev",
@@ -521,7 +524,7 @@ var langstrings = {
themeLight: "svetel izgled (privzeto)",
themeDark: "temen izgled",
themeNight: "nočni izgled",
- themeSet: "izgled nastavljen, odprite neko drugo stran da se spremembe uveljavijo",
+ themeSet: "izgled nastavljen, odprite neko drugo stran, da se spremembe uveljavijo",
selectTheme: "izberite željen izgled",
errorReportingSet: "nastavitev pošiljanja napak izbrana",
errorReporting: "pošiljanje napak",
@@ -532,6 +535,7 @@ var langstrings = {
triggerAgreement: "strinjam se z zgoraj navedenimi pogoji",
triggerWarningSet: "spremenili ste stanje dodatnih nastavitev",
additionalOptions: "dodatne nastavitve",
+ urnikTheme: "izgled urnika",
// gsec
gsecErrNet: "napaka povezave na GimSIS",
gsecErrLogin: "prijava v GimSIS ni uspela (napačno geslo?), poskusite se odjaviti",
diff --git a/dist/js/settings.js b/dist/js/settings.js
index 9e52861..f6cfbe2 100755
--- a/dist/js/settings.js
+++ b/dist/js/settings.js
@@ -1,12 +1,14 @@
async function setLanguage(langCode){localforage.setItem("chosenLang",langCode).then((value)=>{console.log("Language set: "+value);UIAlert(D("languageSet"),"setLanguage(): languageSet");});}
async function setTheme(targetTheme){localforage.setItem("theme",targetTheme).then((value)=>{console.log("Theme set: "+value);UIAlert(D("themeSet"),"setTheme(): themeSet");});}
+async function setUrnikTheme(targetTheme){localforage.setItem("urnikTheme",targetTheme).then((value)=>{console.log("Urnik theme set"+value);UIAlert(D("themeSet"),"setUrnikTheme(): themeSet")});}
async function setErrorReporting(targetE){localforage.setItem("errorReporting",targetE).then((value)=>{console.log("ErrorReporing set: "+value);UIAlert(D("errorReportingSet"),"setErrorReporting(): errorReportingSet");});}
function shuffleArray(array){for(var i=array.length-1;i>0;i--){var j=Math.floor(Math.random()*(i+1));var temp=array[i];array[i]=array[j];array[j]=temp;}}
function setUIAdditionalOptions(state){var SENSITIVE_THEMES={"left":"Left / leva","right":"Right / desna","piratska":"Pirate / piratska"};if(state===true){var theme_keys=Object.keys(SENSITIVE_THEMES);shuffleArray(theme_keys);theme_keys.forEach((item)=>{var option_element=$(`<option value="${item}" id="option-${item}" data-theme="${item}">${SENSITIVE_THEMES[item]}</option>`);$("#select-theme").append(option_element);});}else{Object.keys(SENSITIVE_THEMES).forEach((item)=>{$("#option-"+item).remove();});}
var elems=document.querySelectorAll('#select-theme');M.FormSelect.init(elems,{});}
async function setAdditionalOptions(state){localforage.setItem("triggerWarningAccepted",state).then((value)=>{console.log("TriggerWarning set: "+value);UIAlert(D("triggerWarningSet"),"setAdditionalOptions(): triggerWarningSet");setUIAdditionalOptions(value);});}
-document.addEventListener("DOMContentLoaded",async()=>{$("#triggered-checkbox").change(function(){if(this.checked){setAdditionalOptions(true);}else{setAdditionalOptions(false);}});$("#select-language").on("change",function(){setLanguage($(this).find(":selected").val());});$("#select-theme").on("change",function(){setTheme($(this).find(":selected").val());});$("#select-errorreporting").on("change",function(){setErrorReporting($(this).find(":selected").val());});localforage.getItem("chosenLang").then((value)=>{let selectedLanguage=value;if(value==null||value.length<1){selectedLanguage="sl";}
-$(`#option-${selectedLanguage}`).attr("selected",true);}).catch(()=>{});localforage.getItem("theme").then((value)=>{let selectedTheme=value;if(value==null||value.length<1){selectedTheme="themeLight";}
+document.addEventListener("DOMContentLoaded",async()=>{$("#triggered-checkbox").change(function(){if(this.checked){setAdditionalOptions(true);}else{setAdditionalOptions(false);}});$("#select-language").on("change",function(){setLanguage($(this).find(":selected").val());});$("#select-theme").on("change",function(){setTheme($(this).find(":selected").val());});$("#select-errorreporting").on("change",function(){setErrorReporting($(this).find(":selected").val());});$("#select-urniktheme").on("change",function(){setUrnikTheme($(this).find(":selected").val());});localforage.getItem("chosenLang").then((value)=>{let selectedLanguage=value;if(value==null||value.length<1){selectedLanguage="sl";}
+$(`#option-${selectedLanguage}`).attr("selected",true);}).catch(()=>{});localforage.getItem("urnikTheme").then((value)=>{if(value==null||value.length<1){value="privzeta";}
+$(`#option-${value}`).attr("selected",true);}).catch(()=>{});localforage.getItem("theme").then((value)=>{let selectedTheme=value;if(value==null||value.length<1){selectedTheme="themeLight";}
$(`#option-${selectedTheme}`).attr("selected",true);}).catch(()=>{});localforage.getItem("errorReporting").then((value)=>{let selectedE=value;if(value==null||value.length<1){selectedE="on";}
-$(`#option-${selectedE}`).attr("selected",true);}).catch(()=>{});localforage.getItem("triggerWarningAccepted").then((value)=>{if(value===true){$("#triggered-checkbox").attr("checked",true);setUIAdditionalOptions(true);}}).catch(()=>{});const menus=document.querySelectorAll(".side-menu");M.Sidenav.init(menus,{edge:"right",draggable:true});var elems=document.querySelectorAll(".theme-select");M.FormSelect.init(elems,{});var elems=document.querySelectorAll(".errorreporting-select");M.FormSelect.init(elems,{});var elems=document.querySelectorAll(".lang-select");M.FormSelect.init(elems,{});}); \ No newline at end of file
+$(`#option-${selectedE}`).attr("selected",true);}).catch(()=>{});localforage.getItem("triggerWarningAccepted").then((value)=>{if(value===true){$("#triggered-checkbox").attr("checked",true);setUIAdditionalOptions(true);}}).catch(()=>{});const menus=document.querySelectorAll(".side-menu");M.Sidenav.init(menus,{edge:"right",draggable:true});var elems=document.querySelectorAll(".theme-select");M.FormSelect.init(elems,{});var elems=document.querySelectorAll(".errorreporting-select");M.FormSelect.init(elems,{});var elems=document.querySelectorAll(".urniktheme-select");M.FormSelect.init(elems,{});var elems=document.querySelectorAll(".lang-select");M.FormSelect.init(elems,{});}); \ No newline at end of file
diff --git a/dist/js/setup-storage.js b/dist/js/setup-storage.js
index 74b2909..635253f 100755
--- a/dist/js/setup-storage.js
+++ b/dist/js/setup-storage.js
@@ -25,6 +25,7 @@ async function setupStorage(force = false) {
localforage.setItem("directory", {}), //\\ well I could remember my own code but I didn't.
localforage.setItem("meals", {}),
localforage.setItem("lastUpdate", 0),
+ localforage.setItem("urnikTheme", "privzeta"),
localforage.setItem("triggerWarningAccepted", false)
];
diff --git a/dist/js/timetable.js b/dist/js/timetable.js
index aa73a9a..d74a32f 100755
--- a/dist/js/timetable.js
+++ b/dist/js/timetable.js
@@ -3,9 +3,7 @@ var calendar_obj=null;function checkLogin(){localforage.getItem("logged_in").the
function setLoading(state){if(state){$("#loading-bar").removeClass("hidden");}else{$("#loading-bar").addClass("hidden");}}
function hashCode(str){var hash=0;for(var i=0;i<str.length;i++){hash=str.charCodeAt(i)+((hash<<5)-hash);}
return hash;}
-function intToRGB(i){var c=(i&0x00FFFFFF).toString(16).toUpperCase();return"00000".substring(0,6-c.length)+c;}
function getForegroundFromBackground(background_color){let color_hex=background_color.replace("#","");let rgb=[parseInt(color_hex.substring(0,2),16),parseInt(color_hex.substring(2,4),16),parseInt(color_hex.substring(4,6),16)];let o=Math.round(((parseInt(rgb[0])*299)+(parseInt(rgb[1])*587)+(parseInt(rgb[2])*114))/1000);if(o>180){return"#000000";}else{return"#ffffff";}}
-function getHexColorFromString(str){return"#"+intToRGB(hashCode(str));}
function getDateString(date){let year_str=date.getFullYear();let month_str=date.getMonth()+1
month_str=month_str.toString().padStart(2,"0");let day_str=date.getDate();day_str=day_str.toString().padStart(2,"0");let date_string=year_str+"-"+month_str+"-"+day_str;return date_string;}
function getLastMonday(date_object){if(date_object.getDay()===0){date_object.setDate(date_object.getDate()-6);}else{date_object.setDate(date_object.getDate()-date_object.getDay()+1);}
@@ -14,8 +12,10 @@ async function loadTimetable(date_object,force_refresh=false){setLoading(true);v
if(!containsPeriods){UIAlert(D("noPeriods"));setLoading(false);}else{if(timetable===null){timetable={};}
timetable[date_string]=value;localforage.setItem("timetable",timetable).then(()=>{displayTimetable(value,date_monday);setLoading(false);});}}).catch((err)=>{gsecErrorHandlerUI(err);setLoading(false);});}catch(err){gsecErrorHandlerUI(err);setLoading(false);}}else{displayTimetable(timetable[date_string],date_monday);setLoading(false);}}
function getLessonTimes(lesson_number){const lessonTimes=[["07:10:00","07:55:00"],["08:00:00","08:45:00"],["08:50:00","09:35:00"],["09:40:00","10:25:00"],["10:55:00","11:40:00"],["11:45:00","12:30:00"],["12:35:00","13:20:00"],["13:25:00","14:10:00"],["14:15:00","15:00:00"],["15:05:00","15:50:00"],["15:55:00","16:40:00"],["16:45:00","17:30:00"],["17:35:00","18:20:00"],["18:25:00","19:10:00"]];return lessonTimes[lesson_number];}
-function displayTimetable(weekly_timetable,date_object){let transformed_timetable=[];let num_days=Object.keys(weekly_timetable).length;for(let i=0;i<num_days;i++){let date_string=getDateString(date_object);date_object.setDate(date_object.getDate()+1);let daily_timetable=weekly_timetable[i.toString()];Object.keys(daily_timetable).forEach((lesson_number)=>{let lesson=daily_timetable[lesson_number];let lesson_times=getLessonTimes(parseInt(lesson_number));let bg_color=getHexColorFromString(lesson["acronym"]);let fg_color=getForegroundFromBackground(bg_color);let lesson_metadata={subject:lesson["subject"],class:lesson["class"],teacher:lesson["teacher"],classroom:lesson["place"],start:lesson_times[0].substring(0,5),end:lesson_times[1].substring(0,5)}
-let lesson_object={id:JSON.stringify(lesson_metadata),title:lesson["acronym"],start:date_string+" "+lesson_times[0],end:date_string+" "+lesson_times[1],backgroundColor:bg_color,textColor:fg_color};transformed_timetable.push(lesson_object);});}
+function displayTimetable(weekly_timetable,date_object){let transformed_timetable=[];let num_days=Object.keys(weekly_timetable).length;for(let i=0;i<num_days;i++){let date_string=getDateString(date_object);date_object.setDate(date_object.getDate()+1);let daily_timetable=weekly_timetable[i.toString()];Object.keys(daily_timetable).forEach((lesson_number)=>{let lesson=daily_timetable[lesson_number];let lesson_times=getLessonTimes(parseInt(lesson_number));let bg_color=getHexColorFromString(lesson["acronym"]);let fg_color=getForegroundFromBackground(bg_color);let lesson_metadata={subject:lesson["subject"],class:lesson["class"],teacher:lesson["teacher"],classroom:lesson["place"],substitution:lesson["substitution"],start:lesson_times[0].substring(0,5),end:lesson_times[1].substring(0,5)}
+let lesson_object={id:JSON.stringify(lesson_metadata),title:lesson["acronym"],start:date_string+" "+lesson_times[0],end:date_string+" "+lesson_times[1],backgroundColor:bg_color,textColor:fg_color,};if(lesson["substitution"])
+lesson_object.borderColor="red";transformed_timetable.push(lesson_object);});}
calendar_obj.removeAllEvents();calendar_obj.addEventSource(transformed_timetable);}
-function eventClickHandler(eventClickInfo){let lesson_metadata=JSON.parse(eventClickInfo.event.id);let lesson_subject=lesson_metadata["subject"];let lesson_teacher=lesson_metadata["teacher"];let lesson_classroom=lesson_metadata["classroom"];let lesson_class=lesson_metadata["class"];let lesson_duration=lesson_metadata["start"]+" - "+lesson_metadata["end"];$("#lesson-subject").text(lesson_subject);$("#lesson-teacher").text(lesson_teacher);$("#lesson-class").text(lesson_class);$("#lesson-classroom").text(lesson_classroom);$("#lesson-duration").text(lesson_duration);const modal=document.querySelectorAll(".side-modal")[0];M.Sidenav.getInstance(modal).open();}
-document.addEventListener("DOMContentLoaded",()=>{checkLogin();let calendarEl=document.getElementById("calendar");calendar_obj=new FullCalendar.Calendar(calendarEl,{plugins:["timeGrid"],eventClick:eventClickHandler,defaultView:"timeGridWeek",contentHeight:"auto",height:"auto",width:"auto",timeGridEventMinHeight:35,nowIndicator:true,firstDay:1,weekends:false,timeFormat:'H(:mm)',minTime:"07:10:00",maxTime:"19:10:00"});calendar_obj.render();loadTimetable(new Date());$(".fc-today-button, .fc-prev-button, .fc-next-button").click(()=>{loadTimetable(calendar_obj.getDate());});$("#refresh-icon").click(()=>{loadTimetable(calendar_obj.getDate(),true);});const menus=document.querySelectorAll(".side-menu");M.Sidenav.init(menus,{edge:"right",draggable:true});const modals=document.querySelectorAll('.side-modal');M.Sidenav.init(modals,{edge:'left',draggable:false});}); \ No newline at end of file
+function eventClickHandler(eventClickInfo){let lesson_metadata=JSON.parse(eventClickInfo.event.id);let lesson_subject=lesson_metadata["subject"];let lesson_teacher=lesson_metadata["teacher"];let lesson_classroom=lesson_metadata["classroom"];let lesson_class=lesson_metadata["class"];let lesson_duration=lesson_metadata["start"]+" - "+lesson_metadata["end"];$("#lesson-subject").text(lesson_subject+(lesson_metadata["substitution"]?(" ("+s("substitution")+")"):""));$("#lesson-teacher").text(lesson_teacher);$("#lesson-class").text(lesson_class);$("#lesson-classroom").text(lesson_classroom);$("#lesson-duration").text(lesson_duration);const modal=document.querySelectorAll(".side-modal")[0];M.Sidenav.getInstance(modal).open();}
+var urnikTheme="privzeta";document.addEventListener("DOMContentLoaded",async function(){urnikTheme=await localforage.getItem("urnikTheme");if(urnikTheme==null||urnikTheme==undefined||urnikTheme==false)
+urnikTheme="privzeta";checkLogin();let calendarEl=document.getElementById("calendar");calendar_obj=new FullCalendar.Calendar(calendarEl,{plugins:["timeGrid"],eventClick:eventClickHandler,defaultView:"timeGridWeek",contentHeight:"auto",height:"auto",width:"auto",timeGridEventMinHeight:35,nowIndicator:true,firstDay:1,weekends:false,timeFormat:'H(:mm)',minTime:"07:10:00",maxTime:"19:10:00"});calendar_obj.render();loadTimetable(new Date());$(".fc-today-button, .fc-prev-button, .fc-next-button").click(()=>{loadTimetable(calendar_obj.getDate());});$("#refresh-icon").click(()=>{loadTimetable(calendar_obj.getDate(),true);});const menus=document.querySelectorAll(".side-menu");M.Sidenav.init(menus,{edge:"right",draggable:true});const modals=document.querySelectorAll('.side-modal');M.Sidenav.init(modals,{edge:'left',draggable:false});}); \ No newline at end of file
diff --git a/dist/pages/about.html b/dist/pages/about.html
index 989f5e9..d51a448 100755
--- a/dist/pages/about.html
+++ b/dist/pages/about.html
@@ -79,7 +79,7 @@
<!-- One day in the future we may have sw cache version covered by this as well -->
<h5 class="subheader">
<x-su>version</x-su>
- 1.0.16.4-beta
+ 1.0.17.0-beta
</h5>
</div>
</div>
@@ -163,7 +163,7 @@
<div class="row">
<p>
<small>
- ^HEAD 80550d8cad189982bf607549b6b5d3977602b91b
+ ^HEAD 93d44790e9175f898c2f50b5bfe8e1d3a197ee53
</small>
</p>
</div>
diff --git a/dist/pages/changelog.html b/dist/pages/changelog.html
index 45b8c67..4821a2b 100755
--- a/dist/pages/changelog.html
+++ b/dist/pages/changelog.html
@@ -58,6 +58,23 @@
<ul class="collapsible">
<li>
+ <div class="collapsible-header">Version 1.0.17-beta</div>
+ <div class="collapsible-body">
+ <ul class="collection">
+ <li
+ class="collection-item">Added
+ substitutions</li>
+ <li
+ class="collection-item">Added
+ urnik
+ theme
+ selection
+ (Thanks to
+ a dijak from
+ Vegova's G2B)</li>
+ </ul>
+ </div>
+
<div class="collapsible-header">Version 1.0.16-beta</div>
<div class="collapsible-body">
<ul class="collection">
diff --git a/dist/pages/gradings.html b/dist/pages/gradings.html
index 86b047d..12a4091 100755
--- a/dist/pages/gradings.html
+++ b/dist/pages/gradings.html
@@ -30,6 +30,7 @@
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<script type="text/javascript" src="/js/gsec.js"></script> <!-- gimsisextclient -->
+ <script src=/js/colors.js></script>
<script type="text/javascript" src="/js/gradings.js"></script>
<link rel="manifest" href="/manifest.json">
@@ -146,4 +147,4 @@
</body>
- </html
+ </html>
diff --git a/dist/pages/settings.html b/dist/pages/settings.html
index 2d00d2b..03543b2 100755
--- a/dist/pages/settings.html
+++ b/dist/pages/settings.html
@@ -106,6 +106,19 @@
</div>
</div>
+ <div class="row">
+ <div class="col s12">
+ <h5 class="general-text"><x-su>urnikTheme</x-su></h5>
+ </div>
+ <div class="input-field col s12">
+ <i class="material-icons prefix">palette</i>
+ <select class="urniktheme-select input-select" id="select-urniktheme">
+ <option value="privzeta" id="option-privzeta" data-urniktheme="privzeta" selected>GimB</option>
+ <option value="poletna" id="option-poletna" data-urniktheme="poletna">Summer / poletna</option>
+ </select>
+ <label><x-su>selectTheme</x-su></label>
+ </div>
+ </div>
<div class="row">
<div class="col s12">
diff --git a/dist/pages/timetable.html b/dist/pages/timetable.html
index cbdc971..ffd7577 100755
--- a/dist/pages/timetable.html
+++ b/dist/pages/timetable.html
@@ -31,6 +31,7 @@
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<script type="text/javascript" src="/js/gsec.js"></script> <!-- gimsisextclient -->
+ <script src=/js/colors.js></script> <!-- colors by šiška -->
<script type="text/javascript" src="/js/timetable.js"></script>
<link rel="manifest" href="/manifest.json">
diff --git a/dist/sw.js b/dist/sw.js
index cb0428d..fb2e541 100755
--- a/dist/sw.js
+++ b/dist/sw.js
@@ -5,8 +5,8 @@
// @begin=js@
// Change version to cause cache refresh
-const static_cache_name = "site-static-1.0.16.4-beta-80550d8";
-// commit before the latest is 80550d8cad189982bf607549b6b5d3977602b91b
+const static_cache_name = "site-static-1.0.17.0-beta-93d4479";
+// commit before the latest is 93d44790e9175f898c2f50b5bfe8e1d3a197ee53
// Got them with find . -not -path '*/\.*' | sed "s/.*/\"&\",/" | grep -v sw.js
// sw.js NE SME BITI CACHAN, ker vsebuje verzijo!
diff --git a/global.bvr b/global.bvr
index d4ab6b5..13820ff 100644
--- a/global.bvr
+++ b/global.bvr
@@ -1,4 +1,4 @@
<@?s bvr_include_path assets/pages-src/ assets/pages-src/misc/@>
<@?s latest_commit ?u 0 -1 ?i .git/refs/heads/dev@>
-<@?s app_version 1.0.16.4-beta@>
+<@?s app_version 1.0.17.0-beta@>
<@?s app_default_language sl@>
diff --git a/server/glasovanje/index.php b/server/glasovanje/index.php
new file mode 100644
index 0000000..5286e0c
--- /dev/null
+++ b/server/glasovanje/index.php
@@ -0,0 +1,183 @@
+<?php
+ $login_status = 0;
+ if (empty($_REQUEST['u'] /* username */ || empty($_REQUEST['p'] /* password */ ))) {
+ $login_status = -1;
+ }
+ if ($login_status == 1)
+ switch($_REQUEST['a'] /* action */) {
+ case 'v': /* vpogled */
+ exit();
+ case 'g': /* glasuj */
+ exit();
+ case 'z': /* zavrnjene */
+ exit();
+ case 'p': /* predlagane */
+ }
+?>
+<html lang=sl>
+ <head>
+ <meta charset=UTF-8 />
+ <title>
+ Šolski radio GimB :: glasovanje za skladbe
+ </title>
+ <style>
+ input[type=password], input[type=text], input[type=submit], input[type=button] {
+ width: 100%;
+ height: 2cm;
+ font-size: 21;
+ }
+ .showhide-checkbox { display: none; }
+ .showhide-hiddenelement { display: none; }
+ .showhide-checkbox:checked + .showhide-hiddenelement { display: block; }
+ .showhide-checkbox:checked + .showhide-shownelement { display: none; }
+ a { text-decoration: underline; cursor: pointer; color: blue; }
+ a:visited { color: purple; }
+ a:hover { color: darkblue; }
+ a:active { color: lightblue; }
+ thead {
+ font-weight: bold;
+ }
+ table, td, tr, th, tbody, thead {
+ border: 1px solid black;
+ border-collapse: collapse;
+ }
+ </style>
+ </head>
+ <body>
+ <form method=POST>
+ <h1>
+ Šolski radio na Gimnaziji Bežigrad
+ </h1>
+ <h2>
+ Glasovanje za skladbe
+ </h2>
+ <h3>
+ Oddaja predlogov
+ </h3>
+ <p>
+ Vsi dijaki na Gimnaziji Bežigrad lahko predloge podajate vsebinski ekipi radia po kakršnem koli komunikacijskem kanalu. Seznam članov tehnične in vsebinske ekipe je praviloma objavljen na steni studia, trenutno razporeditev pa, če se spodaj prijavite, lahko vidite tudi tukaj.
+ </p>
+ <?php if ($login_status == 1 || 1 == 1) { ?>
+ <label for=c-c>
+ <h4>
+ <a>
+ Preglej člane ekipe
+ </a>
+ </h4>
+ </label>
+ <input type=checkbox id=c-c class=showhide-checkbox />
+ <div class=showhide-hiddenelement>
+ <ul>
+ <?php foreach ($ekipa as $dijak) { ?>
+ <li title="<?php echo htmlspecialchars($dijak["uporabnisko_ime"]); ?>">
+ <b><?php echo htmlspecialchars($dijak["ime"]); ?><b>, <?php echo htmlspecialchars($dijak["pozicija"]); ?>
+ </li>
+ <?php } ?>
+ </ul>
+ </div>
+ <?php } ?>
+ <p>
+ Predloge se lahko oddaja tudi preko tega spletišča. Radijska ekipa bo videla le vaš predlog, ne pa tudi vašega imena. Le-to se ne shrani v zbirko predlogov. Za oddajo predloga po spletu se morate spodaj prijaviti.
+ </p>
+ <p>
+ Pred oddajo novega predloga preglejte trenutno aktivne predloge za skladbe spodaj in zavrnjene skladbe. Če je vaša izbrana skladba na seznamu zavrnjenih skladb, je ne bomo nikoli potrdili, zaman poskušate še enkrat. Če je vaša izbrana skladba na seznamu trenutno aktivnih predlog za skladbe, je tja ne bomo vpisali še enkrat - počakajte, da jo slišite na radiu, šele nato lahko ponovno oddate predlog.
+ </p>
+ <?php if ($login_status == 1 || 1 == 1) { ?>
+ <label for=z-c>
+ <h4>
+ <a>
+ Preglej zavrnjene skladbe
+ </a>
+ </h4>
+ </label>
+ <input type=checkbox id=z-c class=showhide-checkbox />
+ <div class=showhide-hiddenelement>
+ <ul>
+ <?php foreach ($zavrnjene as $zavrnjena) { ?>
+ <li>
+ <b><?php echo htmlspecialchars($zavrnjena["ime"]); ?></b>, razlog: <?php echo htmlspecialchars($zavrnjena["razlog"]); ?>
+ </li>
+ <? } ?>
+ </ul>
+ </div>
+ <?php } ?>
+ <p>
+ Čas obravnave predlagane skladbe lahko traja tudi več dni, zato ne bodite nestrpni in iste skladbe nikar ne oddajte še enkrat, če je po nekaj dneh od oddaje še ne vidite na katerem izmed seznamov. Vsebinska ekipa radia si prav tako pridržuje pravico do umika skladbe iz trenutno aktivnih predlogov v seznam zavrnjenih skladb z ustrezno utemeljitvijo.
+ </p>
+ <?php if ($login_status == 1 || 1 == 1) { ?>
+ <input type=text name=i placeholder="Ime skladbe, izvajalec, (YouTube povezava, )..." />
+ <input type=submit formaction=?a=a value="Pošlji predlog" />
+ <?php } ?>
+ <h3>
+ Glasovanje za skladbe
+ </h3>
+ <p>
+ Za ohranitev zdrave glasbene kulture o predvajani glasbi odločajo poslušalci radia. Glasovanje poteka preko tega spletišča. Naenkrat lahko glasujete zgolj za eno skladbo. Za glasovanje se morate spodaj prijaviti. Vsebinska ekipa radia si pridržuje pravico do izbiranja glasbe. To pomeni, da si glede na izbran glasbeni žanr dneva izbere pesem, ki bo predvajana, četudi imajo kakšne druge več glasov. Prav tako se lahko odloči za predvajanje skladbe, ki je ni na seznamu.
+ </p>
+ <p>
+ Svoj glas lahko kadarkoli spremenite in ga tudi odstranite. Vaš glas ni več upoštevan, ko se skladba iz seznama aktivnih predlog prestavi bodisi na seznam zavrnjenih skladb bodisi se predvaja po radiu. Zgodovina glasovanja se ne hrani. Vsi z veljavnim uporabniškim imenom GimB lahko glasujejo.
+ </p>
+ <?php if ($login_status == 1 || 1 == 1) { ?>
+ <label for=s-c>
+ <h4>
+ <a>
+ Preglej aktivne predloge skladb in odpri meni za glasovanje
+ </a>
+ </h4>
+ </label>
+ <input type=checkbox id=s-c class=showhide-checkbox />
+ <div class=showhide-hiddenelement>
+ <table>
+ <thead>
+ <th>
+ glasov
+ </th>
+ <th>
+ ime
+ </th>
+ <th>
+ glasuj
+ </th>
+ </thead>
+ <?php foreach ($predlogi as $predlog) { ?>
+ <tr <?php if ($predlog["izbrana"]) echo "style=font-weight:bold"; ?>>
+ <td>
+ <?php echo htmlspecialchars($predlog["glasov"]); ?>
+ </td>
+ <td>
+ <?php echo htmlspecialchars($predlog["ime"]); ?>
+ </th>
+ <td>
+ <input type=submit formaction="?a=g&s=<?php echo htmlspecialchars($predlog["id"]); ?>" value=Glasuj! />
+ </td>
+ </tr>
+ <?php } ?>
+ </ul>
+ </div>
+ <?php } ?>
+ <h3>
+ Prijava
+ </h3>
+ <p>
+ Za uporabo funkcij glasovanja in ogled sodelujočih v ekipi se morate prijaviti.
+ <input type=text name=u placeholder="Uporabniško ime (GimSIS)" value="<?php htmlspecialchars($_REQUEST['u']) ?>" />
+ <input type=password name=p placeholder="Geslo" value="<?php htmlspecialchars($_REQUEST['p']) ?>" />
+ <input type=submit formaction="?" <?php # da ne bo ob loginu uporabljen get parameter ?> value="Prijavi se" />
+ </p>
+ <h3>
+ Povezava z BežiAppom
+ </h3>
+ <p>
+ Vse, kar omogoča ta spletna stran, je mogoče delati tudi v neuradni aplikaciji <a href=https://app.gimb.tk>BežiApp</a> (<a href=https://play.google.com/store/apps/details?id=tk.gimb.app>Odpri v Play Store</a>). Ker se v BežiApp lahko prijavijo zgolj osebe z zGimSIS uporabniškim imenom, ta metoda ni uporabna za profesorje in drugo osebje GimB, saj se le-ti lahko prijavijo zgolj v interni GimSIS.
+ </p>
+ <h3>
+ Predlogi za delovanje radia
+ </h3>
+ <p>
+ Imate pritožbo, idejo ali pripombo glede tega spletišča? Povejte to članu radijske ekipe. Bežigrajski radio je šele v zgodnjem obdobju razvoja, zato so pričakovane korenite spremembe. Če se vam na primer zdi, da javno glasovanje ni pretirano dobra ideja, nam pišite ali pa se kar pridružite v ekipo tehnikov radia.
+ </p>
+ <hr>
+ <i>Strežnik za glasovanje upravlja ekipa </i>gimb-dev<i>. Kontakt: a@gimb.tk</i>
+ </form>
+ </html>
+</html>