UI overhaul, import fixes, fix user store
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import CopyButton from "layout/CopyButton.svelte";
|
||||
import Form from "util/Form.svelte";
|
||||
import Form, { type FormConfig } from "util/Form.svelte";
|
||||
import Button from "layout/Button.svelte";
|
||||
import OtpSetup from "./OTPSetup.svelte";
|
||||
import { put_user } from "lib/NovaAPI";
|
||||
import { get_endpoint, put_user } from "lib/NovaAPI";
|
||||
import { user } from "lib/UserStore";
|
||||
|
||||
let affiliate_link = window.location.protocol+"//"+window.location.host + "?ref=" + encodeURIComponent(window.user.username)
|
||||
let affiliate_link = $derived(
|
||||
window.location.protocol+"//"+window.location.host +
|
||||
"?ref=" + encodeURIComponent($user.username)
|
||||
)
|
||||
let affiliate_deny = $state(false)
|
||||
onMount(() => {
|
||||
affiliate_deny = localStorage.getItem("affiliate_deny") === "1"
|
||||
@@ -16,14 +20,13 @@ const enable_affiliate_prompt = () => {
|
||||
localStorage.removeItem("affiliate_deny")
|
||||
}
|
||||
|
||||
let account_settings = {
|
||||
name: "account_settings",
|
||||
let account_settings: FormConfig = $derived({
|
||||
fields: [
|
||||
{
|
||||
name: "email",
|
||||
label: "E-mail address",
|
||||
type: "email",
|
||||
default_value: window.user.email,
|
||||
default_value: $user.email,
|
||||
description: `We will send an e-mail to the new address to verify
|
||||
that it's real. The address will be saved once the link in the
|
||||
message is clicked. If the e-mail doesn't arrive right away
|
||||
@@ -48,7 +51,7 @@ let account_settings = {
|
||||
name: "username",
|
||||
label: "Name",
|
||||
type: "username",
|
||||
default_value: window.user.username,
|
||||
default_value: $user.username,
|
||||
description: `Changing your username also changes the name used to
|
||||
log in. If you forget your username you can still log in using
|
||||
your e-mail address if you have one configured`,
|
||||
@@ -57,17 +60,17 @@ let account_settings = {
|
||||
name: "checkout_country",
|
||||
label: "Country code used at checkout",
|
||||
type: "text",
|
||||
default_value: window.user.checkout_country,
|
||||
default_value: $user.checkout_country,
|
||||
}, {
|
||||
name: "checkout_provider",
|
||||
label: "Default payment provider used at checkout",
|
||||
type: "text",
|
||||
default_value: window.user.checkout_provider,
|
||||
default_value: $user.checkout_provider,
|
||||
}, {
|
||||
name: "checkout_name",
|
||||
label: "Full name used at checkout",
|
||||
type: "text",
|
||||
default_value: window.user.checkout_name,
|
||||
default_value: $user.checkout_name,
|
||||
separator: true,
|
||||
},
|
||||
],
|
||||
@@ -98,21 +101,20 @@ let account_settings = {
|
||||
checkout_name: fields.checkout_name,
|
||||
})
|
||||
} catch (err) {
|
||||
return {error_json: err}
|
||||
return {success: false, error_json: err}
|
||||
}
|
||||
|
||||
return {success: true, message: "Success! Your changes have been saved"}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const affiliate_settings = {
|
||||
name: "affiliate_settings",
|
||||
let affiliate_settings: FormConfig = $derived({
|
||||
fields: [
|
||||
{
|
||||
name: "affiliate_user_name",
|
||||
label: "Affiliate user name",
|
||||
type: "text",
|
||||
default_value: window.user.affiliate_user_name,
|
||||
default_value: $user.affiliate_user_name,
|
||||
description: `The affiliate user name can be the name of a
|
||||
Nova account you wish to support with your subscription.
|
||||
The account will receive a fee of €0.50 for every month that
|
||||
@@ -125,16 +127,15 @@ const affiliate_settings = {
|
||||
const form = new FormData()
|
||||
form.append("affiliate_user_name", fields.affiliate_user_name)
|
||||
|
||||
const resp = await fetch(window.api_endpoint+"/user", { method: "PUT", body: form });
|
||||
const resp = await fetch(get_endpoint()+"/user", { method: "PUT", body: form });
|
||||
if(resp.status >= 400) {
|
||||
return {error_json: await resp.json()}
|
||||
return {success: false, error_json: await resp.json()}
|
||||
}
|
||||
return {success: true, message: "Success! Your changes have been saved"}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
let delete_account = {
|
||||
name: "delete_account",
|
||||
let delete_account: FormConfig = {
|
||||
fields: [
|
||||
{
|
||||
name: "description",
|
||||
@@ -169,13 +170,13 @@ let delete_account = {
|
||||
submit_label: `<i class="icon">delete</i> Delete`,
|
||||
on_submit: async fields => {
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user",
|
||||
get_endpoint()+"/user",
|
||||
{ method: "DELETE" }
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
return {error_json: await resp.json()}
|
||||
return {success: false, error_json: await resp.json()}
|
||||
}
|
||||
setTimeout(() => { window.location = "/" }, 6000)
|
||||
setTimeout(() => { window.location.assign("/") }, 6000)
|
||||
return {success: true, message: "Success! Your account has been scheduled for deletion in 7 days"}
|
||||
},
|
||||
}
|
||||
@@ -201,7 +202,7 @@ let delete_account = {
|
||||
<a href="{affiliate_link}">{affiliate_link}</a>
|
||||
<CopyButton small_icon text={affiliate_link}/>. Share this link
|
||||
with premium Nova users to gain commissions. You can use
|
||||
the "?ref={encodeURIComponent(window.user.username)}" referral
|
||||
the "?ref={encodeURIComponent($user.username)}" referral
|
||||
code on download pages too. For a detailed description of the
|
||||
affiliate program please check out the <a
|
||||
href="/about#toc_12">Q&A page</a>.
|
||||
|
||||
@@ -6,31 +6,22 @@ import { formatDataVolume } from "util/Formatting";
|
||||
import ProgressBar from "util/ProgressBar.svelte";
|
||||
import SuccessMessage from "util/SuccessMessage.svelte";
|
||||
import { loading_finish, loading_start } from "lib/Loading";
|
||||
import { put_user } from 'lib/NovaAPI';
|
||||
import { user } from 'lib/UserStore';
|
||||
|
||||
let success_message = $state()
|
||||
let hotlinking = $state(window.user.hotlinking_enabled)
|
||||
let transfer_cap = $state(window.user.monthly_transfer_cap / 1e12)
|
||||
let skip_viewer = $state(window.user.skip_file_viewer)
|
||||
let hotlinking = $state($user === null ? false : $user.hotlinking_enabled)
|
||||
let transfer_cap = $state($user === null ? 0 : $user.monthly_transfer_cap / 1e12)
|
||||
let skip_viewer = $state($user === null ? false : $user.skip_file_viewer)
|
||||
|
||||
const update = async () => {
|
||||
const form = new FormData()
|
||||
form.append("hotlinking_enabled", hotlinking)
|
||||
form.append("transfer_cap", transfer_cap*1e12)
|
||||
form.append("skip_file_viewer", skip_viewer)
|
||||
|
||||
loading_start()
|
||||
try {
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user",
|
||||
{ method: "PUT", body: form },
|
||||
)
|
||||
if(resp.status >= 400) {
|
||||
let json = await resp.json()
|
||||
throw json.message
|
||||
}
|
||||
|
||||
window.user.hotlinking_enabled = hotlinking
|
||||
window.user.monthly_transfer_cap = transfer_cap*1e12
|
||||
await put_user({
|
||||
hotlinking_enabled: hotlinking,
|
||||
transfer_cap: transfer_cap*1e12,
|
||||
skip_file_viewer: skip_viewer,
|
||||
})
|
||||
|
||||
success_message.set(true, "Sharing settings updated")
|
||||
} catch (err) {
|
||||
|
||||
@@ -1,48 +1,18 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import Checkout from "layout/checkout/Checkout.svelte";
|
||||
import { loading_finish, loading_start } from "lib/Loading";
|
||||
import { loading_finish, loading_start } from "lib/Loading";
|
||||
import { get_endpoint } from "lib/NovaAPI";
|
||||
import { user } from "lib/UserStore";
|
||||
import { onMount } from "svelte";
|
||||
import Euro from "util/Euro.svelte";
|
||||
import { formatDate } from "util/Formatting";
|
||||
|
||||
let credit_amount = 10
|
||||
|
||||
const checkout = async (network = "", amount = 0, country = "") => {
|
||||
if (amount < 10) {
|
||||
alert("Amount needs to be at least €10")
|
||||
return
|
||||
}
|
||||
|
||||
const form = new FormData()
|
||||
form.set("amount", amount*1e6)
|
||||
form.set("network", network)
|
||||
form.set("country", country)
|
||||
|
||||
loading_start()
|
||||
try {
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user/invoice",
|
||||
{method: "POST", body: form},
|
||||
)
|
||||
if(resp.status >= 400) {
|
||||
let json = await resp.json()
|
||||
throw json.message
|
||||
}
|
||||
|
||||
window.location = (await resp.json()).checkout_url
|
||||
} catch (err) {
|
||||
alert(err)
|
||||
} finally {
|
||||
loading_finish()
|
||||
}
|
||||
}
|
||||
|
||||
let invoices = $state([])
|
||||
let unpaid_invoice = $state(0)
|
||||
const load_invoices = async () => {
|
||||
loading_start()
|
||||
try {
|
||||
const resp = await fetch(window.api_endpoint+"/user/invoice")
|
||||
const resp = await fetch(get_endpoint()+"/user/invoice")
|
||||
if(resp.status >= 400) {
|
||||
throw new Error((await resp.json()).message)
|
||||
}
|
||||
@@ -81,7 +51,7 @@ onMount(() => {
|
||||
Prepaid there are no limits. You pay for what you use, at a rate of €4
|
||||
per TB per month for storage and €1 per TB for data transfer. Your
|
||||
current account balance is <Euro
|
||||
amount={window.user.balance_micro_eur}/>
|
||||
amount={$user === null ? 0 : $user.balance_micro_eur}/>
|
||||
</p>
|
||||
|
||||
{#if unpaid_invoice > 1}
|
||||
|
||||
@@ -1,53 +1,65 @@
|
||||
<script>
|
||||
import { preventDefault } from 'svelte/legacy';
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import Persistence from "icons/Persistence.svelte";
|
||||
import SuccessMessage from "util/SuccessMessage.svelte";
|
||||
import { loading_finish, loading_start } from "lib/Loading";
|
||||
import { get_endpoint, get_user, type User } from "lib/NovaAPI";
|
||||
import { loading_run } from "lib/Loading";
|
||||
|
||||
let success_message = $state()
|
||||
let success_message: SuccessMessage
|
||||
|
||||
// Embedding settings
|
||||
let embed_domains = $state("")
|
||||
let embed_domains: string[] = []
|
||||
|
||||
const save_embed = async () => {
|
||||
const form = new FormData()
|
||||
form.append("embed_domains", embed_domains)
|
||||
await loading_run(async () => {
|
||||
const domain_list = embed_domains.join(" ")
|
||||
const form = new FormData()
|
||||
form.append("embed_domains", domain_list)
|
||||
|
||||
loading_start()
|
||||
try {
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user",
|
||||
{ method: "PUT", body: form }
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
let json = await resp.json()
|
||||
console.debug(json)
|
||||
throw json.message
|
||||
try {
|
||||
const resp = await fetch(
|
||||
get_endpoint()+"/user",
|
||||
{ method: "PUT", body: form }
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
let json = await resp.json()
|
||||
console.debug(json)
|
||||
throw json.message
|
||||
}
|
||||
|
||||
success_message.set(true, "Changes saved")
|
||||
} catch(err) {
|
||||
success_message.set(false, err)
|
||||
}
|
||||
|
||||
success_message.set(true, "Changes saved")
|
||||
} catch(err) {
|
||||
success_message.set(false, err)
|
||||
} finally {
|
||||
loading_finish()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
embed_domains = window.user.file_embed_domains
|
||||
let new_domain: string = ""
|
||||
const add = () => {
|
||||
console.debug("Adding domain", new_domain)
|
||||
embed_domains.push(new_domain)
|
||||
embed_domains = embed_domains
|
||||
new_domain = ""
|
||||
save_embed()
|
||||
}
|
||||
const remove = (index: number) => {
|
||||
embed_domains.splice(index, 1)
|
||||
embed_domains = embed_domains
|
||||
save_embed()
|
||||
}
|
||||
|
||||
let user: User
|
||||
onMount(async () => {
|
||||
user = await get_user()
|
||||
if (user.file_embed_domains !== "") {
|
||||
embed_domains = user.file_embed_domains.split(" ")
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<h2><Persistence/>Embedding controls</h2>
|
||||
<h2>Embedding controls</h2>
|
||||
<SuccessMessage bind:this={success_message}></SuccessMessage>
|
||||
{#if !window.user.subscription.file_viewer_branding}
|
||||
<div class="highlight_yellow">
|
||||
Sharing settings are not available for your account. Subscribe to
|
||||
the Persistence plan or higher to enable these features.
|
||||
</div>
|
||||
{:else if !window.user.hotlinking_enabled}
|
||||
{#if user !== undefined && !user.hotlinking_enabled}
|
||||
<div class="highlight_yellow">
|
||||
To use embedding restrictions hotlinking needs to be enabled.
|
||||
Enable hotlinking on the
|
||||
@@ -57,25 +69,45 @@ onMount(() => {
|
||||
<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.
|
||||
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>
|
||||
<p>
|
||||
The list should be formatted as a list of domain names separated by a
|
||||
space. Like this: 'nova.storage google.com twitter.com'
|
||||
</p>
|
||||
Domain names:<br/>
|
||||
<form class="form_row" onsubmit={preventDefault(save_embed)}>
|
||||
<input class="grow" bind:value={embed_domains} type="text"/>
|
||||
<button class="shrink" action="submit"><i class="icon">save</i> Save</button>
|
||||
</form>
|
||||
<div class="highlight_border">
|
||||
<form on:submit|preventDefault={() => add()}>
|
||||
<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" on:click={() => remove(index)}>
|
||||
<i class="icon">delete</i>
|
||||
</button>
|
||||
<div>{domain}</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.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;
|
||||
|
||||
@@ -34,7 +34,7 @@ let frac = $derived(used / total)
|
||||
files have a daily download limit and hotlinking is disabled.
|
||||
</p>
|
||||
|
||||
{#if $user.monthly_transfer_cap > 0}
|
||||
{#if $user !== null && $user.monthly_transfer_cap > 0}
|
||||
<p>
|
||||
You have a billshock limit configured. <a
|
||||
href="/user/sharing/bandwidth">increase or disable the limit</a> to
|
||||
@@ -56,7 +56,7 @@ let frac = $derived(used / total)
|
||||
and hotlinking is disabled.
|
||||
</p>
|
||||
|
||||
{#if $user.monthly_transfer_cap > 0}
|
||||
{#if $user !== null && $user.monthly_transfer_cap > 0}
|
||||
<p>
|
||||
You have a billshock limit configured. <a
|
||||
href="/user/sharing/bandwidth">increase or disable the limit</a> to
|
||||
|
||||
@@ -8,7 +8,7 @@ let { total = 0, used = 0, disable_warnings = false }: {
|
||||
disable_warnings?: boolean;
|
||||
} = $props();
|
||||
|
||||
let frac = $derived(used / total)
|
||||
let frac = $derived(total <= 0 ? 0 : used / total)
|
||||
</script>
|
||||
|
||||
<ProgressBar total={total} used={used}></ProgressBar>
|
||||
|
||||
@@ -6,8 +6,8 @@ import { loading_finish, loading_start } from "lib/Loading";
|
||||
import { user } from "lib/UserStore";
|
||||
import { put_user } from "lib/NovaAPI";
|
||||
|
||||
let subscription = $state($user.subscription.id)
|
||||
let subscription_type = $state($user.subscription.type)
|
||||
let subscription: string = $state($user === null ? "" : $user.subscription.id)
|
||||
let subscription_type: string = $state($user === null ? "" : $user.subscription.type)
|
||||
let success_message: SuccessMessage = $state()
|
||||
|
||||
const update = async (plan: string) => {
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
<script>
|
||||
import Button from "layout/Button.svelte";
|
||||
<script lang="ts">
|
||||
import { logout_user } from "lib/NovaAPI";
|
||||
import { user } from "lib/UserStore";
|
||||
</script>
|
||||
<ul>
|
||||
<li>Username: {window.user.username}</li>
|
||||
{#if window.user.email === ""}
|
||||
<li class="highlight_blue" style="text-align: initial;">
|
||||
No e-mail address configured. You will not be able to recover your
|
||||
account if you lose your password. Set an e-mail address on the <a
|
||||
href="/user/settings">Settings</a> page.
|
||||
</li>
|
||||
{:else}
|
||||
|
||||
{#if $user !== null}
|
||||
<ul>
|
||||
<li>Username: {$user.username}</li>
|
||||
{#if $user.email === ""}
|
||||
<li class="highlight_blue" style="text-align: initial;">
|
||||
No e-mail address configured. You will not be able to recover your
|
||||
account if you lose your password. Set an e-mail address on the <a
|
||||
href="/user/settings">Settings</a> page.
|
||||
</li>
|
||||
{:else}
|
||||
<li>
|
||||
E-mail address: {$user.email}
|
||||
</li>
|
||||
{/if}
|
||||
<li>
|
||||
E-mail address: {window.user.email}
|
||||
<i class="icon">settings</i>
|
||||
<a href="/user/settings">Account settings</a>
|
||||
</li>
|
||||
{/if}
|
||||
<li>
|
||||
<i class="icon">settings</i>
|
||||
<a href="/user/settings">Account settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
{/if}
|
||||
|
||||
<h3>Quick navigation</h3>
|
||||
|
||||
<div class="button_row">
|
||||
{#if window.user.subscription.filesystem_access}
|
||||
<a href="/d/me" class="button">
|
||||
<i class="icon">folder</i>
|
||||
Filesystem
|
||||
</a>
|
||||
{/if}
|
||||
<a href="/d/me" class="button">
|
||||
<i class="icon">folder</i>
|
||||
Filesystem
|
||||
</a>
|
||||
<button onclick={()=> logout_user("/")}>
|
||||
<i class="icon">logout</i>
|
||||
Log out
|
||||
|
||||
@@ -1,59 +1,69 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { user } from "lib/UserStore";
|
||||
import Euro from "util/Euro.svelte";
|
||||
import { formatDataVolume } from "util/Formatting";
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Supporter level: {window.user.subscription.name}<br/>
|
||||
<i class="icon">shopping_cart</i>
|
||||
<a href="/user/subscription">Manage subscriptions</a><br/>
|
||||
<i class="icon">add_link</i>
|
||||
<a href="/api/patreon_auth/start">Link Patreon subscription</a>
|
||||
</li>
|
||||
|
||||
{#if window.user.balance_micro_eur !== 0}
|
||||
{#if $user !== null}
|
||||
<ul>
|
||||
<li>
|
||||
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro><br/>
|
||||
Supporter level: {$user.subscription.name}<br/>
|
||||
<i class="icon">shopping_cart</i>
|
||||
<a href="/user/subscription">Manage subscriptions</a><br/>
|
||||
<i class="icon">add_link</i>
|
||||
<a href="/api/patreon_auth/start">Link Patreon subscription</a>
|
||||
</li>
|
||||
|
||||
<i class="icon">account_balance_wallet</i>
|
||||
<a href="/user/prepaid/deposit">Deposit credit</a><br/>
|
||||
{#if $user.balance_micro_eur !== 0}
|
||||
<li>
|
||||
Current account balance: <Euro amount={$user.balance_micro_eur}></Euro><br/>
|
||||
|
||||
<i class="icon">receipt</i>
|
||||
<a href="/user/prepaid/transactions">Transaction log</a>
|
||||
<i class="icon">account_balance_wallet</i>
|
||||
<a href="/user/prepaid/deposit">Deposit credit</a><br/>
|
||||
|
||||
{#if window.user.balance_micro_eur > 0 && window.user.subscription.id === ""}
|
||||
<br/>
|
||||
You have account credit but no active subscription. Activate
|
||||
a subscription on the <a href="/user/subscription">subscriptions page</a>
|
||||
<i class="icon">receipt</i>
|
||||
<a href="/user/prepaid/transactions">Transaction log</a>
|
||||
|
||||
{#if $user.balance_micro_eur > 0 && $user.subscription.id === ""}
|
||||
<br/>
|
||||
You have account credit but no active subscription. Activate
|
||||
a subscription on the <a href="/user/subscription">subscriptions page</a>
|
||||
{/if}
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
<li>
|
||||
Max file size: {formatDataVolume($user.subscription.file_size_limit, 3)}
|
||||
</li>
|
||||
<li>
|
||||
{#if $user.subscription.storage_limit > 0}
|
||||
Storage limit: {formatDataVolume($user.subscription.storage_limit, 3)}
|
||||
{:else}
|
||||
No storage limit
|
||||
{/if}
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
<li>
|
||||
Max file size: {formatDataVolume(window.user.subscription.file_size_limit, 3)}
|
||||
</li>
|
||||
<li>
|
||||
{#if window.user.subscription.storage_space > 0}
|
||||
Storage limit: {formatDataVolume(window.user.subscription.storage_space, 3)}
|
||||
{:else}
|
||||
No storage limit
|
||||
{/if}
|
||||
</li>
|
||||
<li>
|
||||
{#if window.user.subscription.monthly_transfer_cap > 0}
|
||||
Data transfer limit: {formatDataVolume(window.user.subscription.monthly_transfer_cap, 3)}
|
||||
{:else}
|
||||
No data transfer limit
|
||||
{/if}
|
||||
</li>
|
||||
{#if window.user.subscription.id !== ""}
|
||||
<li>
|
||||
Support: For questions related to your account you can send a
|
||||
message to support@nova.storage
|
||||
{#if $user.subscription.monthly_transfer_cap > 0}
|
||||
Data transfer limit: {formatDataVolume($user.subscription.monthly_transfer_cap, 3)}
|
||||
{:else}
|
||||
No data transfer limit
|
||||
{/if}
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<li>
|
||||
{#if $user.subscription.file_sharing === true}
|
||||
File sharing enabled
|
||||
{:else}
|
||||
File sharing not allowed
|
||||
{/if}
|
||||
</li>
|
||||
{#if $user.subscription.id !== ""}
|
||||
<li>
|
||||
Support: For questions related to your account you can send a
|
||||
message to support@nova.storage
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
ul {
|
||||
|
||||
@@ -42,7 +42,7 @@ onMount(async () => {
|
||||
transfer_cap = -1
|
||||
}
|
||||
|
||||
storage_limit = user.subscription.storage_space
|
||||
storage_limit = user.subscription.storage_limit
|
||||
|
||||
load_direct_bw()
|
||||
})
|
||||
|
||||
@@ -127,7 +127,7 @@ onMount(() => {
|
||||
{#each cards as card, i (card.id)}
|
||||
<div
|
||||
animate:flip={{duration: 250}}
|
||||
class="card"
|
||||
class="card bubble"
|
||||
class:size_1={card.size === 1}
|
||||
class:size_2={card.size === 2}
|
||||
class:size_3={card.size === 3}
|
||||
@@ -175,17 +175,15 @@ onMount(() => {
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding: 8px 0;
|
||||
margin: 0 8px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.card {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 100%;
|
||||
background: var(--body_background);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--separator);
|
||||
text-align: initial;
|
||||
margin: 0;
|
||||
}
|
||||
.card_component {
|
||||
flex: 1 1 auto;
|
||||
|
||||
Reference in New Issue
Block a user