diff --git a/foodsharing_planner.user.js b/foodsharing_planner.user.js
index 0b52d2b..f34d39b 100644
--- a/foodsharing_planner.user.js
+++ b/foodsharing_planner.user.js
@@ -1,13 +1,19 @@
// ==UserScript==
// @name Foodsharing Planner
// @namespace http://tampermonkey.net/
-// @version 0.1
-// @updateURL https://github.com/TroogS/userscripts/raw/master/foodsharing_planner.user.js
-// @downloadURL https://github.com/TroogS/userscripts/raw/master/foodsharing_planner.user.js
-// @description Use stackoverflow full width, optional night mode
+// @version 0.2
+// @updateURL https://github.com/TroogS/userscripts/blob/master/foodsharing_planner.user.js
+// @downloadURL https://github.com/TroogS/userscripts/blob/master/foodsharing_planner.user.js
+// @description Generate a calendar like view as addition to the foodsharing website germany, austria and switzerland
// @author A. Beging
// @match https://foodsharing.de*
// @match https://foodsharing.de/*
+// @match https://foodsharing.at*
+// @match https://foodsharing.at/*
+// @match https://foodsharingschweiz.ch*
+// @match https://foodsharingschweiz.ch/*
+// @match https://foodsharing.network*
+// @match https://foodsharing.network/*
// @grant none
// ==/UserScript==
@@ -18,6 +24,9 @@ function GM_addStyle (cssStr) {
}
var token;
+var gPickupData;
+var gLoaded = false;
+var gFirstDayDate;
(function() {
'use strict';
@@ -70,43 +79,84 @@ a.navbar-brand.brand span:nth-child(2) span{
.day .pickup {
border: 1px solid #533a20;
+ border-left-width: 5px;
margin: 5px;
border-radius: 5px;
padding: 5px;
}
-.day .pickup.available {
- border-color: #64ae25;
+.day .pickup.pickup-green {
+ border-left-color: #64ae24;
+}
+
+.day .pickup.pickup-yellow {
+ border-left-color: #ffc107
+}
+
+.day .pickup.pickup-red {
+ border-left-color: #dc3545;
}
.day .pickup .img-container {
display: flex;
}
-.day .pickup .img-container div {
+.day .pickup .img-container > div {
padding-right: 5px;
}
+.day .pickup .img-container > div img {
+ width: 35px;
+ height: 35px;
+ border-radius: 5px;
+}
+
+.day .pickup .img-container .empty-slot {
+ width: 34px;
+ display: flex;
+ height: 34px;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid #533a20;
+ text-decoration: none;
+ margin-right: 5px;
+ border-radius: 5px;
+}
+
+.day .pickup .img-container .empty-slot:hover i {
+ color: #533a20;
+}
+
` );
async function BuildPlannerAsync() {
- var data = await LoadPickupsAsync();
- console.log(data);
-
+ gFirstDayDate = GetFirstDay();
var mainPanel = document.querySelectorAll(".fspl")[0];
- var mon = CreateColumn("1", "Montag");
- var tue = CreateColumn("2", "Tuesday");
- var wed = CreateColumn("3", "Wednesday");
- var thu = CreateColumn("4", "Thursday");
- var fri = CreateColumn("5", "Friday");
- var sat = CreateColumn("6", "Saturday");
- var sun = CreateColumn("7", "Sunday");
+ var mon = CreateColumn(0, "Montag", ' ', null);
+ var tue = CreateColumn(1, "Dienstag");
+ var wed = CreateColumn(2, "Mittwoch");
+ var thu = CreateColumn(3, "Donnerstag");
+ var fri = CreateColumn(4, "Freitag");
+ var sat = CreateColumn(5, "Samstag");
+ var sun = CreateColumn(6, "Sonntag", null, ' ');
- data.sort(function(a, b){return a.pickup.date > b.pickup.date});
- data.forEach(pickup => {
+ mainPanel.append(mon);
+ mainPanel.append(tue);
+ mainPanel.append(wed);
+ mainPanel.append(thu);
+ mainPanel.append(fri);
+ mainPanel.append(sat);
+ mainPanel.append(sun);
- if(pickup.pickup.date > GetFirstDay() && pickup.pickup.date < GetLastDay()) {
+ if(!gLoaded) gPickupData = await LoadPickupsAsync();
+
+ var lastDayDate = GetLastDay(gFirstDayDate);
+
+ gPickupData.sort(function(a, b){return a.pickup.date > b.pickup.date});
+ gPickupData.forEach(pickup => {
+
+ if(pickup.pickup.date > gFirstDayDate && pickup.pickup.date < lastDayDate) {
var pickupDiv = CreatePickupDiv(pickup);
switch (pickup.pickup.date.getDay()) {
@@ -134,50 +184,8 @@ async function BuildPlannerAsync() {
}
}
});
-
- mainPanel.append(mon);
- mainPanel.append(tue);
- mainPanel.append(wed);
- mainPanel.append(thu);
- mainPanel.append(fri);
- mainPanel.append(sat);
- mainPanel.append(sun);
}
-/*function BuildPlanner() {
-
-
-
- console.log(22);
- return;
- console.log(11);
- LoadPickups().then(function(data){
-
-
- console.log(1);
- console.log(data);
- console.log(2);
-
- data.forEach(store => {
- store.pickups.forEach(pickup => {
- var pickupDiv = CreatePickupDiv(store.name, "19");
- mon.append(pickupDiv);
- });
- });
-
- mainPanel.append(mon);
- mainPanel.append(tue);
- mainPanel.append(wed);
- mainPanel.append(thu);
- mainPanel.append(fri);
- mainPanel.append(sat);
- mainPanel.append(sun);
-
- return;
- });
-
-}*/
-
function GetFirstDay() {
var curr = new Date();
var first = curr.getDate() - curr.getDay() + 1;
@@ -187,8 +195,8 @@ function GetFirstDay() {
return firstDay;
}
-function GetLastDay() {
- var curr = new Date();
+function GetLastDay(firstDayDate) {
+ var curr = new Date(firstDayDate);
var last = curr.getDate() - curr.getDay() + 7;
var lastDay = new Date(curr.setDate(last));
lastDay.setHours(23,59,59,999);
@@ -198,7 +206,10 @@ function GetLastDay() {
function CreatePickupDiv(data) {
var elementClass = "pickup";
- if(data.pickup.isAvailable) elementClass += " available";
+ if(data.pickup.occupiedSlots.length == data.pickup.totalSlots) elementClass += " pickup-green";
+ if(data.pickup.occupiedSlots.length < data.pickup.totalSlots && data.pickup.occupiedSlots.length > 0) elementClass += " pickup-yellow";
+ if(data.pickup.occupiedSlots.length == 0) elementClass += " pickup-red";
+
var element = CreateElement("div", elementClass);
var headerSpan = CreateElement("div", "font-weight-bold", data.store.name);
@@ -210,17 +221,34 @@ function CreatePickupDiv(data) {
var timeSpan = CreateElement("div", "", timeString);
element.append(timeSpan);
- if(data.pickup.occupiedSlots.length > 0) {
- var imgContainer = CreateElement("div", "img-container");
- data.pickup.occupiedSlots.forEach(slot => {
- var imgDiv = CreateElement("div");
- imgDiv.innerHTML = '
';
- imgContainer.append(imgDiv);
- });
+ var imgContainer = CreateElement("div", "img-container");
- element.append(imgContainer);
- }
+ // Occupies slots
+ if(data.pickup.occupiedSlots.length > 0) {
+
+ data.pickup.occupiedSlots.forEach(slot => {
+ var imgUrl = 'images/mini_q_' + slot.profile.avatar;
+ if(slot.profile.avatar.startsWith('/api/')) imgUrl = slot.profile.avatar + '?w=35&h=35';
+
+ var imgDiv = CreateElement("div");
+ imgDiv.innerHTML = '
';
+ imgContainer.append(imgDiv);
+ });
+ }
+
+ // Free slots
+ for (let i = 0; i < data.pickup.freeSlots; i++) {
+ var freeSlotA = CreateElement("a", "empty-slot");
+ freeSlotA.setAttribute("href", "https://" + window.location.hostname + "/?page=fsbetrieb&id=" + data.store.id);
+ freeSlotA.setAttribute("target", "_blank");
+
+ freeSlotA.innerHTML = '';
+
+ imgContainer.append(freeSlotA);
+ }
+
+ element.append(imgContainer);
return element;
@@ -228,7 +256,7 @@ function CreatePickupDiv(data) {
async function LoadPickupsAsync() {
- var pickupData = new Array();
+ let pickupData = new Array();
var apiStoreData = await ApiGetCallAsync("user/current/stores");
await asyncForEach(apiStoreData, async (store) => {
@@ -238,6 +266,7 @@ async function LoadPickupsAsync() {
apiPickups.pickups.forEach(pickup => {
pickup.date = new Date(pickup.date);
+ pickup.freeSlots = pickup.totalSlots - pickup.occupiedSlots.length;
var obj = {
store: {
@@ -252,6 +281,7 @@ async function LoadPickupsAsync() {
}
});
+ gLoaded = true;
return pickupData;
}
@@ -261,52 +291,44 @@ async function asyncForEach(array, callback) {
}
}
-function LoadPickups() {
-
- return new Promise(function(resolve, reject){
-
- var storeData = new Array();
-
- // Retrieve stores
- ApiGetCall('user/current/stores').then(function(apiStoreData){
- apiStoreData.forEach(store => {
-
- // Retrieve pickups for store
- ApiGetCall('stores/' + store.id + '/pickups').then(function(apiPickups) {
- if(apiPickups.pickups.length > 0) {
-
- apiPickups.pickups.forEach(pickup => {
- pickup.date = new Date(pickup.date);
- });
-
- // Add storedata only if pickups available
- var obj = {
- id: store.id,
- name: store.name,
- pickups: apiPickups.pickups,
- pickupStatus: store.pickupStatus,
- };
-
-
- storeData.push(obj);
- }
- });
- });
-
- resolve(storeData);
- });
- });
-
-}
-
-function CreateColumn(num, title) {
+function CreateColumn(num, title, htmlPre, htmlSuf) {
var titleDiv = CreateElement("div", "day-title text-center", title);
+ titleDiv.innerHTML = title;
+
+ if(htmlPre) {
+ titleDiv.innerHTML = htmlPre + titleDiv.innerHTML;
+ }
+ if(htmlSuf) {
+ titleDiv.innerHTML = titleDiv.innerHTML + htmlSuf;
+ }
+
+ var displayDate = new Date(gFirstDayDate);
+ displayDate.setDate(gFirstDayDate.getDate() + num);
+ console.log(displayDate);
+
+ titleDiv.innerHTML = titleDiv.innerHTML + "
" + GetDatetext(displayDate);
+
var day = CreateElement("div", "day day-" + num, titleDiv);
return day;
}
+function GetDatetext(date) {
+ return WithLeadingZeros(date.getDate(), 2) + "." + WithLeadingZeros(date.getMonth(), 2) + "." + WithLeadingZeros(date.getYear() + 1900, 4)
+}
+function WithLeadingZeros(number, length) {
+
+ var stringNumber = number.toString();
+
+ while(stringNumber.length < length) {
+ stringNumber = "0" + stringNumber;
+ }
+
+ return stringNumber;
+}
+
+// Toggle planner visibility. Load data on show
function TogglePlanner() {
var mainPanel = document.querySelectorAll(".fspl")[0];
@@ -319,6 +341,7 @@ function TogglePlanner() {
}
}
+// Create calendar button for navigation bar
function CreateButton() {
var i = CreateElement("i", "fas fa-calendar-alt");
var a = CreateElement("a", "nav-link", i);
@@ -331,6 +354,7 @@ function CreateButton() {
document.querySelectorAll(".navbar-nav.nav-row")[0].append(div);
}
+// Create element helper function
function CreateElement(tagName, classList, content) {
var element = document.createElement(tagName);
@@ -340,34 +364,17 @@ function CreateElement(tagName, classList, content) {
return element;
}
-function ApiGetCall(endpoint) {
-
- if(token == null) { token = ReadToken(); }
-
- return new Promise(function(resolve, reject){
- window.$.ajax({
- url: 'https://foodsharing.de/api/' + endpoint,
- beforeSend: function(xhr) {
- xhr.setRequestHeader("X-CSRF-Token", token)
- }, success: function(data){
- resolve(data)
- }
- });
- });
-}
-
+// Api call function
async function ApiGetCallAsync(endpoint) {
- const res = await getData('https://foodsharing.de/api/' + endpoint);
+ const res = await window.$.ajax({
+ url: 'https://' + window.location.hostname + '/api/' + endpoint,
+ type: 'GET',
+ });
+
return res;
}
-function getData(ajaxurl) {
- return window.$.ajax({
- url: ajaxurl,
- type: 'GET',
- });
-};
-
+// Read token from cookie
function ReadToken() {
var nameEQ = "CSRF_TOKEN=";
var ca = document.cookie.split(';');