From cc55391a7544b0ce0cc37b8aa628dc8f9a46db49 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 2 Oct 2017 15:50:06 +0200 Subject: Website updated to list supporters on the website. --- website/resources/css/custom.css | 23 ++++ website/resources/files/supporters.json | 13 ++ website/resources/img/spinner.gif | Bin 0 -> 828 bytes website/resources/js/order-license.js | 102 +++++++++++++++ website/resources/js/supporters.js | 214 ++++++++++++++++++++++++++++++++ 5 files changed, 352 insertions(+) create mode 100644 website/resources/files/supporters.json create mode 100644 website/resources/img/spinner.gif create mode 100644 website/resources/js/order-license.js create mode 100644 website/resources/js/supporters.js (limited to 'website/resources') diff --git a/website/resources/css/custom.css b/website/resources/css/custom.css index 795b155c..e5bb720e 100644 --- a/website/resources/css/custom.css +++ b/website/resources/css/custom.css @@ -7,6 +7,29 @@ margin-bottom: 40px; } +.supporterBar .introText { + margin-top: 16px; +} + +.barItem { + margin: 16px; + max-width: 168px; +} + +.barItem img { + width: 100%; +} + +.supportItem, .barItem { + display: inline-block; +} + +.supporterBar { + width: 100%; + margin-left: auto; + margin-right: auto; +} + .errorBox { border: 1px dashed #F44; font-size: 1.2em; diff --git a/website/resources/files/supporters.json b/website/resources/files/supporters.json new file mode 100644 index 00000000..a895f95b --- /dev/null +++ b/website/resources/files/supporters.json @@ -0,0 +1,13 @@ +{ + "modWeight": { + "professional": 2.0, + "enterprise": 4.0, + "patron": 1.0 + }, + "professional": [ + ], + "enterprise": [ + ], + "patron": [ + ] +} diff --git a/website/resources/img/spinner.gif b/website/resources/img/spinner.gif new file mode 100644 index 00000000..f627b993 Binary files /dev/null and b/website/resources/img/spinner.gif differ diff --git a/website/resources/js/order-license.js b/website/resources/js/order-license.js new file mode 100644 index 00000000..82627f2b --- /dev/null +++ b/website/resources/js/order-license.js @@ -0,0 +1,102 @@ +"use strict"; + +(function() { + var imgDataUrl = null; + function applyLicense() { + $("#submit").on("click", function(evt) { + evt.preventDefault(); + + var onSuccess = function() { + alert("Form submitted!"); + }; + + var onFailure = function() { + alert("Whoops"); + }; + + var data = {}; + data.name = $("#name").val(); + var rnd = generateRandom(); + var err = processImageUpload(); + if (err) { + alert(err); + $("#logo")[0].value = null; + return; + } + if (imgDataUrl) data.logo = imgDataUrl; + $.ajax({ + url: "/license-submit/" + rnd, + method: "PUT", + contentType: "application/json", + data: JSON.stringify(data), + processData: false, + success: onSuccess, + failure: onFailure + }); + }); + + $("#companyLogo").on("click", function(evt) { + evt.preventDefault(); + $("#logo").click(); + }); + + $("#deleteCompanyLogo").on("click", function(evt) { + evt.preventDefault(); + $("#logo")[0].value = null; + $("#logoCnt").empty().hide(); + $("#companyLogo").show(); + $("#deleteCompanyLogo").hide(); + }); + + $("#logo").on("change", function() { + var err = showImage(); + if (err) { + alert(err); + $("#logo")[0].value = null; + } else { + $("#companyLogo").hide(); + $("#deleteCompanyLogo").show(); + } + }); + } + + function generateRandom() { + var buf = new Uint8Array(40); + window.crypto.getRandomValues(buf); + return btoa(String.fromCharCode.apply(null, buf)).replace(/\+/g, '_').replace(/\//gi, '-'); + } + + function showImage() { + $("#logoCnt").empty().hide(); + try { + return processImageUpload(function(dataUrl) { + var img = $(""); + img.css({ + "max-width": "500px", + "max-height": "300px" + }); + $("#logoCnt").append(img).show(); + img.attr("src", dataUrl); + }); + } catch (e) { + if (console && console.log) console.log(e); + } + } + + function processImageUpload(fnc) { + var f = $("#logo")[0].files[0]; + if (!f) return; + if (f.size > 10000000) return "Logo too large; please give us a logo below 10MiB in size."; + var imageType = /^image\//; + if (!imageType.test(f.type)) return "Please upload an image, for example in PNG format."; + var reader = new FileReader(); + reader.onload = function(e) { + imgDataUrl = e.target.result; + if (fnc) fnc(e.target.result); + }; + reader.readAsDataURL(f); + return null; + } + + $(applyLicense); +})(); diff --git a/website/resources/js/supporters.js b/website/resources/js/supporters.js new file mode 100644 index 00000000..5ec1b057 --- /dev/null +++ b/website/resources/js/supporters.js @@ -0,0 +1,214 @@ +"use strict"; + +(function($) { + var supporters = {}; + var weights = {}; + var types = ["patron", "professional", "enterprise"]; + + function shuffle(array) { + var i = 0, j = 0, temp = null; + for (i = array.length - 1; i > 0; i -= 1) { + j = Math.floor(Math.random() * (i + 1)); + temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } + + function pad(number) { + return number < 10 ? '0' + number : number; + } + + function fromDate(d) { + return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()); + + } + + function toDate(s) { + var x = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s); + if (x) return new Date(parseInt(x[1]), parseInt(x[2]), parseInt(x[3])); + return null; + } + + function Supporter(type, json) { + this.type = type; + this.name = json.name; + this.logo = json.logo; + this.url = json.url; + this.showName = json.showName; + this.start = json.range ? toDate(json.range[0]) : null; + this.end = json.range ? toDate(json.range[1]) : null; + this.weight = (!json.weight && json.weight !== 0.0) ? 1.0 : json.weight; + } + + Supporter.prototype.inRange = function(d) { + return (!this.start || this.start <= d) && (!this.end || this.end > d); + }; + + Supporter.prototype.render = function() { + var d = $("
").addClass("supportItem").addClass(this.type); + var a = d; + if (this.url) { + a = $("").attr("href", this.url).attr("rel", "noopener"); + d.append(a); + } + var n = $("").text(this.name); + a.append(n); + + if (this.logo) { + a.addClass("logo"); + var i = new Image(); + var showName = this.showName; + i.onload = function() { + var w = i.width; + var h = i.height; + var wf = w / 162; + var hf = h / 80; + var f = hf > wf ? hf : wf; + var wt = Math.round(w / f); + var ht = Math.round(h / f); + i.width = wt; + i.height = ht; + if (!showName) a.empty(); + a.prepend(i); + }; + i.src = 'files/' + this.logo; + } + return d; + } + + function errorHandler(xhr, statusText, err) { + var errMsg = "Can't connect to projectlombok.org to fetch the list of licensees and supporters."; + if (console && console.log) { + console.log("AJAX error for loading list of supporters:"); + console.log(err); + } + var errBox = $("
").addClass("errorBox").text(errMsg); + $(".supporters").text("").append(errBox); + } + + function successHandler(data) { + $.each(types, function() { + var t = this; + supporters[t] = []; + if (data && data[t]) $.each(data[t], function() { + supporters[t].push(new Supporter(t, this)); + }); + }); + weights = data.modWeight; + if (typeof weights !== 'object') weights = {}; + updatePage(); + } + + function build() { + var spinner = $("").attr("title", "loading").attr("src", "/img/spinner.gif").addClass("spinner"); + $(".supporters").append(spinner); + $.ajax({ + url: "/files/supporters.json", + dataType: "json", + cache: true, + error: errorHandler, + success: function(data) { + spinner.remove(); + successHandler(data); + } + }); + } + + function applySupporters() { + build(); + } + + function updatePage() { + updateSupporters(); + updateSupporterBar(); + } + + var supPerBar = 4; + function updateSupporterBar() { + var s = $(".supporterBar"); + s.find(".introText").show(); + s.append($("
").addClass("sbCnt")); + s = s.find(".sbCnt"); + var now = new Date(); + var list = []; + $.each(types, function() { + var t = this; + $.each(supporters[t], function() { + if (this.inRange(now)) { + var w = weights[t] ? weights[t] : 1.0; + if (this.weight) w = w * this.weight; + for (var i = 0; i < w; i++) list.push(this); + } + }); + }); + + shuffle(list); + + var len = list.length; + var pos = 0; + var c = [], cd = []; + for (var i = 0; i < supPerBar; i++) { + c[i] = null; + cd[i] = $("
").addClass("barItem"); + } + + var upd = function() { + var nw = [], a = [], fo = $(), fi = $(); + var sPos = pos; + for (var i = 0; i < supPerBar; i++) { + if (++pos === len) pos = 0; + var z = false; + for (var j = 0; j < i; j++) if (nw[j] === list[pos]) z = true; + if (z) i--; + else nw[i] = list[pos]; + if (pos === sPos) break; + } + for (var i = 0; i < supPerBar; i++) a[i] = (nw[i] === c[i] || !nw[i]) ? null : nw[i].render(i + 1).hide(); + for (var i = 0; i < supPerBar; i++) { + if (a[i]) { + fi = fi.add(a[i]); + fo = fo.add(cd[i].children()); + if (cd[i].parent().length === 0) s.append(cd[i]); + cd[i].append(a[i]); + c[i] = nw[i]; + } + } + + if (fo.length === 0) fi.fadeIn(); + else { + fo.fadeOut("normal", function() { + fi.fadeIn(); + fo.remove(); + }); + } + }; + + setInterval(upd, 10000); + upd(); + } + + function updateSupporters() { + var s = $(".supporters"); + s.empty(); + var now = new Date(); + $.each(types, function() { + var t = this; + var d = $("