Files
fnx_web/svelte/src/user_home/SharingSettings.svelte

161 lines
4.2 KiB
Svelte
Raw Normal View History

2026-08-03 23:31:43 +02:00
<script lang="ts">
import { onMount } from "svelte";
import { formatDataVolume } from "util/Formatting";
import ProgressBar from "util/ProgressBar.svelte";
import { loading_run } from "lib/Loading";
import { get_endpoint, put_user } from 'lib/NovaAPI';
import SuccessMessage from 'util/SuccessMessage.svelte';
import { user } from "lib/UserStore";
let success_message: SuccessMessage = $state()
let transfer_cap = $state($user === null ? 0 : $user.monthly_transfer_cap / 1e12)
const update_user = async (e: SubmitEvent) => {
if (e !== null) {
e.preventDefault()
}
loading_run(async () => {
try {
await put_user({
transfer_cap: transfer_cap*1e12,
embed_domains: embed_domains.join(" "),
})
success_message.set(true, "Sharing settings updated")
} catch (err) {
success_message.set(false, "Failed to update user: "+err)
}
})
}
let transfer_used = $state(0)
let load_transfer_used = () => {
let today = new Date()
let start = new Date()
start.setDate(start.getDate() - 30)
fetch(
get_endpoint() + "/user/time_series/egress" +
"?start=" + start.toISOString() +
"&end=" + today.toISOString() +
"&interval=60"
).then(resp => {
if (!resp.ok) { return Promise.reject("Error: " + resp.status); }
return resp.json();
}).then(resp => {
transfer_used = resp.amounts.reduce((acc, cur) => { return acc + cur }, 0)
}).catch(e => {
console.error("Error requesting time series: " + e);
})
}
// Embedding settings
let embed_domains: string[] = $state($user === null ? [] : $user.embed_domains.split(" "))
let new_domain: string = $state("")
const add_domain = (e: SubmitEvent) => {
e.preventDefault()
console.debug("Adding domain", new_domain)
embed_domains.push(new_domain)
embed_domains = embed_domains
new_domain = ""
update_user(e)
}
const del_domain = (index: number) => {
embed_domains.splice(index, 1)
embed_domains = embed_domains
update_user(null)
}
onMount(async () => {
load_transfer_used()
})
</script>
<section>
<SuccessMessage bind:this={success_message}/>
<h2>Bill shock limit</h2>
<p>
Billshock limit in terabytes per month (1 TB = 1000 GB). Set to 0 to
disable.
</p>
<form onsubmit={update_user} class="billshock_container">
<input type="number" bind:value={transfer_cap} step="0.1" min="0" style="width: 5em;"/>
<div style="margin: 0.5em;">TB</div>
<button type="submit">
<i class="icon">save</i> Save
</button>
</form>
<p>
Bandwidth used in the last 30 days: {formatDataVolume(transfer_used, 3)},
new limit: {formatDataVolume(transfer_cap*1e12, 3)}
</p>
<ProgressBar used={transfer_used} total={transfer_cap*1e12}></ProgressBar>
<p>
The billshock limit limits how much bandwidth your account can use in a
30 day window. When this limit is reached hotlinking will be disabled
and you will no longer be charged for bandwidth usage. This is mostly
useful for the Prepaid subscription, but it works for Patreon plans too.
Set to 0 to disable the limit.
</p>
<h2>Embedding controls</h2>
<p>
Here you can control which websites are allowed to embed your files in
their web pages. If a website that is not on this list tries to embed
one of your files the request will be blocked. This applies to both
hotlink and iframe embeds. If the list is empty, all domains are allowed
to embed your files.
</p>
<div class="highlight_border">
<form onsubmit={add_domain}>
<div class="form_row">
<span>Add domain name</span>
<input class="grow" bind:value={new_domain} type="text"/>
<button class="shrink" type="submit"><i class="icon">add</i> Add</button>
</div>
</form>
<hr/>
{#if embed_domains.length === 0}
<span>
No domains specified. All websites are allowed to embed your files
</span>
{/if}
{#each embed_domains as domain, index}
<div class="form_row">
<button class="shrink" type="button" onclick={() => del_domain(index)}>
<i class="icon">delete</i>
</button>
<div>{domain}</div>
</div>
{/each}
</div>
</section>
<style>
.billshock_container {
display: flex;
flex-direction: row;
align-items: center;
}
.highlight_border {
text-align: initial;
}
.form_row {
display: inline-flex;
flex-direction: row;
width: 100%;
align-items: center;
gap: 0.5em;
}
.grow {
flex: 1 1 auto;
}
.shrink {
flex: 0 0 auto;
}
</style>