Update foodsharing_planner.user.js
This commit is contained in:
@@ -1,13 +1,19 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Foodsharing Planner
|
// @name Foodsharing Planner
|
||||||
// @namespace http://tampermonkey.net/
|
// @namespace http://tampermonkey.net/
|
||||||
// @version 0.1
|
// @version 0.2
|
||||||
// @updateURL https://github.com/TroogS/userscripts/raw/master/foodsharing_planner.user.js
|
// @updateURL https://github.com/TroogS/userscripts/blob/master/foodsharing_planner.user.js
|
||||||
// @downloadURL https://github.com/TroogS/userscripts/raw/master/foodsharing_planner.user.js
|
// @downloadURL https://github.com/TroogS/userscripts/blob/master/foodsharing_planner.user.js
|
||||||
// @description Use stackoverflow full width, optional night mode
|
// @description Generate a calendar like view as addition to the foodsharing website germany, austria and switzerland
|
||||||
// @author A. Beging
|
// @author A. Beging
|
||||||
// @match https://foodsharing.de*
|
// @match https://foodsharing.de*
|
||||||
// @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
|
// @grant none
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
@@ -18,6 +24,9 @@ function GM_addStyle (cssStr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var token;
|
var token;
|
||||||
|
var gPickupData;
|
||||||
|
var gLoaded = false;
|
||||||
|
var gFirstDayDate;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
@@ -70,43 +79,84 @@ a.navbar-brand.brand span:nth-child(2) span{
|
|||||||
|
|
||||||
.day .pickup {
|
.day .pickup {
|
||||||
border: 1px solid #533a20;
|
border: 1px solid #533a20;
|
||||||
|
border-left-width: 5px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day .pickup.available {
|
.day .pickup.pickup-green {
|
||||||
border-color: #64ae25;
|
border-left-color: #64ae24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day .pickup.pickup-yellow {
|
||||||
|
border-left-color: #ffc107
|
||||||
|
}
|
||||||
|
|
||||||
|
.day .pickup.pickup-red {
|
||||||
|
border-left-color: #dc3545;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day .pickup .img-container {
|
.day .pickup .img-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day .pickup .img-container div {
|
.day .pickup .img-container > div {
|
||||||
padding-right: 5px;
|
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() {
|
async function BuildPlannerAsync() {
|
||||||
var data = await LoadPickupsAsync();
|
gFirstDayDate = GetFirstDay();
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
var mainPanel = document.querySelectorAll(".fspl")[0];
|
var mainPanel = document.querySelectorAll(".fspl")[0];
|
||||||
|
|
||||||
var mon = CreateColumn("1", "Montag");
|
var mon = CreateColumn(0, "Montag", '<a href="#"><i class="fas fa-arrow-left"/></a> ', null);
|
||||||
var tue = CreateColumn("2", "Tuesday");
|
var tue = CreateColumn(1, "Dienstag");
|
||||||
var wed = CreateColumn("3", "Wednesday");
|
var wed = CreateColumn(2, "Mittwoch");
|
||||||
var thu = CreateColumn("4", "Thursday");
|
var thu = CreateColumn(3, "Donnerstag");
|
||||||
var fri = CreateColumn("5", "Friday");
|
var fri = CreateColumn(4, "Freitag");
|
||||||
var sat = CreateColumn("6", "Saturday");
|
var sat = CreateColumn(5, "Samstag");
|
||||||
var sun = CreateColumn("7", "Sunday");
|
var sun = CreateColumn(6, "Sonntag", null, ' <a href="#"><i class="fas fa-arrow-right"/></a>');
|
||||||
|
|
||||||
data.sort(function(a, b){return a.pickup.date > b.pickup.date});
|
mainPanel.append(mon);
|
||||||
data.forEach(pickup => {
|
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);
|
var pickupDiv = CreatePickupDiv(pickup);
|
||||||
|
|
||||||
switch (pickup.pickup.date.getDay()) {
|
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() {
|
function GetFirstDay() {
|
||||||
var curr = new Date();
|
var curr = new Date();
|
||||||
var first = curr.getDate() - curr.getDay() + 1;
|
var first = curr.getDate() - curr.getDay() + 1;
|
||||||
@@ -187,8 +195,8 @@ function GetFirstDay() {
|
|||||||
return firstDay;
|
return firstDay;
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetLastDay() {
|
function GetLastDay(firstDayDate) {
|
||||||
var curr = new Date();
|
var curr = new Date(firstDayDate);
|
||||||
var last = curr.getDate() - curr.getDay() + 7;
|
var last = curr.getDate() - curr.getDay() + 7;
|
||||||
var lastDay = new Date(curr.setDate(last));
|
var lastDay = new Date(curr.setDate(last));
|
||||||
lastDay.setHours(23,59,59,999);
|
lastDay.setHours(23,59,59,999);
|
||||||
@@ -198,7 +206,10 @@ function GetLastDay() {
|
|||||||
|
|
||||||
function CreatePickupDiv(data) {
|
function CreatePickupDiv(data) {
|
||||||
var elementClass = "pickup";
|
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 element = CreateElement("div", elementClass);
|
||||||
|
|
||||||
var headerSpan = CreateElement("div", "font-weight-bold", data.store.name);
|
var headerSpan = CreateElement("div", "font-weight-bold", data.store.name);
|
||||||
@@ -210,17 +221,34 @@ function CreatePickupDiv(data) {
|
|||||||
var timeSpan = CreateElement("div", "", timeString);
|
var timeSpan = CreateElement("div", "", timeString);
|
||||||
element.append(timeSpan);
|
element.append(timeSpan);
|
||||||
|
|
||||||
if(data.pickup.occupiedSlots.length > 0) {
|
|
||||||
var imgContainer = CreateElement("div", "img-container");
|
var imgContainer = CreateElement("div", "img-container");
|
||||||
|
|
||||||
|
// Occupies slots
|
||||||
|
if(data.pickup.occupiedSlots.length > 0) {
|
||||||
|
|
||||||
data.pickup.occupiedSlots.forEach(slot => {
|
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");
|
var imgDiv = CreateElement("div");
|
||||||
imgDiv.innerHTML = '<a href="https://foodsharing.de/profile/' + slot.profile.id + '" target="_blank"><img title="' + slot.profile.name + '" src="images/mini_q_' + slot.profile.avatar + '" /></a>';
|
imgDiv.innerHTML = '<a href="https://' + window.location.hostname + '/profile/' + slot.profile.id + '" target="_blank"><img title="' + slot.profile.name + '" src="' + imgUrl + '" /></a>';
|
||||||
imgContainer.append(imgDiv);
|
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 = '<i class="fas fa-question" />';
|
||||||
|
|
||||||
|
imgContainer.append(freeSlotA);
|
||||||
|
}
|
||||||
|
|
||||||
element.append(imgContainer);
|
element.append(imgContainer);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
@@ -228,7 +256,7 @@ function CreatePickupDiv(data) {
|
|||||||
|
|
||||||
async function LoadPickupsAsync() {
|
async function LoadPickupsAsync() {
|
||||||
|
|
||||||
var pickupData = new Array();
|
let pickupData = new Array();
|
||||||
var apiStoreData = await ApiGetCallAsync("user/current/stores");
|
var apiStoreData = await ApiGetCallAsync("user/current/stores");
|
||||||
|
|
||||||
await asyncForEach(apiStoreData, async (store) => {
|
await asyncForEach(apiStoreData, async (store) => {
|
||||||
@@ -238,6 +266,7 @@ async function LoadPickupsAsync() {
|
|||||||
apiPickups.pickups.forEach(pickup => {
|
apiPickups.pickups.forEach(pickup => {
|
||||||
|
|
||||||
pickup.date = new Date(pickup.date);
|
pickup.date = new Date(pickup.date);
|
||||||
|
pickup.freeSlots = pickup.totalSlots - pickup.occupiedSlots.length;
|
||||||
|
|
||||||
var obj = {
|
var obj = {
|
||||||
store: {
|
store: {
|
||||||
@@ -252,6 +281,7 @@ async function LoadPickupsAsync() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gLoaded = true;
|
||||||
return pickupData;
|
return pickupData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,52 +291,44 @@ async function asyncForEach(array, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoadPickups() {
|
function CreateColumn(num, title, htmlPre, htmlSuf) {
|
||||||
|
|
||||||
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) {
|
|
||||||
var titleDiv = CreateElement("div", "day-title text-center", title);
|
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 + "<br />" + GetDatetext(displayDate);
|
||||||
|
|
||||||
var day = CreateElement("div", "day day-" + num, titleDiv);
|
var day = CreateElement("div", "day day-" + num, titleDiv);
|
||||||
|
|
||||||
return day;
|
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() {
|
function TogglePlanner() {
|
||||||
var mainPanel = document.querySelectorAll(".fspl")[0];
|
var mainPanel = document.querySelectorAll(".fspl")[0];
|
||||||
|
|
||||||
@@ -319,6 +341,7 @@ function TogglePlanner() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create calendar button for navigation bar
|
||||||
function CreateButton() {
|
function CreateButton() {
|
||||||
var i = CreateElement("i", "fas fa-calendar-alt");
|
var i = CreateElement("i", "fas fa-calendar-alt");
|
||||||
var a = CreateElement("a", "nav-link", i);
|
var a = CreateElement("a", "nav-link", i);
|
||||||
@@ -331,6 +354,7 @@ function CreateButton() {
|
|||||||
document.querySelectorAll(".navbar-nav.nav-row")[0].append(div);
|
document.querySelectorAll(".navbar-nav.nav-row")[0].append(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create element helper function
|
||||||
function CreateElement(tagName, classList, content) {
|
function CreateElement(tagName, classList, content) {
|
||||||
var element = document.createElement(tagName);
|
var element = document.createElement(tagName);
|
||||||
|
|
||||||
@@ -340,34 +364,17 @@ function CreateElement(tagName, classList, content) {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ApiGetCall(endpoint) {
|
// Api call function
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function ApiGetCallAsync(endpoint) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getData(ajaxurl) {
|
// Read token from cookie
|
||||||
return window.$.ajax({
|
|
||||||
url: ajaxurl,
|
|
||||||
type: 'GET',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function ReadToken() {
|
function ReadToken() {
|
||||||
var nameEQ = "CSRF_TOKEN=";
|
var nameEQ = "CSRF_TOKEN=";
|
||||||
var ca = document.cookie.split(';');
|
var ca = document.cookie.split(';');
|
||||||
|
|||||||
Reference in New Issue
Block a user