aboutsummaryrefslogtreecommitdiff
path: root/website
diff options
context:
space:
mode:
Diffstat (limited to 'website')
-rw-r--r--website/resources/css/custom.css23
-rw-r--r--website/resources/files/supporters.json13
-rw-r--r--website/resources/img/spinner.gifbin0 -> 828 bytes
-rw-r--r--website/resources/js/order-license.js102
-rw-r--r--website/resources/js/supporters.js214
-rw-r--r--website/templates/main.html1
-rw-r--r--website/templates/order-license-info.html24
-rw-r--r--website/templates/order-license.html78
-rw-r--r--website/templates/supporters.html10
9 files changed, 465 insertions, 0 deletions
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
--- /dev/null
+++ b/website/resources/img/spinner.gif
Binary files 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 />");
+ 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 = $("<div />").addClass("supportItem").addClass(this.type);
+ var a = d;
+ if (this.url) {
+ a = $("<a />").attr("href", this.url).attr("rel", "noopener");
+ d.append(a);
+ }
+ var n = $("<span />").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 = $("<div />").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 = $("<img />").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($("<div />").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] = $("<div />").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 = $("<div />").addClass("row");
+ var h = $("<h2 />").text(t);
+ d.append(h);
+ $.each(supporters[t], function() {
+ if (this.inRange(now)) d.append(this.render());
+ });
+ if (d.children().length > 1) s.append(d);
+ });
+ if (s.children().length < 1) {
+ var x = $("<div />").addClass("noSupportersBox").html(
+ "We don't have any supporters yet this month.<br /><a href=\"https://patreon.com/lombok\" rel=\"noopener\">Become a patron</a> " +
+ "or <a href=\"/order-license-info\">order a professional or enterprise license</a> today!");
+ s.append(x);
+ }
+ }
+
+ $(applySupporters);
+})($); \ No newline at end of file
diff --git a/website/templates/main.html b/website/templates/main.html
index 2089cb5e..df096955 100644
--- a/website/templates/main.html
+++ b/website/templates/main.html
@@ -29,6 +29,7 @@
</div>
</div>
<div class="row supporterBar">
+ <div class="introText" hidden="hidden">Project Lombok is powered by:</div>
</div>
</div>
<div class="row text-center">
diff --git a/website/templates/order-license-info.html b/website/templates/order-license-info.html
new file mode 100644
index 00000000..b465eaf0
--- /dev/null
+++ b/website/templates/order-license-info.html
@@ -0,0 +1,24 @@
+<#import "/_scaffold.html" as main>
+
+<@main.scaffold>
+ <div class="page-header top5">
+ <div class="row text-center">
+ <h2>Order a professional or enterprise license</h2>
+ </div>
+ <div class="row">
+ <p>
+ Lombok is open source. We offer three licenses for using lombok. The standard license is free. Here you can order a professional or enterprise license.
+ </p><p>
+ As part of being a professional or enterprise licensee, we normally offer to put your name, a logo, and possibly a link on our ‘supporters and licensees’ page. From time to time we’ll put a supporter or licensee on our front page. You may of course opt out of this offer. We may, at our discretion, opt not to list you. If we elect not to do so, you will be notified at the email address you fill in on our form, and you are as always free to cancel your license at any time.
+ </p><p>
+ The license fee is based on the number of developers that work for you or your company using Project Lombok, per month. The fee is charged in advance. You may choose to pay either monthly or yearly (for sufficiently small licensees, only a yearly option is available).
+ </p><p>
+ <span class="legalese">Project Lombok is provided by the copyright holders and contributors “as is” and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed, even for professional and enterprise license holders. In no event shall the copyright holder or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.</span>
+ </p><p>
+ Instead of a professional or enterprise license, if you’d like to support the efforts of Project Lombok, you can also support us via <a href="https://www.patreon.com/lombok">Patreon</a>.
+ </p><p>
+ <a href="order-license">Order a professional or enterprise license now</a>.
+ </p>
+ </div>
+ </div>
+</@main.scaffold>
diff --git a/website/templates/order-license.html b/website/templates/order-license.html
new file mode 100644
index 00000000..4d52d93a
--- /dev/null
+++ b/website/templates/order-license.html
@@ -0,0 +1,78 @@
+<#import "/_scaffold.html" as main>
+
+<@main.scaffold load=["/js/order-license.js"]>
+ <div class="page-header top5">
+ <div class="row text-center">
+ <h2>Order a professional or enterprise license</h2>
+ </div>
+ <div class="row">
+ <form>
+ <fieldset class="form-group">
+ <legend>Basic information</legend>
+ <div class="form-group">
+ <label for="companyName">Company name</label>
+ <input type="text" class="form-control" aria-describedby="companyNameHelp" id="companyName" placeholder="license holder name" />
+ <small id="companyNameHelp" class="form-text text-muted">If applying for an individual license, fill in your own name.</small>
+ </div>
+ <div class="form-group">
+ <label for="email">Email</label>
+ <input type="email" class="form-control" aria-describedby="emailHelp" id="email" placeholder="email of contact / holder" />
+ <small id="emailHelp" class="form-text text-muted">We will never share this email with any third parties; we'll email you the invoice at this email address.</small>
+ </div>
+ </fieldset>
+ <fieldset class="form-group">
+ <legend>Type of license</legend>
+ <div class="form-check">
+ <label class="form-check-label">
+ <input type="radio" class="form-check-input" name="licenseType" value="professional" checked="checked" />
+ Professional
+ </label>
+ </div>
+ <div class="form-check">
+ <label class="form-check-label">
+ <input type="radio" class="form-check-input" name="licenseType" value="enterprise" />
+ Enterprise
+ </label>
+ </div>
+ </fieldset>
+ <fieldset class="form-group">
+ <legend>Mention</legend>
+ <div class="form-check">
+ <label class="form-check-label">
+ <input type="checkbox" class="form-check-input" name="mentionMe" checked="checked" />
+ Mention me on the <em>supporters / licensees</em> page.
+ </label>
+ </div>
+ <div class="form-group">
+ <label for="companyUrl">Company URL (optional)</label>
+ <input type="url" class="form-control" id="companyUrl" placeholder="URL of your company website" />
+ </div>
+ <div class="form-group">
+ <label for="logo">Company Logo (optional)</label>
+ <input type="file" style="display: none;" id="logo" name="logo" />
+ <button class="form-control" id="companyLogo">Upload a logo</button>
+ <div id="logoCnt" style="display: none;"></div>
+ <button class="form-control" id="deleteCompanyLogo" style="display: none;">Remove logo</button>
+ </div>
+ </fieldset>
+ <button type="submit" class="btn btn-primary">Submit order</button>
+ </p>
+ </div>
+ </div>
+ <div>
+Form fields:
+
+* EU / US / Elders
+* Naam bedrijf
+* Do you want to be mentioned?
+* Link to logo
+* Link to website
+* Professional of enterprise
+* # of developers
+* Email of contact.sta
+* In EU: VAT Number
+* In EU: How would you like to pay? IBAN or Payoneer
+* In US: How would you like to pay? International wire transfer, or Payoneer (default = payoneer).
+* Elders: We’ll get back to you..
+ </div>
+</@main.scaffold>
diff --git a/website/templates/supporters.html b/website/templates/supporters.html
new file mode 100644
index 00000000..2003a23f
--- /dev/null
+++ b/website/templates/supporters.html
@@ -0,0 +1,10 @@
+<#import "/_scaffold.html" as main>
+
+<@main.scaffold load=["js/supporters.js"]>
+ <div class="page-header top5">
+ <div class="row text-center">
+ <h1>Project Lombok supporters</h1>
+ </div><div class="row supporters">
+ </div>
+ </div>
+</@main.scaffold>