Clean up UI for small screens

This commit is contained in:
2024-03-15 13:58:27 +01:00
parent 6376e67cd7
commit 13c5889a56
5 changed files with 54 additions and 39 deletions

View File

@@ -30,7 +30,7 @@ let chart_interval = 0
let chart_timespans = [ let chart_timespans = [
{label: "Day (1m)", span: 1440, interval: 1}, {label: "Day (1m)", span: 1440, interval: 1},
{label: "Week (1h)", span: 10080, interval: 60}, {label: "Week (1h)", span: 10080, interval: 60},
{label: "Month (1h)", span: 43200, interval: 60}, {label: "Month (1d)", span: 43200, interval: 1440},
{label: "Quarter (1d)", span: 131400, interval: 1440}, {label: "Quarter (1d)", span: 131400, interval: 1440},
{label: "Year (1d)", span: 525600, interval: 1440}, {label: "Year (1d)", span: 525600, interval: 1440},
{label: "Two Years (1d)", span: 1051200, interval: 1440}, {label: "Two Years (1d)", span: 1051200, interval: 1440},
@@ -38,7 +38,6 @@ let chart_timespans = [
] ]
let total_downloads = 0 let total_downloads = 0
let total_transfer_free = 0
let total_transfer_paid = 0 let total_transfer_paid = 0
$: update_chart(state.base, chart_timespan, chart_interval) $: update_chart(state.base, chart_timespan, chart_interval)
@@ -81,19 +80,13 @@ let update_chart = async (base, timespan, interval) => {
chart.data().datasets = [ chart.data().datasets = [
{ {
label: "Unique downloads", label: "Unique Downloads",
borderWidth: 2, borderWidth: 2,
pointRadius: 0, pointRadius: 0,
borderColor: color_by_name("chart_1_color"), borderColor: color_by_name("chart_1_color"),
backgroundColor: color_by_name("chart_1_color"), backgroundColor: color_by_name("chart_1_color"),
}, { }, {
label: "Free downloads", label: "Total Downloads",
borderWidth: 2,
pointRadius: 0,
borderColor: color_by_name("chart_2_color"),
backgroundColor: color_by_name("chart_2_color"),
}, {
label: "Paid downloads",
borderWidth: 2, borderWidth: 2,
pointRadius: 0, pointRadius: 0,
borderColor: color_by_name("chart_3_color"), borderColor: color_by_name("chart_3_color"),
@@ -111,22 +104,16 @@ let update_chart = async (base, timespan, interval) => {
}); });
total_downloads = 0 total_downloads = 0
total_transfer_free = 0
total_transfer_paid = 0 total_transfer_paid = 0
resp.downloads.amounts.forEach(val => total_downloads += val); resp.downloads.amounts.forEach(val => total_downloads += val);
resp.transfer_free.amounts.forEach((val, idx) => {
resp.transfer_free.amounts[idx] = val / base.file_size;
total_transfer_free += val
});
resp.transfer_paid.amounts.forEach((val, idx) => { resp.transfer_paid.amounts.forEach((val, idx) => {
resp.transfer_paid.amounts[idx] = val / base.file_size; resp.transfer_paid.amounts[idx] = val / base.file_size;
total_transfer_paid += val total_transfer_paid += val
}); });
chart.data().labels = resp.downloads.timestamps chart.data().labels = resp.downloads.timestamps
chart.data().datasets[0].data = resp.downloads.amounts chart.data().datasets[0].data = resp.downloads.amounts
chart.data().datasets[1].data = resp.transfer_free.amounts chart.data().datasets[1].data = resp.transfer_paid.amounts
chart.data().datasets[2].data = resp.transfer_paid.amounts
chart.update() chart.update()
} catch (err) { } catch (err) {
console.error("Failed to get time series data:", err) console.error("Failed to get time series data:", err)
@@ -135,13 +122,27 @@ let update_chart = async (base, timespan, interval) => {
</script> </script>
<Modal bind:visible={visible} title="Details" width={(state.base.type === "file" ? 1000 : 750) + "px"}> <Modal bind:visible={visible} title="Details" width={(state.base.type === "file" ? 1000 : 750) + "px"}>
<h3 class="indent">Node details</h3>
<table style="width: 100%;"> <table style="width: 100%;">
<tr><td>Name</td><td>{state.base.name}</td></tr> <tr>
<tr><td>Path</td><td>{state.base.path}</td></tr> <td>Name</td>
<tr><td>Date created</td><td>{formatDate(state.base.created, true, true, true)}</td></tr> <td>{state.base.name}</td>
<tr><td>Date modified</td><td>{formatDate(state.base.modified, true, true, true)}</td></tr> </tr>
<tr><td>Mode</td><td>{state.base.mode_string}</td></tr> <tr>
<td>Path</td>
<td>{state.base.path}</td>
</tr>
<tr>
<td>Created</td>
<td>{formatDate(state.base.created, true, true, true)}</td>
</tr>
<tr>
<td>Modified</td>
<td>{formatDate(state.base.modified, true, true, true)}</td>
</tr>
<tr>
<td>Mode</td>
<td>{state.base.mode_string}</td>
</tr>
{#if state.base.id} {#if state.base.id}
<tr> <tr>
<td>Public ID</td> <td>Public ID</td>
@@ -149,22 +150,20 @@ let update_chart = async (base, timespan, interval) => {
</tr> </tr>
{/if} {/if}
{#if state.base.type === "file"} {#if state.base.type === "file"}
<tr><td>File type</td><td>{state.base.file_type}</td></tr> <tr>
<td>File type</td>
<td>{state.base.file_type}</td>
</tr>
<tr> <tr>
<td>File size</td> <td>File size</td>
<td>{formatDataVolume(state.base.file_size, 4)} ( {formatThousands(state.base.file_size)} B )</td> <td>{formatDataVolume(state.base.file_size, 4)} ( {formatThousands(state.base.file_size)} B )</td>
</tr> </tr>
<tr><td>Unique downloads</td><td>{formatThousands(total_downloads)}</td></tr>
<tr> <tr>
<td>Free bandwidth used</td> <td>Downloads</td>
<td> <td>{formatThousands(total_downloads)} (unique, counted once per IP)</td>
{formatDataVolume(total_transfer_free, 4)}
( {formatThousands(total_transfer_free)} B ),
{(total_transfer_free/state.base.file_size).toFixed(1)}x file size
</td>
</tr> </tr>
<tr> <tr>
<td>Premium bandwidth used</td> <td>Transfer used</td>
<td> <td>
{formatDataVolume(total_transfer_paid, 4)} {formatDataVolume(total_transfer_paid, 4)}
( {formatThousands(total_transfer_paid)} B ), ( {formatThousands(total_transfer_paid)} B ),

View File

@@ -130,7 +130,7 @@ onDestroy(close_socket)
line-height: 0.75em; line-height: 0.75em;
margin-top: 0.5em; margin-top: 0.5em;
} }
@media (max-width: 700px) { @media (max-width: 800px) {
.label { .label {
text-align: center; text-align: center;
padding-left: 0; padding-left: 0;

View File

@@ -236,7 +236,7 @@ const update_css = path => document.documentElement.style = branding_from_path(p
/* This max-width needs to be synced with the .toolbar max-width in /* This max-width needs to be synced with the .toolbar max-width in
Toolbar.svelte and the .label max-width in FileStats.svelte */ Toolbar.svelte and the .label max-width in FileStats.svelte */
@media (max-width: 700px) { @media (max-width: 800px) {
.viewer_area { .viewer_area {
flex-direction: column-reverse; flex-direction: column-reverse;
} }

View File

@@ -25,8 +25,8 @@ const click = e => {
<div class="wrapper"> <div class="wrapper">
<button bind:this={button} on:click={open} href="/user" class="button round" title="Menu"> <button bind:this={button} on:click={open} href="/user" class="button round" title="Menu">
<PixeldrainLogo style="height: 1.6em; width: 1.6em; margin: 0;"></PixeldrainLogo> <PixeldrainLogo style="height: 1.8em; width: 1.8em; margin: 0;"></PixeldrainLogo>
<span> <span class="button_username">
{window.user.username === "" ? "Pixeldrain" : window.user.username} {window.user.username === "" ? "Pixeldrain" : window.user.username}
</span> </span>
</button> </button>
@@ -37,6 +37,7 @@ const click = e => {
<dialog bind:this={dialog} on:click={click}> <dialog bind:this={dialog} on:click={click}>
<div class="menu"> <div class="menu">
{#if window.user.username !== ""} {#if window.user.username !== ""}
<div class="menu_username">{window.user.username}</div>
<div class="stats_table"> <div class="stats_table">
<div>Subscription</div> <div>Subscription</div>
<div>{window.user.subscription.name}</div> <div>{window.user.subscription.name}</div>
@@ -53,9 +54,13 @@ const click = e => {
</div> </div>
<Button link_href="/d/me" icon="folder" label="My Filesystem"/> <Button link_href="/d/me" icon="folder" label="My Filesystem"/>
<Button link_href="/user" icon="person" label="Profile"/> <Button link_href="/user" icon="person" label="Profile"/>
<Button link_href="/user/settings" icon="settings" label="Settings"/> <Button link_href="/user/settings" icon="settings" label="Account Settings"/>
<Button link_href="/user/subscription" icon="shopping_cart" label="Subscription"/> <Button link_href="/user/subscription" icon="shopping_cart" label="Subscription"/>
<Button link_href="/user/prepaid/transactions" icon="receipt" label="Transactions"/> <Button link_href="/user/prepaid/transactions" icon="receipt" label="Transactions"/>
{#if window.user.is_admin}
<Button link_href="/admin" icon="admin_panel_settings" label="Admin Panel"/>
{/if}
{:else} {:else}
<Button link_href="/" icon="home" label="Home"/> <Button link_href="/" icon="home" label="Home"/>
<Button link_href="/#pro" icon="star" label="Get Premium"/> <Button link_href="/#pro" icon="star" label="Get Premium"/>
@@ -94,10 +99,22 @@ dialog {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.menu_username {
text-align: center;
border-bottom: 2px solid var(--separator);
font-size: 1.1em;
}
.stats_table { .stats_table {
display: grid; display: grid;
grid-template-columns: auto auto; grid-template-columns: auto auto;
gap: 0.2em 1em; gap: 0.2em 1em;
margin: 3px; margin: 3px;
} }
/* Hide username on small screen */
@media(max-width: 800px) {
.button_username {
display: none;
}
}
</style> </style>

View File

@@ -138,7 +138,6 @@ let expand = e => {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(8em, 1fr)); grid-template-columns: repeat(auto-fit, minmax(8em, 1fr));
} }
.separator { .separator {
height: 2px; height: 2px;
width: 100%; width: 100%;
@@ -164,7 +163,7 @@ let expand = e => {
/* This max-width needs to be synced with the .viewer_area max-width in /* This max-width needs to be synced with the .viewer_area max-width in
Toolbar.svelte and the .label max-width in FileStats.svelte */ Toolbar.svelte and the .label max-width in FileStats.svelte */
@media (max-width: 700px) { @media (max-width: 800px) {
.toolbar { .toolbar {
overflow-y: hidden; overflow-y: hidden;
max-height: 2.5em; max-height: 2.5em;