2025-10-13 16:05:50 +02:00
|
|
|
<script lang="ts">
|
2024-07-09 18:18:26 +02:00
|
|
|
import { onMount } from "svelte";
|
2025-03-27 15:38:59 +01:00
|
|
|
import Chart from "util/Chart.svelte";
|
2025-10-13 16:05:50 +02:00
|
|
|
import { color_by_name } from "util/Util";
|
2025-03-28 14:16:20 +01:00
|
|
|
import { formatDataVolume, formatThousands } from "util/Formatting";
|
2025-10-13 16:05:50 +02:00
|
|
|
import { get_endpoint } from "lib/PixeldrainAPI";
|
2024-07-09 18:18:26 +02:00
|
|
|
|
2025-10-13 16:05:50 +02:00
|
|
|
let { card_size = 1 }: {
|
|
|
|
|
card_size?: number;
|
|
|
|
|
} = $props();
|
|
|
|
|
|
|
|
|
|
let chart_height = $derived((80 + (card_size * 60)) + "px")
|
|
|
|
|
let graph_views_downloads = $state(null)
|
|
|
|
|
let graph_bandwidth = $state(null)
|
2024-07-09 18:18:26 +02:00
|
|
|
|
|
|
|
|
let load_graphs = async (minutes, interval) => {
|
|
|
|
|
let end = new Date()
|
|
|
|
|
let start = new Date()
|
|
|
|
|
start.setMinutes(start.getMinutes() - minutes)
|
|
|
|
|
|
|
|
|
|
try {
|
2025-10-13 16:05:50 +02:00
|
|
|
let views_req = get_graph_data("views", start, end, interval);
|
|
|
|
|
let downloads_req = get_graph_data("downloads", start, end, interval);
|
|
|
|
|
let bandwidth_req = get_graph_data("bandwidth", start, end, interval);
|
|
|
|
|
let transfer_paid_req = get_graph_data("transfer_paid", start, end, interval);
|
|
|
|
|
let views = await views_req
|
|
|
|
|
let downloads = await downloads_req
|
|
|
|
|
let bandwidth = await bandwidth_req
|
|
|
|
|
let transfer_paid = await transfer_paid_req
|
2024-07-09 18:18:26 +02:00
|
|
|
|
|
|
|
|
graph_views_downloads.data().labels = views.timestamps;
|
|
|
|
|
graph_views_downloads.data().datasets[0].data = views.amounts
|
|
|
|
|
graph_views_downloads.data().datasets[1].data = downloads.amounts
|
|
|
|
|
graph_bandwidth.data().labels = bandwidth.timestamps;
|
|
|
|
|
graph_bandwidth.data().datasets[0].data = bandwidth.amounts
|
|
|
|
|
graph_bandwidth.data().datasets[1].data = transfer_paid.amounts
|
|
|
|
|
|
|
|
|
|
graph_views_downloads.update()
|
|
|
|
|
graph_bandwidth.update()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Failed to update graphs", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-13 16:05:50 +02:00
|
|
|
let total_views = $state(0)
|
|
|
|
|
let total_downloads = $state(0)
|
|
|
|
|
let total_bandwidth = $state(0)
|
|
|
|
|
let total_transfer_paid = $state(0)
|
2024-07-09 18:18:26 +02:00
|
|
|
|
2025-10-13 16:05:50 +02:00
|
|
|
let get_graph_data = async (stat: string, start: Date, end: Date, interval: number) => {
|
2024-07-09 18:18:26 +02:00
|
|
|
let resp = await fetch(
|
2025-10-13 16:05:50 +02:00
|
|
|
get_endpoint() + "/user/time_series/" + stat +
|
2024-07-09 18:18:26 +02:00
|
|
|
"?start=" + start.toISOString() +
|
|
|
|
|
"&end=" + end.toISOString() +
|
|
|
|
|
"&interval=" + interval
|
|
|
|
|
)
|
2025-10-13 16:05:50 +02:00
|
|
|
let resp_json: {
|
|
|
|
|
timestamps: string[]
|
|
|
|
|
amounts: number[]
|
|
|
|
|
} = await resp.json()
|
2024-07-09 18:18:26 +02:00
|
|
|
|
|
|
|
|
// Convert the timestamps to a human-friendly format
|
2025-10-13 16:05:50 +02:00
|
|
|
resp_json.timestamps.forEach((val, idx) => {
|
2024-07-09 18:18:26 +02:00
|
|
|
let date = new Date(val);
|
2025-10-13 16:05:50 +02:00
|
|
|
let str: string = date.getFullYear().toString();
|
2024-07-09 18:18:26 +02:00
|
|
|
str += "-" + ("00" + (date.getMonth() + 1)).slice(-2);
|
|
|
|
|
str += "-" + ("00" + date.getDate()).slice(-2);
|
|
|
|
|
str += " " + ("00" + date.getHours()).slice(-2);
|
|
|
|
|
str += ":" + ("00" + date.getMinutes()).slice(-2);
|
2025-10-13 16:05:50 +02:00
|
|
|
resp_json.timestamps[idx] = " " + str + " "; // Poor man's padding
|
2024-07-09 18:18:26 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Add up the total amount and save it in the correct place
|
2025-10-13 16:05:50 +02:00
|
|
|
let total = resp_json.amounts.reduce((acc, cur) => { return acc + cur }, 0)
|
2024-07-09 18:18:26 +02:00
|
|
|
|
|
|
|
|
if (stat == "views") {
|
|
|
|
|
total_views = total;
|
|
|
|
|
} else if (stat == "downloads") {
|
|
|
|
|
total_downloads = total;
|
|
|
|
|
graph_views_downloads.update()
|
|
|
|
|
} else if (stat == "bandwidth") {
|
|
|
|
|
total_bandwidth = total;
|
|
|
|
|
} else if (stat == "transfer_paid") {
|
|
|
|
|
total_transfer_paid = total;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-13 16:05:50 +02:00
|
|
|
return resp_json
|
2024-07-09 18:18:26 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-13 16:05:50 +02:00
|
|
|
let graph_timespan = $state(0)
|
2024-07-09 18:18:26 +02:00
|
|
|
let update_graphs = (minutes, interval) => {
|
|
|
|
|
graph_timespan = minutes
|
|
|
|
|
load_graphs(minutes, interval)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMount(() => {
|
|
|
|
|
graph_views_downloads.data().datasets = [
|
|
|
|
|
{
|
|
|
|
|
label: "Views",
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
pointRadius: 0,
|
|
|
|
|
borderColor: color_by_name("highlight_color"),
|
|
|
|
|
backgroundColor: color_by_name("highlight_color"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Downloads",
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
pointRadius: 0,
|
|
|
|
|
borderColor: color_by_name("danger_color"),
|
|
|
|
|
backgroundColor: color_by_name("danger_color"),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
graph_bandwidth.data().datasets = [
|
|
|
|
|
{
|
2025-01-27 14:09:41 +01:00
|
|
|
label: "Free transfer",
|
2024-07-09 18:18:26 +02:00
|
|
|
borderWidth: 2,
|
|
|
|
|
pointRadius: 0,
|
|
|
|
|
borderColor: color_by_name("highlight_color"),
|
|
|
|
|
backgroundColor: color_by_name("highlight_color"),
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-01-27 14:09:41 +01:00
|
|
|
label: "Premium transfer",
|
2024-07-09 18:18:26 +02:00
|
|
|
borderWidth: 2,
|
|
|
|
|
pointRadius: 0,
|
|
|
|
|
borderColor: color_by_name("danger_color"),
|
|
|
|
|
backgroundColor: color_by_name("danger_color"),
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
update_graphs(43200, 1440);
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
2024-07-11 13:30:46 +02:00
|
|
|
<div class="time_buttons">
|
2024-07-09 18:18:26 +02:00
|
|
|
<button
|
2025-10-13 16:05:50 +02:00
|
|
|
onclick={() => update_graphs(1440, 1)}
|
2024-07-11 13:30:46 +02:00
|
|
|
class:button_highlight={graph_timespan == 1440}
|
|
|
|
|
class="group_first">
|
|
|
|
|
Day
|
2024-07-09 18:18:26 +02:00
|
|
|
</button>
|
|
|
|
|
<button
|
2025-10-13 16:05:50 +02:00
|
|
|
onclick={() => update_graphs(10080, 60)}
|
2024-07-11 13:30:46 +02:00
|
|
|
class:button_highlight={graph_timespan == 10080}
|
|
|
|
|
class="group_middle">
|
|
|
|
|
Week
|
2024-07-09 18:18:26 +02:00
|
|
|
</button>
|
|
|
|
|
<button
|
2025-10-13 16:05:50 +02:00
|
|
|
onclick={() => update_graphs(43200, 1440)}
|
2024-07-11 13:30:46 +02:00
|
|
|
class:button_highlight={graph_timespan == 43200}
|
|
|
|
|
class="group_middle">
|
|
|
|
|
Month
|
2024-07-09 18:18:26 +02:00
|
|
|
</button>
|
|
|
|
|
<button
|
2025-10-13 16:05:50 +02:00
|
|
|
onclick={() => update_graphs(131400, 1440)}
|
2024-07-11 13:30:46 +02:00
|
|
|
class:button_highlight={graph_timespan == 131400}
|
|
|
|
|
class="group_middle">
|
|
|
|
|
Quarter
|
2024-07-09 18:18:26 +02:00
|
|
|
</button>
|
|
|
|
|
<button
|
2025-10-13 16:05:50 +02:00
|
|
|
onclick={() => update_graphs(525600, 1440)}
|
2024-07-11 13:30:46 +02:00
|
|
|
class:button_highlight={graph_timespan == 525600}
|
|
|
|
|
class="group_middle">
|
|
|
|
|
Year
|
2024-07-09 18:18:26 +02:00
|
|
|
</button>
|
|
|
|
|
<button
|
2025-10-13 16:05:50 +02:00
|
|
|
onclick={() => update_graphs(1051200, 1440)}
|
2024-07-11 13:30:46 +02:00
|
|
|
class:button_highlight={graph_timespan == 1051200}
|
|
|
|
|
class="group_last">
|
|
|
|
|
Two Years
|
2024-07-09 18:18:26 +02:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-07-11 13:30:46 +02:00
|
|
|
<Chart bind:this={graph_bandwidth} data_type="bytes" height={chart_height} ticks={false}/>
|
2024-07-09 18:18:26 +02:00
|
|
|
<div class="center">
|
|
|
|
|
{formatDataVolume(total_bandwidth, 3)} free downloads and
|
|
|
|
|
{formatDataVolume(total_transfer_paid, 3)} paid downloads
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-07-11 13:30:46 +02:00
|
|
|
<Chart bind:this={graph_views_downloads} data_type="number" height={chart_height} ticks={false}/>
|
2024-07-09 18:18:26 +02:00
|
|
|
<div class="center">
|
|
|
|
|
{formatThousands(total_views)} views and
|
|
|
|
|
{formatThousands(total_downloads)} downloads
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
.center {
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
2024-07-11 13:30:46 +02:00
|
|
|
.time_buttons {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 2px;
|
|
|
|
|
}
|
|
|
|
|
.time_buttons > button {
|
|
|
|
|
min-width: 3em;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
2024-07-09 18:18:26 +02:00
|
|
|
</style>
|