Update IP ban management
This commit is contained in:
@@ -54,7 +54,7 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: system-ui, sans-serif;
|
font-family: system-ui, sans-serif;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
line-height: 1.8em;
|
line-height: 1.6em;
|
||||||
color: var(--text_color);
|
color: var(--text_color);
|
||||||
background-color: var(--layer_1_color);
|
background-color: var(--layer_1_color);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -241,7 +241,7 @@ section {
|
|||||||
/* Common elements */
|
/* Common elements */
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6, .light {
|
h1, h2, h3, h4, h5, h6, .light {
|
||||||
line-height: 1em;
|
line-height: 1;
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
font-family: 'Open Sans Light', sans-serif;
|
font-family: 'Open Sans Light', sans-serif;
|
||||||
@@ -311,7 +311,7 @@ table:not(.form) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr:not(.form) {border-bottom: 1px var(--layer_2_color_border) solid;}
|
tr:not(.form) {border-bottom: 1px var(--layer_2_color_border) solid;}
|
||||||
tr > td, tr > th {padding: 0.3em 0.6em;}
|
tr > td, tr > th {padding: 0.2em 0.5em;}
|
||||||
@media(max-width: 30em) {
|
@media(max-width: 30em) {
|
||||||
/* Forms will be stacked on small screens */
|
/* Forms will be stacked on small screens */
|
||||||
tr.form > td {
|
tr.form > td {
|
||||||
@@ -420,7 +420,7 @@ select {
|
|||||||
outline: 0;
|
outline: 0;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
line-height: 1em;
|
line-height: 1;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -475,7 +475,7 @@ select:disabled , select.disabled {
|
|||||||
button > *,
|
button > *,
|
||||||
.button > * {
|
.button > * {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
line-height: 1em;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round {
|
.round {
|
||||||
|
@@ -2,10 +2,12 @@
|
|||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { formatDate } from "../util/Formatting.svelte";
|
import { formatDate } from "../util/Formatting.svelte";
|
||||||
import Spinner from "../util/Spinner.svelte";
|
import Spinner from "../util/Spinner.svelte";
|
||||||
|
import Expandable from "../util/Expandable.svelte";
|
||||||
|
|
||||||
let loading = true
|
let loading = true
|
||||||
let rows = []
|
let rows = []
|
||||||
|
|
||||||
|
let expanded = false
|
||||||
let creating = false
|
let creating = false
|
||||||
let new_ban_address
|
let new_ban_address
|
||||||
let new_ban_reason = "unknown"
|
let new_ban_reason = "unknown"
|
||||||
@@ -18,9 +20,6 @@ const get_bans = async () => {
|
|||||||
throw new Error(resp.text());
|
throw new Error(resp.text());
|
||||||
}
|
}
|
||||||
rows = await resp.json()
|
rows = await resp.json()
|
||||||
rows.sort((a, b) => {
|
|
||||||
return b.ban_time.localeCompare(a.ban_time)
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert(err);
|
alert(err);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -87,8 +86,15 @@ onMount(get_bans);
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="toolbar" style="text-align: left;">
|
<div class="toolbar">
|
||||||
<div class="toolbar_spacer"></div>
|
<div class="toolbar_spacer"></div>
|
||||||
|
<button class:button_highlight={expanded} on:click={() => {expanded = !expanded}}>
|
||||||
|
{#if expanded}
|
||||||
|
<i class="icon">unfold_less</i> Collapse all
|
||||||
|
{:else}
|
||||||
|
<i class="icon">unfold_more</i> Expand all
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
<button class:button_highlight={creating} on:click={() => {creating = !creating}}>
|
<button class:button_highlight={creating} on:click={() => {creating = !creating}}>
|
||||||
<i class="icon">create</i> Add IP ban
|
<i class="icon">create</i> Add IP ban
|
||||||
</button>
|
</button>
|
||||||
@@ -134,37 +140,51 @@ onMount(get_bans);
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#each rows as row (row.address)}
|
||||||
|
<Expandable expanded={expanded}>
|
||||||
|
<div slot="header" class="header">
|
||||||
|
<div class="title">{row.address}</div>
|
||||||
|
<div class="stats">
|
||||||
|
Offences<br/>
|
||||||
|
{row.offences.length}
|
||||||
|
</div>
|
||||||
|
<div class="stats">
|
||||||
|
Date<br/>
|
||||||
|
{formatDate(row.offences[0].ban_time, false, false, false)}
|
||||||
|
</div>
|
||||||
|
<button on:click|preventDefault={() => {delete_ban(row.address)}} class="button button_red" style="align-self: center;">
|
||||||
|
<i class="icon">delete</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Reason</td>
|
||||||
|
<td>Reporter</td>
|
||||||
|
<td>Ban time</td>
|
||||||
|
<td>Expire time</td>
|
||||||
|
<td>File</td>
|
||||||
|
</tr>
|
||||||
|
{#each row.offences as offence (offence.ban_time)}
|
||||||
|
<tr>
|
||||||
|
<td>{offence.reason}</td>
|
||||||
|
<td>{offence.reporter}</td>
|
||||||
|
<td>{formatDate(offence.ban_time, true, true, false)}</td>
|
||||||
|
<td>{formatDate(offence.expire_time, true, true, false)}</td>
|
||||||
|
<td>
|
||||||
|
{#if offence.file_public_id}
|
||||||
|
<a href="/u/{offence.file_public_id}" target="_blank">
|
||||||
|
{offence.file_name}
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</table>
|
||||||
|
</Expandable>
|
||||||
|
{/each}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<div class="table_scroll">
|
|
||||||
<table style="text-align: left;">
|
|
||||||
<tr>
|
|
||||||
<td>Address</td>
|
|
||||||
<td>Reason</td>
|
|
||||||
<td>Ban time</td>
|
|
||||||
<td>Expire time</td>
|
|
||||||
<td>Offences</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{#each rows as row (row.address)}
|
|
||||||
<tr>
|
|
||||||
<td>{row.address}</td>
|
|
||||||
<td>{row.reason}</td>
|
|
||||||
<td>{formatDate(row.ban_time, true, true, false)}</td>
|
|
||||||
<td>{formatDate(row.expire_time, true, true, false)}</td>
|
|
||||||
<td>{row.offences}</td>
|
|
||||||
<td>
|
|
||||||
<button on:click|preventDefault={() => {delete_ban(row.address)}} class="button button_red round">
|
|
||||||
<i class="icon">delete</i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -178,7 +198,28 @@ onMount(get_bans);
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
.toolbar > * { flex: 0 0 auto; }
|
.toolbar > * { flex: 0 0 auto; }
|
||||||
.toolbar_spacer { flex: 1 1 auto; }
|
.toolbar_spacer { flex: 1 1 auto; }
|
||||||
|
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
line-height: 1.2em;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
align-self: center;
|
||||||
|
word-break: break-all;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
.stats {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: 3px 4px;
|
||||||
|
border-left: 1px solid var(--layer_3_color_border);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -13,14 +13,11 @@ onMount(() => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Math.floor(Math.random()*3)) {
|
switch (Math.floor(Math.random()*2)) {
|
||||||
case 0:
|
case 0:
|
||||||
set_ad_type("aads")
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
set_ad_type("ads.plus")
|
set_ad_type("ads.plus")
|
||||||
break
|
break
|
||||||
case 2:
|
case 1:
|
||||||
set_ad_type("valueimpression")
|
set_ad_type("valueimpression")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@@ -31,14 +31,11 @@ onMount(() => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Math.floor(Math.random()*3)) {
|
switch (Math.floor(Math.random()*2)) {
|
||||||
case 0:
|
case 0:
|
||||||
set_ad_type("ads.plus")
|
set_ad_type("ads.plus")
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
set_ad_type("aads")
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
set_ad_type("valueimpression")
|
set_ad_type("valueimpression")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@@ -77,9 +77,11 @@ const start_upload = () => {
|
|||||||
for (let i = 0; i < upload_queue.length && active_uploads < 3; i++) {
|
for (let i = 0; i < upload_queue.length && active_uploads < 3; i++) {
|
||||||
if (upload_queue[i].status == "queued") {
|
if (upload_queue[i].status == "queued") {
|
||||||
active_uploads++
|
active_uploads++
|
||||||
upload_queue[i].status = "uploading"
|
|
||||||
upload_queue[i].component.start()
|
upload_queue[i].component.start()
|
||||||
} else if (upload_queue[i].status == "finished") {
|
} else if (
|
||||||
|
upload_queue[i].status == "finished" ||
|
||||||
|
upload_queue[i].status == "error"
|
||||||
|
) {
|
||||||
finished_count++
|
finished_count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +206,7 @@ const uploads_finished = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_list(title, anonymous) {
|
async function create_list(title, anonymous) {
|
||||||
let files = upload_queue.reduce(
|
let files = upload_queue.reduce(
|
||||||
(acc, curr) => {
|
(acc, curr) => {
|
||||||
if (curr.status === "finished") {
|
if (curr.status === "finished") {
|
||||||
@@ -215,7 +217,7 @@ function create_list(title, anonymous) {
|
|||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
return fetch(
|
const resp = await fetch(
|
||||||
window.api_endpoint+"/list",
|
window.api_endpoint+"/list",
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -226,12 +228,11 @@ function create_list(title, anonymous) {
|
|||||||
"files": files
|
"files": files
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
).then(resp => {
|
)
|
||||||
if (!resp.ok) {
|
if(!resp.ok) {
|
||||||
return Promise.reject("HTTP error: " + resp.status)
|
return Promise.reject("HTTP error: "+resp.status)
|
||||||
}
|
}
|
||||||
return resp.json()
|
return await resp.json()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const copy_link = () => {
|
const copy_link = () => {
|
||||||
|
@@ -78,8 +78,11 @@ const on_failure = (status, message) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const start = () => {
|
export const start = () => {
|
||||||
|
job.status = "uploading"
|
||||||
|
|
||||||
|
// Check the file size limit. For free accounts it's 10 GB
|
||||||
if (window.user.subscription.file_size_limit === 0) {
|
if (window.user.subscription.file_size_limit === 0) {
|
||||||
window.user.subscription.file_size_limit = 5e9
|
window.user.subscription.file_size_limit = 10e9
|
||||||
}
|
}
|
||||||
if (job.total_size > window.user.subscription.file_size_limit) {
|
if (job.total_size > window.user.subscription.file_size_limit) {
|
||||||
on_failure(
|
on_failure(
|
||||||
|
Reference in New Issue
Block a user