diff --git a/res/include/md/subscribe.md b/res/include/md/subscribe.md
index 93fccbe..6189166 100644
--- a/res/include/md/subscribe.md
+++ b/res/include/md/subscribe.md
@@ -39,6 +39,10 @@ account. {{if .Authenticated}}(Your e-mail address: {{.User.Email}}){{end}}
Order plan 'I'm doing my part!'
+{{else if eq $plan "t5"}}
+
+Order plan 'Resolve'
+
{{else if eq $plan "t2"}}
Order plan 'Persistence'
diff --git a/res/include/script/admin.js b/res/include/script/admin.js
index 1c7e23b..6c3d2af 100644
--- a/res/include/script/admin.js
+++ b/res/include/script/admin.js
@@ -1,102 +1,10 @@
-// Draw usage graph
+let graphViews = drawGraph(document.getElementById("views_chart"), "Views", "number");
+let graphBandwidth = drawGraph(document.getElementById("bandwidth_chart"), "Bandwidth", "bytes");
-Chart.defaults.global.defaultFontColor = "#b3b3b3";
-Chart.defaults.global.defaultFontSize = 15;
-Chart.defaults.global.defaultFontFamily = "Ubuntu";
-Chart.defaults.global.maintainAspectRatio = false;
-Chart.defaults.global.elements.point.radius = 0;
-Chart.defaults.global.tooltips.mode = "index";
-Chart.defaults.global.tooltips.axis = "x";
-Chart.defaults.global.tooltips.intersect = false;
-Chart.defaults.global.animation.duration = 1000;
-Chart.defaults.global.animation.easing = "linear";
-
-var graph = new Chart(
- document.getElementById('bandwidth_chart'),
- {
- type: 'line',
- data: {
- datasets: [
- {
- label: "Bandwidth",
- backgroundColor: "rgba(64, 255, 64, .01)",
- borderColor: "rgba(96, 255, 96, 1)",
- borderWidth: 1.5,
- lineTension: 0.2,
- fill: true,
- yAxisID: "y_bandwidth"
- }, {
- label: "Views",
- backgroundColor: "rgba(64, 64, 255, .01)",
- borderColor: "rgba(96, 96, 255, 1)",
- borderWidth: 1.5,
- lineTension: 0.2,
- fill: true,
- yAxisID: "y_views"
- }
- ]
- },
- options: {
- scales: {
- yAxes: [
- {
- type: "linear",
- display: true,
- position: "left",
- id: "y_bandwidth",
- scaleLabel: {
- display: true,
- labelString: "Bandwidth"
- },
- ticks: {
- callback: function(value, index, values) {
- return formatDataVolume(value, 3);
- },
- beginAtZero: true
- },
- gridLines: {
- color: "rgba(100, 255, 100, .05)"
- }
- }, {
- type: "linear",
- display: true,
- position: "right",
- id: "y_views",
- scaleLabel: {
- display: true,
- labelString: "Views"
- },
- ticks: {
- callback: function(value, index, values) {
- return formatNumber(value, 3);
- },
- beginAtZero: true
- },
- gridLines: {
- color: "rgba(128, 128, 255, .05)"
- }
- }
- ],
- xAxes: [
- {
- ticks: {
- maxRotation: 16
- },
- gridLines: {
- display: false
- }
- }
- ]
- }
- }
- }
-);
-
-let graphTimeout = null;
function loadGraph(minutes, interval, live){
if (graphTimeout !== null) { clearTimeout(graphTimeout) }
if (live) {
- graphTimeout = setTimeout(() => {loadGraph(minutes, interval, true)}, 2000)
+ graphTimeout = setTimeout(() => {updateGraphs(minutes, interval, true)}, 10000)
}
let today = new Date()
@@ -112,26 +20,41 @@ function loadGraph(minutes, interval, live){
if (!resp.ok) { return Promise.reject("Error: "+resp.status);}
return resp.json();
}).then(resp => {
- if (resp.success) {
- window.graph.data.labels = resp.labels;
- window.graph.data.datasets[0].data = resp.downloads;
- window.graph.data.datasets[1].data = resp.views;
- window.graph.update();
+ resp.views.timestamps.forEach((val, idx) => {
+ let date = new Date(val);
+ let dateStr = ("00"+(date.getMonth()+1)).slice(-2);
+ dateStr += "-"+("00"+date.getDate()).slice(-2);
+ dateStr += " "+("00"+date.getHours()).slice(-2);
+ dateStr += ":"+("00"+date.getMinutes()).slice(-2);
+ resp.views.timestamps[idx] = " "+dateStr+" "; // Poor man's padding
+ });
+ graphViews.data.labels = resp.views.timestamps;
+ graphViews.data.datasets[0].data = resp.views.amounts;
+ graphBandwidth.data.labels = resp.views.timestamps;
+ graphBandwidth.data.datasets[0].data = resp.bandwidth.amounts;
+ graphViews.update()
+ graphBandwidth.update();
- document.getElementById("time_start").innerText = resp.labels[0];
- document.getElementById("time_end").innerText = resp.labels.slice(-1)[0];
- let total = 0
- resp.downloads.forEach(e => { total += e; });
- document.getElementById("total_bandwidth").innerText = formatDataVolume(total, 3);
- total = 0
- resp.views.forEach(e => { total += e; });
- document.getElementById("total_views").innerText = formatThousands(total);
- }
+ document.getElementById("time_start").innerText = resp.views.timestamps[0];
+ document.getElementById("time_end").innerText = resp.views.timestamps.slice(-1)[0];
+ let total = 0
+ resp.bandwidth.amounts.forEach(e => { total += e; });
+ document.getElementById("total_bandwidth").innerText = formatDataVolume(total, 3);
+ total = 0
+ resp.views.amounts.forEach(e => { total += e; });
+ document.getElementById("total_views").innerText = formatThousands(total);
}).catch(e => {
alert("Error requesting time series: "+e);
})
}
+let graphTimeout = null;
+function updateGraphs(minutes, interval, live) {
+
+ loadGraph(graphViews, "views", minutes, interval);
+ loadGraph(graphBandwidth, "bandwidth", minutes, interval);
+}
+
loadGraph(1440, 10, true);
// Load performance statistics
diff --git a/res/include/script/dependencies/Modal.js b/res/include/script/dependencies/Modal.js
index 95f15fb..0a32483 100644
--- a/res/include/script/dependencies/Modal.js
+++ b/res/include/script/dependencies/Modal.js
@@ -55,6 +55,10 @@ Modal.prototype.setBody = function(element) {
this.body.append(element)
}
+Modal.prototype.cloneTemplate = function(templateID) {
+ this.setBody(document.getElementById(templateID).content.cloneNode(true))
+}
+
Modal.prototype.open = function() {
if (this.visible) { return }
this.visible = true
diff --git a/res/include/script/dependencies/drawGraph.js b/res/include/script/dependencies/drawGraph.js
new file mode 100644
index 0000000..fafe5a9
--- /dev/null
+++ b/res/include/script/dependencies/drawGraph.js
@@ -0,0 +1,65 @@
+Chart.defaults.global.defaultFontColor = "#b3b3b3";
+Chart.defaults.global.defaultFontSize = 15;
+Chart.defaults.global.defaultFontFamily = "system-ui, sans-serif";
+Chart.defaults.global.maintainAspectRatio = false;
+Chart.defaults.global.elements.point.radius = 0;
+Chart.defaults.global.tooltips.mode = "index";
+Chart.defaults.global.tooltips.axis = "x";
+Chart.defaults.global.tooltips.intersect = false;
+Chart.defaults.global.animation.duration = 500;
+Chart.defaults.global.animation.easing = "linear";
+
+function drawGraph(element, label, dataType) {
+ return new Chart(
+ element,
+ {
+ type: 'line',
+ data: {
+ datasets: [
+ {
+ label: label,
+ backgroundColor: highlightColor,
+ borderWidth: 0,
+ lineTension: 0,
+ fill: true,
+ yAxisID: "ax_1"
+ }
+ ]
+ },
+ options: {
+ legend: { display: false },
+ scales: {
+ yAxes: [
+ {
+ type: "linear",
+ display: true,
+ position: "left",
+ id: "ax_1",
+ ticks: {
+ callback: function(value, index, values) {
+ if (dataType == "bytes") {
+ return formatDataVolume(value, 3);
+ }
+ return formatNumber(value, 3);
+ },
+ beginAtZero: true
+ },
+ gridLines: { display: false },
+ }
+ ],
+ xAxes: [
+ {
+ ticks: {
+ sampleSize: 1,
+ padding: 4,
+ minRotation: 0,
+ maxRotation: 0
+ },
+ gridLines: { display: false }
+ }
+ ]
+ }
+ }
+ }
+ );
+}
diff --git a/res/include/script/file_viewer/DetailsWindow.js b/res/include/script/file_viewer/DetailsWindow.js
index c38ed0d..d41c05f 100644
--- a/res/include/script/file_viewer/DetailsWindow.js
+++ b/res/include/script/file_viewer/DetailsWindow.js
@@ -2,7 +2,9 @@ function DetailsWindow(viewer) {
this.viewer = viewer
this.visible = false
this.file = null
- this.graph = 0
+ this.graphsInitialized = false
+ this.graphViews = 0
+ this.graphDownloads = 0
this.modal = new Modal(
document.getElementById("file_viewer"),
() => { this.toggle() },
@@ -27,8 +29,9 @@ DetailsWindow.prototype.toggle = function() {
this.btnDetails.classList.add("button_highlight")
this.visible = true
- if (this.graph === 0) {
- this.renderGraph()
+ if (!this.graphsInitialized) {
+ this.renderGraphs()
+ this.graphsInitialized = true
}
this.updateGraph(this.file)
}
@@ -54,12 +57,22 @@ DetailsWindow.prototype.setFile = function(file) {
}
}
+DetailsWindow.prototype.renderGraphs = function() {
+ console.log("rendering graphs")
+ this.graphDownloads = drawGraph(
+ document.getElementById("downloads_chart"), "Downloads", "number",
+ );
+ this.graphViews = drawGraph(
+ document.getElementById("views_chart"), "Views", "number",
+ );
+}
+
DetailsWindow.prototype.updateGraph = function(file) {
console.log("updating graph")
let today = new Date()
let start = new Date()
- start.setDate(start.getDate()-30)
+ start.setDate(start.getDate()-90)
fetch(
file.timeseries_href+
@@ -70,101 +83,21 @@ DetailsWindow.prototype.updateGraph = function(file) {
if (!resp.ok) {return null}
return resp.json()
}).then(resp => {
- this.graph.data.labels = resp.labels
- this.graph.data.datasets[0].data = resp.downloads
- this.graph.data.datasets[1].data = resp.views
- this.graph.update()
+ resp.views.timestamps.forEach((val, idx) => {
+ let date = new Date(val);
+ let dateStr = ("00"+(date.getMonth()+1)).slice(-2);
+ dateStr += "-"+("00"+date.getDate()).slice(-2);
+ dateStr += " "+("00"+date.getHours()).slice(-2)+"h";
+ resp.views.timestamps[idx] = " "+dateStr+" "; // Poor man's padding
+ });
+ resp.bandwidth.amounts.forEach((val, idx) => {
+ resp.bandwidth.amounts[idx] = Math.round(val/file.size);
+ });
+ this.graphDownloads.data.labels = resp.views.timestamps
+ this.graphViews.data.labels = resp.views.timestamps
+ this.graphDownloads.data.datasets[0].data = resp.bandwidth.amounts
+ this.graphViews.data.datasets[0].data = resp.views.amounts
+ this.graphDownloads.update()
+ this.graphViews.update()
})
}
-
-DetailsWindow.prototype.renderGraph = function() {
- console.log("rendering graph")
- Chart.defaults.global.defaultFontColor = "#b3b3b3"
- Chart.defaults.global.defaultFontSize = 15
- Chart.defaults.global.defaultFontFamily = "Ubuntu"
- Chart.defaults.global.maintainAspectRatio = false;
- Chart.defaults.global.elements.point.radius = 0
- Chart.defaults.global.tooltips.mode = "index"
- Chart.defaults.global.tooltips.axis = "x"
- Chart.defaults.global.tooltips.intersect = false
- this.graph = new Chart(
- document.getElementById('bandwidth_chart'),
- {
- type: 'line',
- data: {
- datasets: [
- {
- label: "Downloads",
- backgroundColor: "rgba(64, 255, 64, .01)",
- borderColor: "rgba(96, 255, 96, 1)",
- borderWidth: 1.5,
- lineTension: 0.2,
- fill: true,
- yAxisID: "y_bandwidth"
- }, {
- label: "Views",
- backgroundColor: "rgba(64, 64, 255, .01)",
- borderColor: "rgba(96, 96, 255, 1)",
- borderWidth: 1.5,
- lineTension: 0.2,
- fill: true,
- yAxisID: "y_views"
- }
- ]
- },
- options: {
- scales: {
- yAxes: [
- {
- type: "linear",
- display: true,
- position: "left",
- id: "y_bandwidth",
- scaleLabel: {
- display: true,
- labelString: "Downloads"
- },
- ticks: {
- callback: function(value, index, values) {
- return formatNumber(value, 3);
- },
- beginAtZero: true
- },
- gridLines: {
- color: "rgba(100, 255, 100, .05)"
- }
- }, {
- type: "linear",
- display: true,
- position: "right",
- id: "y_views",
- scaleLabel: {
- display: true,
- labelString: "Views"
- },
- ticks: {
- callback: function(value, index, values) {
- return formatNumber(value, 3);
- },
- beginAtZero: true
- },
- gridLines: {
- color: "rgba(128, 128, 255, .05)"
- }
- }
- ],
- xAxes: [
- {
- ticks: {
- maxRotation: 16
- },
- gridLines: {
- display: false
- }
- }
- ]
- }
- }
- }
- )
-}
diff --git a/res/include/script/user_home.js b/res/include/script/user_home.js
new file mode 100644
index 0000000..e986b8a
--- /dev/null
+++ b/res/include/script/user_home.js
@@ -0,0 +1,61 @@
+function loadGraph(graph, stat, minutes, interval){
+ let today = new Date()
+ let start = new Date()
+ start.setMinutes(start.getMinutes()-minutes)
+
+ fetch(
+ apiEndpoint+"/user/time_series/" + stat +
+ "?start="+start.toISOString() +
+ "&end="+today.toISOString() +
+ "&interval="+interval
+ ).then(resp => {
+ if (!resp.ok) { return Promise.reject("Error: "+resp.status);}
+ return resp.json();
+ }).then(resp => {
+ resp.timestamps.forEach((val, idx) => {
+ let date = new Date(val);
+ let dateStr = ("00"+(date.getMonth()+1)).slice(-2);
+ dateStr += "-"+("00"+date.getDate()).slice(-2);
+ dateStr += " "+("00"+date.getHours()).slice(-2);
+ dateStr += ":"+("00"+date.getMinutes()).slice(-2);
+ resp.timestamps[idx] = " "+dateStr+" "; // Poor man's padding
+ });
+ graph.data.labels = resp.timestamps;
+ graph.data.datasets[0].data = resp.amounts;
+ graph.update();
+
+ document.getElementById("time_start").innerText = resp.timestamps[0];
+ document.getElementById("time_end").innerText = resp.timestamps.slice(-1)[0];
+ let total = 0
+ resp.amounts.forEach(e => { total += e; });
+
+ if (stat == "views") {
+ document.getElementById("total_views").innerText = formatThousands(total);
+ } else if (stat == "downloads") {
+ document.getElementById("total_downloads").innerText = formatThousands(total);
+ } else if (stat == "bandwidth") {
+ document.getElementById("total_bandwidth").innerText = formatDataVolume(total, 3);
+ }
+ }).catch(e => {
+ console.error("Error requesting time series: "+e);
+ })
+}
+
+let graphViews = drawGraph(document.getElementById("views_chart"), "Views", "number");
+let graphDownloads = drawGraph(document.getElementById("downloads_chart"), "Downloads", "number");
+let graphBandwidth = drawGraph(document.getElementById("bandwidth_chart"), "Bandwidth", "bytes");
+let graphTimeout = null;
+
+function updateGraphs(minutes, interval, live) {
+ if (graphTimeout !== null) { clearTimeout(graphTimeout) }
+ if (live) {
+ graphTimeout = setTimeout(() => {updateGraphs(minutes, interval, true)}, 10000)
+ }
+
+ loadGraph(graphViews, "views", minutes, interval);
+ loadGraph(graphDownloads, "downloads", minutes, interval);
+ loadGraph(graphBandwidth, "bandwidth", minutes, interval);
+}
+
+// Default
+updateGraphs(10080, 60, false);
diff --git a/res/include/style/file_manager.css b/res/include/style/file_manager.css
index 985f41a..d97af23 100644
--- a/res/include/style/file_manager.css
+++ b/res/include/style/file_manager.css
@@ -104,6 +104,7 @@ is collapsed */
margin: 0;
box-sizing: border-box;
color: var(--text_color);
+ text-decoration: none;
}
.node:hover:not(.node_selected) {
background-color: var(--input_color_dark);
diff --git a/res/include/style/layout.css b/res/include/style/layout.css
index e398ebe..61958dd 100644
--- a/res/include/style/layout.css
+++ b/res/include/style/layout.css
@@ -96,7 +96,7 @@ body{
.page_navigation {
position: fixed;
backface-visibility: hidden;
- z-index: 100;
+ z-index: 99;
width: 250px;
height: 100%;
left: 0;
@@ -125,7 +125,7 @@ body{
overflow-x: hidden;
z-index: 50;
transition: left 0.5s;
- padding: 50px 0 50px 0;
+ padding: 70px 0 100px 0;
}
@media (max-width: 800px) {
.page_navigation {
@@ -183,6 +183,7 @@ body{
text-overflow: ellipsis;
transition: background-color 0.5s;
border-radius: 5px;
+ text-decoration: none;
}
.page_navigation a:hover {
background-color: #3f3f3f;
@@ -285,10 +286,11 @@ hr{
a {
color: #74ad38;
- color: var(--highlight_color);
- text-decoration: none;
+ color: var(--highlight_color_dark);
+}
+a:hover {
+ color: var(--highlight_color);
}
-a:hover {text-decoration: underline;}
.form{
margin-left: auto;
diff --git a/res/include/style/modal.css b/res/include/style/modal.css
index 39c6417..9ba2b93 100644
--- a/res/include/style/modal.css
+++ b/res/include/style/modal.css
@@ -1,5 +1,5 @@
.modal_background {
- position: absolute;
+ position: fixed;
top: 0;
right: 0;
bottom: 0;
diff --git a/res/static/img/benefit_5.png b/res/static/img/benefit_5.png
new file mode 100644
index 0000000..1fe9f8e
Binary files /dev/null and b/res/static/img/benefit_5.png differ
diff --git a/res/template/account/user_home.html b/res/template/account/user_home.html
index 567a4e5..904936f 100644
--- a/res/template/account/user_home.html
+++ b/res/template/account/user_home.html
@@ -18,52 +18,77 @@
+ {{if eq .User.Subscription.Name ""}}
+ Supporter status: Not a pixeldrain supporter
Learn how to support pixeldrain.
{{else}}
- {{if eq .User.Subscription "patreon_1"}}
- Level 1 Patreon supporter. Benefits:
-
-
- {{else if eq .User.Subscription "patreon_2"}}
- Level 2 Patreon supporter. Benefits:
-
-
- {{else if eq .User.Subscription "patreon_3"}}
- Level 3 Patreon supporter. Benefits:
-
-
- {{else if eq .User.Subscription "patreon_4"}}
- Level 4 Patreon supporter. Benefits:
-
-
- {{end}}
+ Supporter level {{.User.Subscription.Name}}
+
+
{{end}}
+ Here you can see how often your files are viewed, downloaded + and how much bandwidth they consume. The buttons at the top + can be pressed to adjust the timeframe. If you choose 'Live' + or 'Day' the statistics will be updated periodically. No + need to refresh the page. +
+ +