Use centralized loading indicator

This commit is contained in:
2022-04-26 15:23:57 +02:00
parent 4ca2da91f0
commit 464a238f91
17 changed files with 258 additions and 369 deletions

View File

@@ -1,7 +1,6 @@
<script> <script>
import { onMount, tick } from "svelte"; import { onMount, tick } from "svelte";
import { formatDate, formatDuration } from "../util/Formatting.svelte"; import LoadingIndicator from "../util/LoadingIndicator.svelte";
import Spinner from "../util/Spinner.svelte";
import AbuseReporterTable from "./AbuseReporterTable.svelte"; import AbuseReporterTable from "./AbuseReporterTable.svelte";
let loading = true let loading = true
@@ -122,11 +121,7 @@ const delete_reporter = async reporter => {
onMount(get_reporters); onMount(get_reporters);
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<div class="toolbar" style="text-align: left;"> <div class="toolbar" style="text-align: left;">
@@ -201,14 +196,6 @@ onMount(get_reporters);
</div> </div>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@@ -1,6 +1,6 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
import Spinner from "../util/Spinner.svelte"; import LoadingIndicator from "../util/LoadingIndicator.svelte";
import AbuseReport from "./AbuseReport.svelte"; import AbuseReport from "./AbuseReport.svelte";
let loading = true let loading = true
@@ -91,11 +91,7 @@ onMount(() => {
}); });
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<div class="toolbar" style="text-align: left;"> <div class="toolbar" style="text-align: left;">
@@ -123,14 +119,6 @@ onMount(() => {
</section> </section>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@@ -1,8 +1,8 @@
<script> <script>
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 Expandable from "../util/Expandable.svelte"; import Expandable from "../util/Expandable.svelte";
import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = true let loading = true
let rows = [] let rows = []
@@ -79,11 +79,7 @@ const delete_ban = async (addr) => {
onMount(get_bans); onMount(get_bans);
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<div class="toolbar"> <div class="toolbar">
@@ -188,14 +184,6 @@ onMount(get_bans);
</section> </section>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@@ -2,7 +2,7 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import Euro from "../util/Euro.svelte"; import Euro from "../util/Euro.svelte";
import Form from "./../util/Form.svelte"; import Form from "./../util/Form.svelte";
import Spinner from "../util/Spinner.svelte"; import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = true let loading = true
@@ -173,12 +173,9 @@ onMount(get_coupons)
</script> </script>
<LoadingIndicator loading={loading}/>
<section> <section>
{#if loading}
<div class="spinner_container">
<Spinner />
</div>
{/if}
<h2>Give user credit</h2> <h2>Give user credit</h2>
<p> <p>
This adds credit to a user's account. You only need to enter one of This adds credit to a user's account. You only need to enter one of
@@ -222,14 +219,3 @@ onMount(get_coupons)
</table> </table>
</div> </div>
</section> </section>
<style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
</style>

View File

@@ -17,10 +17,10 @@ import AdLeaderboard from "./AdLeaderboard.svelte";
import AdSkyscraper from "./AdSkyscraper.svelte"; import AdSkyscraper from "./AdSkyscraper.svelte";
import Sharebar from "./Sharebar.svelte"; import Sharebar from "./Sharebar.svelte";
import GalleryView from "./GalleryView.svelte"; import GalleryView from "./GalleryView.svelte";
import Spinner from "../util/Spinner.svelte";
import Downloader from "./Downloader.svelte"; import Downloader from "./Downloader.svelte";
import CustomBanner from "./CustomBanner.svelte"; import CustomBanner from "./CustomBanner.svelte";
import UkraineModal from "./UkraineModal.svelte"; import UkraineModal from "./UkraineModal.svelte";
import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = true let loading = true
let embedded = false let embedded = false
@@ -366,11 +366,7 @@ const keyboard_event = evt => {
<!-- Head elements for the ads --> <!-- Head elements for the ads -->
<AdHead></AdHead> <AdHead></AdHead>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner></Spinner>
</div>
{/if}
<div id="headerbar" class="headerbar"> <div id="headerbar" class="headerbar">
<button <button
@@ -618,15 +614,6 @@ const keyboard_event = evt => {
</div> </div>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
right: 10px;
height: 100px;
width: 100px;
z-index: 10000;
}
.file_viewer { .file_viewer {
position: absolute; position: absolute;
display: flex; display: flex;

View File

@@ -3,7 +3,6 @@ import { onMount } from 'svelte';
import { formatDate, formatDataVolume, formatThousands } from '../util/Formatting.svelte' import { formatDate, formatDataVolume, formatThousands } from '../util/Formatting.svelte'
import { fs_get_file_url, fs_get_node } from './FilesystemAPI.svelte' import { fs_get_file_url, fs_get_node } from './FilesystemAPI.svelte'
import Sharebar from './Sharebar.svelte' import Sharebar from './Sharebar.svelte'
import Spinner from '../util/Spinner.svelte'
import Modal from '../util/Modal.svelte' import Modal from '../util/Modal.svelte'
import FileManager from './filemanager/FileManager.svelte'; import FileManager from './filemanager/FileManager.svelte';
import Audio from './viewers/Audio.svelte'; import Audio from './viewers/Audio.svelte';
@@ -11,6 +10,7 @@ import Image from './viewers/Image.svelte';
import Video from './viewers/Video.svelte'; import Video from './viewers/Video.svelte';
import PDF from './viewers/PDF.svelte'; import PDF from './viewers/PDF.svelte';
import PixeldrainLogo from '../util/PixeldrainLogo.svelte'; import PixeldrainLogo from '../util/PixeldrainLogo.svelte';
import LoadingIndicator from '../util/LoadingIndicator.svelte';
// Elements // Elements
let file_viewer let file_viewer
@@ -271,13 +271,9 @@ const share = () => {
<svelte:window on:keydown={keydown} /> <svelte:window on:keydown={keydown} />
<div bind:this={file_viewer} class="file_viewer"> <LoadingIndicator loading={state.loading}/>
{#if state.loading}
<div style="position: absolute; right: 0; top: 0; height: 48px; width: 48px; z-index: 100;">
<Spinner></Spinner>
</div>
{/if}
<div bind:this={file_viewer} class="file_viewer">
<div bind:this={header_bar} class="file_viewer_headerbar"> <div bind:this={header_bar} class="file_viewer_headerbar">
<button on:click={toolbar_toggle} class="button_toggle_toolbar round" class:button_highlight={toolbar_visible}> <button on:click={toolbar_toggle} class="button_toggle_toolbar round" class:button_highlight={toolbar_visible}>
<i class="icon">menu</i> <i class="icon">menu</i>

View File

@@ -1,8 +1,8 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
import UserBucket from "./UserBucket.svelte"; import UserBucket from "./UserBucket.svelte";
import Spinner from "../util/Spinner.svelte";
import { fs_get_buckets, fs_create_bucket } from "../filesystem/FilesystemAPI.svelte"; import { fs_get_buckets, fs_create_bucket } from "../filesystem/FilesystemAPI.svelte";
import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = true let loading = true
let buckets = [] let buckets = []
@@ -41,11 +41,7 @@ const create_bucket = async () => {
onMount(get_buckets); onMount(get_buckets);
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<div class="toolbar" style="text-align: right;"> <div class="toolbar" style="text-align: right;">
@@ -84,13 +80,3 @@ onMount(get_buckets);
<UserBucket bucket={bucket} on:refresh={get_buckets}></UserBucket> <UserBucket bucket={bucket} on:refresh={get_buckets}></UserBucket>
{/each} {/each}
</section> </section>
<style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
}
</style>

View File

@@ -1,6 +1,6 @@
<script> <script>
import { formatDate } from "../util/Formatting.svelte"; import { formatDate } from "../util/Formatting.svelte";
import Spinner from "../util/Spinner.svelte"; import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = false let loading = false
let loaded = false let loaded = false
@@ -82,11 +82,7 @@ const logout = async (key) => {
} }
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
{#if !loaded} {#if !loaded}
@@ -164,14 +160,6 @@ const logout = async (key) => {
</div> </div>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@@ -139,75 +139,6 @@ let delete_account = {
return {success: true, message: "Success! Your account has been scheduled for deletion in 7 days"} return {success: true, message: "Success! Your account has been scheduled for deletion in 7 days"}
}, },
} }
let success_message
let changes_made = false
let file_picker
let currently_selecting = "" // header, background or footer
let theme = ""
let header_image = ""
let background_image = ""
let footer_image = ""
let select_file = t => {
currently_selecting = t
file_picker.open()
}
let add_file = files => {
let type = files[0].type
if (type != "image/png" && type != "image/jpeg" && type != "image/gif" && type != "image/webp") {
success_message.set(false, "File must be an image type")
return
}
if (files[0].size > 10e6) {
success_message.set(false, "Files larger than 10 MB are not allowed. Recommended size is below 1 MB")
return
}
if (currently_selecting === "header") {
header_image = files[0].id
} else if (currently_selecting === "background") {
background_image = files[0].id
} else if (currently_selecting === "footer") {
footer_image = files[0].id
}
changes_made = true
}
let save = async () => {
const form = new FormData()
form.append("theme", theme)
form.append("header_image", header_image)
form.append("background_image", background_image)
form.append("footer_image", footer_image)
const resp = await fetch(
window.api_endpoint+"/user/file_customization",
{ method: "PUT", body: form }
);
if(resp.status >= 400) {
let json = await resp.json()
console.debug(json)
success_message.set(false, json.message)
return
}
success_message.set(true, "Changes saved")
changes_made = false
}
onMount(() => {
if (window.user.file_viewer_branding) {
let b = window.user.file_viewer_branding
theme = b.theme ? b.theme : ""
header_image = b.header_image ? b.header_image : ""
background_image = b.background_image ? b.background_image : ""
footer_image = b.footer_image ? b.footer_image : ""
}
})
</script> </script>
<section> <section>
@@ -223,125 +154,4 @@ onMount(() => {
<h3>Delete account</h3> <h3>Delete account</h3>
<Form config={delete_account}></Form> <Form config={delete_account}></Form>
<h2>File viewer branding</h2>
{#if !window.user.subscription.file_viewer_branding}
<div class="highlight_red">
File viewer branding is not available for your account. Subscribe to
the Persistence plan or higher to enable this feature.
</div>
{:else if !window.user.hotlinking_enabled}
<div class="highlight_red">
To use the branding feature bandwidth sharing needs to be enabled.
Without this the custom images will not be able to load. Enable
bandwidth sharing on the
<a href="/user/subscription">subscription page</a>.
</div>
{/if}
<SuccessMessage bind:this={success_message}></SuccessMessage>
<p>
You can change the appearance of your file viewer pages. The images you
choose here will be loaded each time someone visits one of your files.
The data usage will also be subtracted from your account's data cap.
Keep in mind that large images can take a very long time to load over
cellular connections. I recommend keeping the header and footer images
below 100 kB, and the background image below 1 MB. Allowed image types
are PNG, JPEG, GIF and WebP. If you want to use an animated banner you
should use APNG or WebP. Avoid using animated GIFs as they are very slow
to load.
</p>
<h3>Theme</h3>
<p>
Choose a theme for your download pages. This theme will override the
theme preference of the person viewing the file. Set to 'None' to let
the viewer choose their own theme.
</p>
<ThemePicker
theme={theme}
on:theme_change={e => {theme = e.detail; changes_made = true}}>
</ThemePicker>
<h3>Header image</h3>
<p>
Will be shown above the file. Maximum height is 90px. Will be shrunk if
larger.
</p>
<button on:click={() => {select_file("header")}}>
<i class="icon">add_photo_alternate</i>
Select header image
</button>
<button on:click={() => {header_image = ""}}>
<i class="icon">close</i>
Remove
</button>
{#if header_image}
<div class="highlight_shaded">
<img class="banner_preview" src="/api/file/{header_image}" alt="Custom file viewer header"/>
</div>
{/if}
<h3>Background image</h3>
<p>
This image will be shown behind the file which is being viewed. I
recommend choosing something dark and not too distracting. Try to keep
the file below 1 MB to not harm page loading times. Using a JPEG image
with a quality value of 60 is usually good enough.
</p>
<button on:click={() => {select_file("background")}}>
<i class="icon">add_photo_alternate</i>
Select background image
</button>
<button on:click={() => {background_image = ""}}>
<i class="icon">close</i>
Remove
</button>
{#if background_image}
<div class="highlight_shaded">
<img class="background_preview" src="/api/file/{background_image}" alt="Custom file viewer background"/>
</div>
{/if}
<h3>Footer image</h3>
<p>
Will be shown below the file. Maximum height is 90px. Will be shrunk if
larger.
</p>
<button on:click={() => {select_file("footer")}}>
<i class="icon">add_photo_alternate</i>
Select footer image
</button>
<button on:click={() => {footer_image = ""}}>
<i class="icon">close</i>
Remove
</button>
{#if footer_image}
<div class="highlight_shaded">
<img class="banner_preview" src="/api/file/{footer_image}" alt="Custom file viewer footer"/>
</div>
{/if}
<hr/>
<button on:click={save} class:button_highlight={changes_made}>
<i class="icon">save</i> Save
</button>
<br/>
<br/>
</section> </section>
<FilePicker bind:this={file_picker} on:files={e => {add_file(e.detail)}} multi_select={false} title="Select image file"></FilePicker>
<style>
.banner_preview {
max-height: 90px;
max-width: 100%;
display: block;
margin: auto;
}
.background_preview {
max-height: 200px;
max-width: 100%;
display: block;
margin: auto;
}
</style>

View File

@@ -1,7 +1,7 @@
<script> <script>
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 LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = false let loading = false
@@ -59,11 +59,7 @@ onMount(() => {
}) })
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<h2>Account activity log</h2> <h2>Account activity log</h2>
@@ -134,14 +130,6 @@ onMount(() => {
</section> </section>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@@ -1,6 +1,6 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
import Spinner from "../util/Spinner.svelte"; import LoadingIndicator from "../util/LoadingIndicator.svelte";
import { copy_text } from "../util/Util.svelte"; import { copy_text } from "../util/Util.svelte";
let loading = false let loading = false
@@ -55,11 +55,7 @@ onMount(() => {
}) })
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<!-- Show a back button if an app is selected --> <!-- Show a back button if an app is selected -->
@@ -200,15 +196,6 @@ onMount(() => {
</section> </section>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.app_icon { .app_icon {
height: 1.6em; height: 1.6em;
vertical-align: middle; vertical-align: middle;

View File

@@ -7,6 +7,7 @@ import Transactions from "./Transactions.svelte";
import Subscription from "./Subscription.svelte"; import Subscription from "./Subscription.svelte";
import ConnectApp from "./ConnectApp.svelte"; import ConnectApp from "./ConnectApp.svelte";
import ActivityLog from "./ActivityLog.svelte"; import ActivityLog from "./ActivityLog.svelte";
import SharingSettings from "./SharingSettings.svelte";
let page = "" let page = ""
@@ -52,6 +53,13 @@ onMount(() => {
<i class="icon">settings</i><br/> <i class="icon">settings</i><br/>
Settings Settings
</a> </a>
<a class="button"
href="/user/sharing"
class:button_highlight={page === "sharing"}
on:click|preventDefault={() => {navigate("sharing", "Sharing")}}>
<i class="icon">share</i><br/>
Sharing
</a>
<a class="button" <a class="button"
href="/user/connect_app" href="/user/connect_app"
class:button_highlight={page === "connect_app"} class:button_highlight={page === "connect_app"}
@@ -97,6 +105,8 @@ onMount(() => {
<Home/> <Home/>
{:else if page === "settings"} {:else if page === "settings"}
<AccountSettings/> <AccountSettings/>
{:else if page === "sharing"}
<SharingSettings/>
{:else if page === "api_keys"} {:else if page === "api_keys"}
<APIKeys/> <APIKeys/>
{:else if page === "activity"} {:else if page === "activity"}

View File

@@ -0,0 +1,197 @@
<script>
import { onMount } from "svelte";
import FilePicker from "../file_viewer/FilePicker.svelte";
import LoadingIndicator from "../util/LoadingIndicator.svelte";
import SuccessMessage from "../util/SuccessMessage.svelte";
import ThemePicker from "../util/ThemePicker.svelte";
let loading = false
let success_message
let file_picker
let currently_selecting = "" // header, background or footer
let theme = ""
let header_image = ""
let background_image = ""
let footer_image = ""
let select_file = t => {
currently_selecting = t
file_picker.open()
}
let add_file = files => {
let type = files[0].type
if (type != "image/png" && type != "image/jpeg" && type != "image/gif" && type != "image/webp") {
success_message.set(false, "File must be an image type")
return
}
if (files[0].size > 10e6) {
success_message.set(false, "Files larger than 10 MB are not allowed. Recommended size is below 1 MB")
return
}
if (currently_selecting === "header") {
header_image = files[0].id
} else if (currently_selecting === "background") {
background_image = files[0].id
} else if (currently_selecting === "footer") {
footer_image = files[0].id
}
save()
}
let save = async () => {
loading = true
const form = new FormData()
form.append("theme", theme)
form.append("header_image", header_image)
form.append("background_image", background_image)
form.append("footer_image", footer_image)
const resp = await fetch(
window.api_endpoint+"/user/file_customization",
{ method: "PUT", body: form }
);
if(resp.status >= 400) {
let json = await resp.json()
console.debug(json)
success_message.set(false, json.message)
return
}
success_message.set(true, "Changes saved")
loading = false
}
onMount(() => {
if (window.user.file_viewer_branding) {
let b = window.user.file_viewer_branding
theme = b.theme ? b.theme : ""
header_image = b.header_image ? b.header_image : ""
background_image = b.background_image ? b.background_image : ""
footer_image = b.footer_image ? b.footer_image : ""
}
})
</script>
<LoadingIndicator loading={loading}/>
<section>
<h2>File viewer branding</h2>
{#if !window.user.subscription.file_viewer_branding}
<div class="highlight_red">
File viewer branding is not available for your account. Subscribe to
the Persistence plan or higher to enable this feature.
</div>
{:else if !window.user.hotlinking_enabled}
<div class="highlight_red">
To use the branding feature bandwidth sharing needs to be enabled.
Without this the custom images will not be able to load. Enable
bandwidth sharing on the
<a href="/user/subscription">subscription page</a>.
</div>
{/if}
<SuccessMessage bind:this={success_message}></SuccessMessage>
<p>
You can change the appearance of your file viewer pages. The images you
choose here will be loaded each time someone visits one of your files.
The data usage will also be subtracted from your account's data cap.
Keep in mind that large images can take a very long time to load over
cellular connections. I recommend keeping the header and footer images
below 100 kB, and the background image below 1 MB. Allowed image types
are PNG, JPEG, GIF and WebP. If you want to use an animated banner you
should use APNG or WebP. Avoid using animated GIFs as they are very slow
to load.
</p>
<h3>Theme</h3>
<p>
Choose a theme for your download pages. This theme will override the
theme preference of the person viewing the file. Set to 'None' to let
the viewer choose their own theme.
</p>
<ThemePicker
theme={theme}
on:theme_change={e => {theme = e.detail; save()}}>
</ThemePicker>
<h3>Header image</h3>
<p>
Will be shown above the file. Maximum height is 90px. Will be shrunk if
larger.
</p>
<button on:click={() => {select_file("header")}}>
<i class="icon">add_photo_alternate</i>
Select header image
</button>
<button on:click={() => {header_image = ""; save()}}>
<i class="icon">close</i>
Remove
</button>
{#if header_image}
<div class="highlight_shaded">
<img class="banner_preview" src="/api/file/{header_image}" alt="Custom file viewer header"/>
</div>
{/if}
<h3>Background image</h3>
<p>
This image will be shown behind the file which is being viewed. I
recommend choosing something dark and not too distracting. Try to keep
the file below 1 MB to not harm page loading times. Using a JPEG image
with a quality value of 60 is usually good enough.
</p>
<button on:click={() => {select_file("background")}}>
<i class="icon">add_photo_alternate</i>
Select background image
</button>
<button on:click={() => {background_image = ""; save()}}>
<i class="icon">close</i>
Remove
</button>
{#if background_image}
<div class="highlight_shaded">
<img class="background_preview" src="/api/file/{background_image}" alt="Custom file viewer background"/>
</div>
{/if}
<h3>Footer image</h3>
<p>
Will be shown below the file. Maximum height is 90px. Will be shrunk if
larger.
</p>
<button on:click={() => {select_file("footer")}}>
<i class="icon">add_photo_alternate</i>
Select footer image
</button>
<button on:click={() => {footer_image = ""; save()}}>
<i class="icon">close</i>
Remove
</button>
{#if footer_image}
<div class="highlight_shaded">
<img class="banner_preview" src="/api/file/{footer_image}" alt="Custom file viewer footer"/>
</div>
{/if}
<br/>
<br/>
</section>
<FilePicker bind:this={file_picker} on:files={e => {add_file(e.detail)}} multi_select={false} title="Select image file"></FilePicker>
<style>
.banner_preview {
max-height: 90px;
max-width: 100%;
display: block;
margin: auto;
}
.background_preview {
max-height: 200px;
max-width: 100%;
display: block;
margin: auto;
}
</style>

View File

@@ -1,9 +1,9 @@
<script> <script>
import Spinner from "../util/Spinner.svelte";
import Euro from "../util/Euro.svelte" import Euro from "../util/Euro.svelte"
import ProgressBar from "../util/ProgressBar.svelte"; import ProgressBar from "../util/ProgressBar.svelte";
import { onMount } from "svelte"; import { onMount } from "svelte";
import { formatDataVolume } from "../util/Formatting.svelte"; import { formatDataVolume } from "../util/Formatting.svelte";
import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = false let loading = false
let subscription = window.user.subscription.id let subscription = window.user.subscription.id
@@ -73,11 +73,8 @@ onMount(load_tranfer_used)
</script> </script>
{#if loading} <LoadingIndicator loading={loading}/>
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section> <section>
<h2>Manage subscription</h2> <h2>Manage subscription</h2>
{#if window.user.subscription.type !== "patreon"} {#if window.user.subscription.type !== "patreon"}
@@ -237,15 +234,6 @@ onMount(load_tranfer_used)
</section> </section>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.green { .green {
color: var(--highlight_color); color: var(--highlight_color);
} }
@@ -257,15 +245,6 @@ onMount(load_tranfer_used)
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
} }
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.feat_table { .feat_table {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -1,8 +1,8 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
import { formatDataVolume, formatDate } from "../util/Formatting.svelte"; import { formatDataVolume, formatDate } from "../util/Formatting.svelte";
import Spinner from "../util/Spinner.svelte";
import Euro from "../util/Euro.svelte" import Euro from "../util/Euro.svelte"
import LoadingIndicator from "../util/LoadingIndicator.svelte";
let loading = false let loading = false
@@ -135,12 +135,9 @@ onMount(() => {
}) })
</script> </script>
<LoadingIndicator loading={loading}/>
<section> <section>
{#if loading}
<div class="spinner_container">
<Spinner />
</div>
{/if}
<h2>Deposit credits</h2> <h2>Deposit credits</h2>
<p> <p>
You can deposit credit on your pixeldrain account with Bitcoin, You can deposit credit on your pixeldrain account with Bitcoin,
@@ -301,14 +298,6 @@ onMount(() => {
</section> </section>
<style> <style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@@ -0,0 +1,22 @@
<script>
import Spinner from "./Spinner.svelte";
export let loading = false
</script>
{#if loading}
<div class="container">
<Spinner/>
</div>
{/if}
<style>
.container {
position: fixed;
top: 10px;
right: 10px;
height: 120px;
width: 120px;
z-index: 1000;
}
</style>

View File

@@ -181,6 +181,7 @@ func New(
{GET, "user" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})}, {GET, "user" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/home" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})}, {GET, "user/home" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/settings" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})}, {GET, "user/settings" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/sharing" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/api_keys" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})}, {GET, "user/api_keys" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/activity" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})}, {GET, "user/activity" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/connect_app" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})}, {GET, "user/connect_app" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},