Replace CSS classes with semantic HTML
This commit is contained in:
@@ -46,8 +46,11 @@ a > svg { vertical-align: middle; }
|
|||||||
*, *::before, *::after {
|
*, *::before, *::after {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
html, body { overflow-x: hidden; }
|
html, body {
|
||||||
body{
|
/* This makes sure that no scrollbar shows up when the menu is open on small screens*/
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: system-ui, sans-serif;
|
font-family: system-ui, sans-serif;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
@@ -56,20 +59,26 @@ body{
|
|||||||
background-color: var(--layer_1_color);
|
background-color: var(--layer_1_color);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.checkers {
|
header, footer, .checkers {
|
||||||
background-image: url("{{bgPattern}}");
|
background-image: url("{{bgPattern}}");
|
||||||
background-color: #111111; /* Fallback */
|
background-color: #111111; /* Fallback */
|
||||||
background-color: var(--layer_1_color);
|
background-color: var(--layer_1_color);
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-blend-mode: luminosity;
|
background-blend-mode: luminosity;
|
||||||
}
|
}
|
||||||
.inset {
|
header, footer {
|
||||||
padding-top: 70px;
|
padding-top: 70px;
|
||||||
box-shadow: inset 1px 1px 10px 0 var(--shadow_color);
|
box-shadow: inset 1px 1px 10px 0 var(--shadow_color);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
header > h1 {
|
||||||
|
text-shadow: 1px 1px 10px var(--shadow_color);
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
padding: 200px 8px 40px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Page layout elements */
|
/* Page layout elements */
|
||||||
|
|
||||||
@@ -131,7 +140,7 @@ body{
|
|||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.limit_width {
|
section {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
@@ -141,10 +150,6 @@ body{
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
.page_body > h1 {
|
|
||||||
text-shadow: 1px 1px 25px #000000;
|
|
||||||
text-shadow: 1px 1px 25px var(--shadow_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Page contents */
|
/* Page contents */
|
||||||
|
|
||||||
|
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>This page does not exist!</h1>
|
<h1>This page does not exist!</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
If you came here by a link from this very same website you can
|
If you came here by a link from this very same website you can
|
||||||
tell me about it on
|
tell me about it on
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Bye!
|
Bye!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -7,15 +7,15 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>451, Unavailable For Legal Reasons</h1>
|
<h1>451, Unavailable For Legal Reasons</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
Hello. This file has received an abuse report and has been taken
|
Hello. This file has received an abuse report and has been taken
|
||||||
down. It cannot be shared anymore.
|
down. It cannot be shared anymore.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>You broke pixeldrain</h1>
|
<h1>You broke pixeldrain</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
Great job.
|
Great job.
|
||||||
</p>
|
</p>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
try again in a few minutes (or hours), or go back to the <a
|
try again in a few minutes (or hours), or go back to the <a
|
||||||
href='/'>home page</a> and start over.
|
href='/'>home page</a> and start over.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>Change website appearance</h1>
|
<h1>Change website appearance</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
You can change how pixeldrain looks! Your theme choice will
|
You can change how pixeldrain looks! Your theme choice will
|
||||||
be saved in a cookie.
|
be saved in a cookie.
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
(Inspired by <a href="https://www.gnome-look.org/p/1441725/" target="_blank">Skeuos GTK</a>)<br/>
|
(Inspired by <a href="https://www.gnome-look.org/p/1441725/" target="_blank">Skeuos GTK</a>)<br/>
|
||||||
<!--<input type="radio" id="style_sunny" name="style"><label for="style_sunny">Sunny Style</label>-->
|
<!--<input type="radio" id="style_sunny" name="style"><label for="style_sunny">Sunny Style</label>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Style selector
|
// Style selector
|
||||||
|
@@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>Apps</h1>
|
<h1>Apps</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<h2>ShareX</h2>
|
<h2>ShareX</h2>
|
||||||
<div class="specs">
|
<div class="specs">
|
||||||
Platform: Windows 7, 8.1 and 10 |
|
Platform: Windows 7, 8.1 and 10 |
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
please send them to
|
please send them to
|
||||||
<a href="mailto:support@pixeldrain.com">support@pixeldrain.com</a>.
|
<a href="mailto:support@pixeldrain.com">support@pixeldrain.com</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -7,27 +7,38 @@
|
|||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
|
|
||||||
<div class="limit_width">
|
{{if eq .Other "success"}}
|
||||||
{{if eq .Other "success"}}
|
<header>
|
||||||
<h1>Success!</h1>
|
<h1>Success!</h1>
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
<p>
|
<p>
|
||||||
Your account's e-mail address has been updated.
|
Your account's e-mail address has been updated.
|
||||||
</p>
|
</p>
|
||||||
{{else if eq .Other "not_found"}}
|
</section>
|
||||||
|
{{else if eq .Other "not_found"}}
|
||||||
|
<header>
|
||||||
<h1>E-mail change failed</h1>
|
<h1>E-mail change failed</h1>
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
<p>
|
<p>
|
||||||
This e-mail change request does not exist or has expired.
|
This e-mail change request does not exist or has expired.
|
||||||
Please try again if you still want to change your e-mail
|
Please try again if you still want to change your e-mail
|
||||||
address.
|
address.
|
||||||
</p>
|
</p>
|
||||||
{{else}}
|
</section>
|
||||||
|
{{else}}
|
||||||
|
<header>
|
||||||
<h1>Error</h1>
|
<h1>Error</h1>
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
<p>
|
<p>
|
||||||
Something went wrong while processing this request. Please
|
Something went wrong while processing this request. Please
|
||||||
try again later.
|
try again later.
|
||||||
</p>
|
</p>
|
||||||
{{end}}
|
</section>
|
||||||
</div>
|
{{end}}
|
||||||
|
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>404, File Not Found!</h1>
|
<h1>404, File Not Found!</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
This file does not exist, or it has been removed. Possible
|
This file does not exist, or it has been removed. Possible
|
||||||
reasons for this are:
|
reasons for this are:
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<p>
|
<p>
|
||||||
I'm sorry for the inconvenience.
|
I'm sorry for the inconvenience.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
@@ -49,10 +49,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>404, List Not Found!</h1>
|
<h1>404, List Not Found!</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
This list does not exist, or it has been removed. Possible
|
This list does not exist, or it has been removed. Possible
|
||||||
reasons for this are:
|
reasons for this are:
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<p>
|
<p>
|
||||||
I'm sorry for the inconvenience.
|
I'm sorry for the inconvenience.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -25,10 +25,10 @@
|
|||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>{{.Title}}</h1>
|
<h1>{{.Title}}</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
{{if eq .Other.Type "file"}}
|
{{if eq .Other.Type "file"}}
|
||||||
Download <a href="{{.APIEndpoint}}/file/{{.Other.APIResponse.ID}}?download">{{.Other.APIResponse.Name}}</a> here.
|
Download <a href="{{.APIEndpoint}}/file/{{.Other.APIResponse.ID}}?download">{{.Other.APIResponse.Name}}</a> here.
|
||||||
{{else}}
|
{{else}}
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
<li><a href="https://www.apple.com/safari/">Safari</a> (Mac OS)</li>
|
<li><a href="https://www.apple.com/safari/">Safari</a> (Mac OS)</li>
|
||||||
<li><a href="https://www.microsoft.com/en-us/edge">Edge</a> (Windows)</li>
|
<li><a href="https://www.microsoft.com/en-us/edge">Edge</a> (Windows)</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</section>
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -110,14 +110,14 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id='body' class="body">
|
<div id='body' class="body">
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>{{.Form.Title}}</h1>
|
<h1>{{.Form.Title}}</h1>
|
||||||
</div>
|
</header>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
{{template "form" .Form}}
|
{{template "form" .Form}}
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>{{.Title}}</h1>
|
<h1>{{.Title}}</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
{{.Other}}
|
{{.Other}}
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{{define "page_menu"}}
|
{{define "page_menu"}}
|
||||||
<button id="button_toggle_navigation" class="button_toggle_navigation" onclick="toggleMenu();">☰</button>
|
<button id="button_toggle_navigation" class="button_toggle_navigation" onclick="toggleMenu();">☰</button>
|
||||||
<div id="page_navigation" class="page_navigation">
|
<nav id="page_navigation" class="page_navigation">
|
||||||
<a href="/">Home</a>
|
<a href="/">Home</a>
|
||||||
<hr />
|
<hr />
|
||||||
{{if .Authenticated}}<a href="/user">{{.User.Username}}</a>
|
{{if .Authenticated}}<a href="/user">{{.User.Username}}</a>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
{{if eq .User.Subscription.ID ""}}
|
{{if eq .User.Subscription.ID ""}}
|
||||||
<a href="https://pixeldrain.com/vouchercodes">Shopping discounts</a>
|
<a href="https://pixeldrain.com/vouchercodes">Shopping discounts</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</nav>
|
||||||
<script>
|
<script>
|
||||||
function toggleMenu() {
|
function toggleMenu() {
|
||||||
var nav = document.getElementById("page_navigation");
|
var nav = document.getElementById("page_navigation");
|
||||||
@@ -54,7 +54,7 @@ function resetMenu() {
|
|||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "page_bottom"}}
|
{{define "page_bottom"}}
|
||||||
<div class="inset checkers" style="padding-top: 150px">
|
<footer>
|
||||||
<div style="display: inline-block; margin: 0 8px 0 8px;">
|
<div style="display: inline-block; margin: 0 8px 0 8px;">
|
||||||
Pixeldrain is a product by <a href="//fornaxian.tech" target="_blank">Fornaxian Technologies</a>
|
Pixeldrain is a product by <a href="//fornaxian.tech" target="_blank">Fornaxian Technologies</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,8 +71,6 @@ function resetMenu() {
|
|||||||
<span class="small_footer_text" style="font-size: .75em; line-height: .75em;">
|
<span class="small_footer_text" style="font-size: .75em; line-height: .75em;">
|
||||||
page rendered by {{.Hostname}}
|
page rendered by {{.Hostname}}
|
||||||
</span>
|
</span>
|
||||||
<br/>
|
</footer>
|
||||||
<br/>
|
|
||||||
</div>
|
|
||||||
</div><!-- end page_body -->
|
</div><!-- end page_body -->
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@@ -5,24 +5,23 @@
|
|||||||
{{template "user_style" .}}
|
{{template "user_style" .}}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id='body' class="body">
|
{{template "page_top" .}}
|
||||||
{{template "page_top" .}}
|
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>Upload History</h1>
|
<h1>Upload History</h1>
|
||||||
</div>
|
</header>
|
||||||
|
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
Here are all files you have previously uploaded to pixeldrain using this computer.
|
Here are all files you have previously uploaded to pixeldrain using this computer.
|
||||||
This data is saved locally in your web browser and gets updated every time you upload a file through your current browser.
|
This data is saved locally in your web browser and gets updated every time you upload a file through your current browser.
|
||||||
</p>
|
</p>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
<div id="uploaded_files" class="highlight_dark"></div>
|
||||||
|
</section>
|
||||||
|
{{template "page_bottom" .}}
|
||||||
|
|
||||||
<div id="uploaded_files" class="highlight_dark"></div>
|
|
||||||
</div>
|
|
||||||
{{template "page_bottom" .}}
|
|
||||||
</div>
|
|
||||||
<script>
|
<script>
|
||||||
let apiEndpoint = '{{.APIEndpoint}}';
|
let apiEndpoint = '{{.APIEndpoint}}';
|
||||||
{{template `util.js`}}
|
{{template `util.js`}}
|
||||||
|
@@ -93,21 +93,21 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset" style="padding-bottom: 60px;">
|
<header style="padding-bottom: 60px;">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(max-width: 800px)" srcset="/res/img/header_orbitron.png">
|
<source media="(max-width: 800px)" srcset="/res/img/header_orbitron.png">
|
||||||
<img class="header_image" src="/res/img/header_orbitron_wide.png" alt="Header image">
|
<img class="header_image" src="/res/img/header_orbitron_wide.png" alt="Header image">
|
||||||
</picture>
|
</picture>
|
||||||
</div>
|
</header>
|
||||||
|
|
||||||
<!-- Svelte element -->
|
<!-- Svelte element -->
|
||||||
<div id="uploader" class="page_content"></div>
|
<div id="uploader" class="page_content"></div>
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>What is pixeldrain?</h1>
|
<h1>What is pixeldrain?</h1>
|
||||||
</div>
|
</header>
|
||||||
|
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<p>
|
<p>
|
||||||
Pixeldrain is a file sharing website built for speed and ease of
|
Pixeldrain is a file sharing website built for speed and ease of
|
||||||
use. You can upload files you want to share online to our
|
use. You can upload files you want to share online to our
|
||||||
@@ -475,7 +475,7 @@
|
|||||||
logging in head to the <a href="/user/transactions">transactions
|
logging in head to the <a href="/user/transactions">transactions
|
||||||
page</a> to deposit your coins.
|
page</a> to deposit your coins.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<template id="tpl_file_expiry">
|
<template id="tpl_file_expiry">
|
||||||
<p>
|
<p>
|
||||||
|
@@ -10,9 +10,9 @@
|
|||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>My Buckets</h1>
|
<h1>My Buckets</h1>
|
||||||
</div>
|
</header>
|
||||||
<div id="page_content" class="page_content"></div>
|
<div id="page_content" class="page_content"></div>
|
||||||
|
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
|
@@ -6,15 +6,14 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>Please confirm that you want to log out of your pixeldrain account</h1>
|
<h1>Please confirm that you want to log out of your pixeldrain account</h1>
|
||||||
<br/>
|
</header>
|
||||||
</div>
|
|
||||||
<br/>
|
<br/>
|
||||||
<form method="POST" action="/logout">
|
<form method="POST" action="/logout">
|
||||||
<input type="submit" value="I want to log out of pixeldrain on this computer" class="button_highlight"/>
|
<input type="submit" value="I want to log out of pixeldrain on this computer" class="button_highlight"/>
|
||||||
</form>
|
</form>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<br/>
|
<br/>
|
||||||
<h2>Why do I need to confirm my logout?</h2>
|
<h2>Why do I need to confirm my logout?</h2>
|
||||||
<p>
|
<p>
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
page visit we can confirm that you really want to log out.
|
page visit we can confirm that you really want to log out.
|
||||||
</p>
|
</p>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
{{template "analytics"}}
|
{{template "analytics"}}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -8,10 +8,10 @@
|
|||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header">
|
||||||
<h1>Widget showcase</h1>
|
<h1>Widget showcase</h1>
|
||||||
</div>
|
</header>
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<h2>Size 2 header</h2>
|
<h2>Size 2 header</h2>
|
||||||
<h3>Size 3 header</h3>
|
<h3>Size 3 header</h3>
|
||||||
<h4>Size 4 header</h4>
|
<h4>Size 4 header</h4>
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<iframe src="https://pixeldrain.com/u/Nygt1on4?embed" style="border: none; width: 800px; max-width: 100%; height: 600px; max-height: 100%; border-radius: 16px;"></iframe>
|
<iframe src="https://pixeldrain.com/u/Nygt1on4?embed" style="border: none; width: 800px; max-width: 100%; height: 600px; max-height: 100%; border-radius: 16px;"></iframe>
|
||||||
</div>
|
</section>
|
||||||
{{template "page_bottom" .}}
|
{{template "page_bottom" .}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -82,85 +82,83 @@ const delete_reporter = async (email) => {
|
|||||||
onMount(get_reporters);
|
onMount(get_reporters);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="toolbar" style="text-align: left;">
|
||||||
|
<div class="toolbar_spacer"></div>
|
||||||
|
<button class:button_highlight={creating} on:click={() => {creating = !creating}}>
|
||||||
|
<i class="icon">create</i> Add abuse reporter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{#if creating}
|
||||||
|
<div class="highlight_light">
|
||||||
|
<form on:submit|preventDefault={create_reporter}>
|
||||||
|
<table class="form">
|
||||||
|
<tr>
|
||||||
|
<td>E-mail address</td>
|
||||||
|
<td><input type="text" bind:this={new_reporter_email}/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td><input type="text" bind:this={new_reporter_name} value="Anonymous tip"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>
|
||||||
|
<input id="reporter_type_individual" name="reporter_type" type="radio" bind:group={new_reporter_type} value="individual" />
|
||||||
|
<label for="reporter_type_individual">Individual</label>
|
||||||
|
<br/>
|
||||||
|
<input id="reporter_type_org" name="reporter_type" type="radio" bind:group={new_reporter_type} value="org" />
|
||||||
|
<label for="reporter_type_org">Organisation</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<button class="button_highlight" type="submit" style="float: right;">
|
||||||
|
<i class="icon">save</i> Save
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
</section>
|
||||||
|
|
||||||
<div class="limit_width">
|
<br/>
|
||||||
<div class="toolbar" style="text-align: left;">
|
|
||||||
<div class="toolbar_spacer"></div>
|
|
||||||
<button class:button_highlight={creating} on:click={() => {creating = !creating}}>
|
|
||||||
<i class="icon">create</i> Add abuse reporter
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{#if creating}
|
|
||||||
<div class="highlight_light">
|
|
||||||
<form on:submit|preventDefault={create_reporter}>
|
|
||||||
<table class="form">
|
|
||||||
<tr>
|
|
||||||
<td>E-mail address</td>
|
|
||||||
<td><input type="text" bind:this={new_reporter_email}/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Name</td>
|
|
||||||
<td><input type="text" bind:this={new_reporter_name} value="Anonymous tip"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Type</td>
|
|
||||||
<td>
|
|
||||||
<input id="reporter_type_individual" name="reporter_type" type="radio" bind:group={new_reporter_type} value="individual" />
|
|
||||||
<label for="reporter_type_individual">Individual</label>
|
|
||||||
<br/>
|
|
||||||
<input id="reporter_type_org" name="reporter_type" type="radio" bind:group={new_reporter_type} value="org" />
|
|
||||||
<label for="reporter_type_org">Organisation</label>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<button class="button_highlight" type="submit" style="float: right;">
|
|
||||||
<i class="icon">save</i> Save
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br/>
|
<div class="table_scroll">
|
||||||
|
<table style="text-align: left;">
|
||||||
<div class="table_scroll">
|
<tr>
|
||||||
<table style="text-align: left;">
|
<td>E-mail</td>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Blocked</td>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>Last used</td>
|
||||||
|
<td>Created</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
{#each reporters as reporter (reporter.email)}
|
||||||
<tr>
|
<tr>
|
||||||
<td>E-mail</td>
|
<td>{reporter.email}</td>
|
||||||
<td>Name</td>
|
<td>{reporter.name}</td>
|
||||||
<td>Blocked</td>
|
<td>{reporter.files_blocked}</td>
|
||||||
<td>Type</td>
|
<td>{reporter.type}</td>
|
||||||
<td>Last used</td>
|
<td>{formatDate(reporter.last_used, true, true, false)}</td>
|
||||||
<td>Created</td>
|
<td>{formatDate(reporter.created, false, false, false)}</td>
|
||||||
<td></td>
|
<td>
|
||||||
|
<button on:click|preventDefault={() => {delete_reporter(reporter.email)}} class="button button_red round">
|
||||||
|
<i class="icon">delete</i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{#each reporters as reporter (reporter.email)}
|
{/each}
|
||||||
<tr>
|
</table>
|
||||||
<td>{reporter.email}</td>
|
|
||||||
<td>{reporter.name}</td>
|
|
||||||
<td>{reporter.files_blocked}</td>
|
|
||||||
<td>{reporter.type}</td>
|
|
||||||
<td>{formatDate(reporter.last_used, true, true, false)}</td>
|
|
||||||
<td>{formatDate(reporter.created, false, false, false)}</td>
|
|
||||||
<td>
|
|
||||||
<button on:click|preventDefault={() => {delete_reporter(reporter.email)}} class="button button_red round">
|
|
||||||
<i class="icon">delete</i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@@ -91,38 +91,36 @@ onMount(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div class="limit_width">
|
|
||||||
<div class="toolbar" style="text-align: left;">
|
|
||||||
<div class="toolbar_spacer"></div>
|
|
||||||
<div>Start:</div>
|
|
||||||
<input type="date" bind:this={startPicker}/>
|
|
||||||
<div>End:</div>
|
|
||||||
<input type="date" bind:this={endPicker}/>
|
|
||||||
<button on:click={get_reports}>Go</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Pending</h2>
|
|
||||||
{#each reports_pending as report (report.id)}
|
|
||||||
{#if report.status === "pending"}
|
|
||||||
<AbuseReport report={report} on:refresh={get_reports}/>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
<h2>Resolved</h2>
|
|
||||||
{#each reports_processed as report (report.id)}
|
|
||||||
{#if report.status !== "pending"}
|
|
||||||
<AbuseReport report={report} on:refresh={get_reports}/>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="toolbar" style="text-align: left;">
|
||||||
|
<div class="toolbar_spacer"></div>
|
||||||
|
<div>Start:</div>
|
||||||
|
<input type="date" bind:this={startPicker}/>
|
||||||
|
<div>End:</div>
|
||||||
|
<input type="date" bind:this={endPicker}/>
|
||||||
|
<button on:click={get_reports}>Go</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Pending</h2>
|
||||||
|
{#each reports_pending as report (report.id)}
|
||||||
|
{#if report.status === "pending"}
|
||||||
|
<AbuseReport report={report} on:refresh={get_reports}/>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<h2>Resolved</h2>
|
||||||
|
{#each reports_processed as report (report.id)}
|
||||||
|
{#if report.status !== "pending"}
|
||||||
|
<AbuseReport report={report} on:refresh={get_reports}/>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
|
@@ -65,17 +65,12 @@ onMount(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<section>
|
||||||
<div class="limit_width">
|
<h2>File removal</h2>
|
||||||
<h2>File removal</h2>
|
<p>
|
||||||
<p>
|
Paste any pixeldrain file links in here to remove them
|
||||||
Paste any pixeldrain file links in here to remove them
|
</p>
|
||||||
</p>
|
<div class="highlight_dark">
|
||||||
<div class="highlight_dark">
|
<Form config={block_form}></Form>
|
||||||
<Form config={block_form}></Form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
@@ -159,168 +159,160 @@ onDestroy(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<section>
|
||||||
<div class="limit_width">
|
<h3>Bandwidth usage and file views</h3>
|
||||||
<h3>Bandwidth usage and file views</h3>
|
</section>
|
||||||
</div>
|
<div class="highlight_dark" style="margin-bottom: 6px;">
|
||||||
<div class="highlight_dark" style="margin-bottom: 6px;">
|
<button on:click={() => { loadGraph(1440, 1, true) }}>Day</button>
|
||||||
<button on:click={() => { loadGraph(1440, 1, true) }}>Day</button>
|
<button on:click={() => { loadGraph(10080, 10, false) }}>Week</button>
|
||||||
<button on:click={() => { loadGraph(10080, 10, false) }}>Week</button>
|
<button on:click={() => { loadGraph(20160, 60, false) }}>Two Weeks</button>
|
||||||
<button on:click={() => { loadGraph(20160, 60, false) }}>Two Weeks</button>
|
<button on:click={() => { loadGraph(43200, 60, false) }}>Month</button>
|
||||||
<button on:click={() => { loadGraph(43200, 60, false) }}>Month</button>
|
<button on:click={() => { loadGraph(131400, 1440, false) }}>Quarter</button>
|
||||||
<button on:click={() => { loadGraph(131400, 1440, false) }}>Quarter</button>
|
<button on:click={() => { loadGraph(262800, 1440, false) }}>Half-year</button>
|
||||||
<button on:click={() => { loadGraph(262800, 1440, false) }}>Half-year</button>
|
<button on:click={() => { loadGraph(525600, 1440, false) }}>Year</button>
|
||||||
<button on:click={() => { loadGraph(525600, 1440, false) }}>Year</button>
|
<button on:click={() => { loadGraph(1051200, 1440, false) }}>Two Years</button>
|
||||||
<button on:click={() => { loadGraph(1051200, 1440, false) }}>Two Years</button>
|
</div>
|
||||||
</div>
|
<Chart bind:this={graphBandwidth} data_type="bytes" legend={false} />
|
||||||
<Chart bind:this={graphBandwidth} data_type="bytes" legend={false} />
|
<Chart bind:this={graphViews} data_type="number" legend={false} />
|
||||||
<Chart bind:this={graphViews} data_type="number" legend={false} />
|
<div class="highlight_dark">
|
||||||
<div class="highlight_dark">
|
Total usage from {start_time} to {end_time}<br/>
|
||||||
Total usage from {start_time} to {end_time}<br/>
|
{formatDataVolume(total_bandwidth, 3)} bandwidth,
|
||||||
{formatDataVolume(total_bandwidth, 3)} bandwidth,
|
{formatDataVolume(total_bandwidth_paid, 3)} paid bandwidth,
|
||||||
{formatDataVolume(total_bandwidth_paid, 3)} paid bandwidth,
|
{formatThousands(total_views, 3)} views and
|
||||||
{formatThousands(total_views, 3)} views and
|
{formatThousands(total_downloads, 3)} downloads
|
||||||
{formatThousands(total_downloads, 3)} downloads
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<a class="button" href="/api/admin/call_stack">Call stack</a>
|
|
||||||
<a class="button" href="/api/admin/heap_profile">Heap profile</a>
|
|
||||||
<a class="button" href="/api/admin/cpu_profile">CPU profile (wait 1 min)</a>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<div class="limit_width">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>DB Time</td>
|
|
||||||
<td>{formatDate(new Date(status.db_time), true, true, true)}</td>
|
|
||||||
<td>DB Latency</td>
|
|
||||||
<td>{formatNumber(status.db_latency / 1000, 3)} ms</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>Pixelstore peers</h3>
|
|
||||||
<div class="table_scroll">
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>Address</td>
|
|
||||||
<td>Pos</td>
|
|
||||||
<td>Alive</td>
|
|
||||||
<td>Err</td>
|
|
||||||
<td>1m</td>
|
|
||||||
<td>5m</td>
|
|
||||||
<td>15m</td>
|
|
||||||
<td>Ping</td>
|
|
||||||
<td>Free</td>
|
|
||||||
<td>Min free</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{#each status.peers as peer}
|
|
||||||
<tr class="peer_row"
|
|
||||||
class:highlight_red={peer.free_space < peer.min_free_space / 2 || !peer.reachable}
|
|
||||||
class:highlight_yellow={peer.free_space < peer.min_free_space}
|
|
||||||
class:highlight_green={peer.reachable}
|
|
||||||
>
|
|
||||||
<td>{peer.address}</td>
|
|
||||||
<td>{peer.position}</td>
|
|
||||||
<td>{peer.reachable}</td>
|
|
||||||
<td>{peer.unreachable_count}</td>
|
|
||||||
<td>{peer.load_1_min.toFixed(1)}</td>
|
|
||||||
<td>{peer.load_5_min.toFixed(1)}</td>
|
|
||||||
<td>{peer.load_15_min.toFixed(1)}</td>
|
|
||||||
<td>{formatDuration(peer.latency, 3)}</td>
|
|
||||||
<td>{formatDataVolume(peer.free_space, 4)}</td>
|
|
||||||
<td>{formatDataVolume(peer.min_free_space, 3)}</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<h3>Pixelstore stats</h3>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>Local reads</td>
|
|
||||||
<td>Local read size</td>
|
|
||||||
<td>Remote reads</td>
|
|
||||||
<td>Remote read size</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>{status.local_reads}</td>
|
|
||||||
<td>{formatDataVolume(status.local_read_size, 4)}</td>
|
|
||||||
<td>{status.remote_reads}</td>
|
|
||||||
<td>{formatDataVolume(status.remote_read_size, 4)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{status.local_reads_per_sec.toPrecision(4)} / s</td>
|
|
||||||
<td>{formatDataVolume(status.local_read_size_per_sec, 4)} / s</td>
|
|
||||||
<td>{status.remote_reads_per_sec.toPrecision(4)} / s</td>
|
|
||||||
<td>{formatDataVolume(status.remote_read_size_per_sec, 4)} /s</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<h3>Socket statistics</h3>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>Watcher</td>
|
|
||||||
<td>Threads</td>
|
|
||||||
<td>Listeners</td>
|
|
||||||
<td>Avg</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>File statistics</td>
|
|
||||||
<td>{status.stats_watcher_threads}</td>
|
|
||||||
<td>{status.stats_watcher_listeners}</td>
|
|
||||||
<td>{(status.stats_watcher_listeners / status.stats_watcher_threads).toPrecision(3)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Downloads</td>
|
|
||||||
<td>{status.download_clients}</td>
|
|
||||||
<td>{status.download_connections}</td>
|
|
||||||
<td>{(status.download_connections / status.download_clients).toPrecision(3)}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<h3>Query statistics</h3>
|
|
||||||
<div class="table_scroll" style="text-align: left;">
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td style="cursor: pointer;" on:click={() => { getStats('query_name') }}>Query</td>
|
|
||||||
<td style="cursor: pointer;" on:click={() => { getStats('calls') }}>Calls</td>
|
|
||||||
<td style="cursor: pointer;" on:click={() => { getStats('average_duration') }}>Avg dur</td>
|
|
||||||
<td style="cursor: pointer;" on:click={() => { getStats('total_duration') }}>Total dur</td>
|
|
||||||
<td>Callers</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="tstat_body">
|
|
||||||
{#each status.query_statistics as q}
|
|
||||||
<tr>
|
|
||||||
<td>{q.query_name}</td>
|
|
||||||
<td>{q.calls}</td>
|
|
||||||
<td>{q.average_duration}ms</td>
|
|
||||||
<td>{formatDuration(q.total_duration, 0)}</td>
|
|
||||||
<td>
|
|
||||||
{#each q.callers as caller}
|
|
||||||
{caller.count}x {caller.name}<br/>
|
|
||||||
{/each}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<br/>
|
||||||
.peer_row {
|
<a class="button" href="/api/admin/call_stack">Call stack</a>
|
||||||
text-align: left;
|
<a class="button" href="/api/admin/heap_profile">Heap profile</a>
|
||||||
}
|
<a class="button" href="/api/admin/cpu_profile">CPU profile (wait 1 min)</a>
|
||||||
</style>
|
<br/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>DB Time</td>
|
||||||
|
<td>{formatDate(new Date(status.db_time), true, true, true)}</td>
|
||||||
|
<td>DB Latency</td>
|
||||||
|
<td>{formatNumber(status.db_latency / 1000, 3)} ms</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Pixelstore peers</h3>
|
||||||
|
<div class="table_scroll">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Address</td>
|
||||||
|
<td>Pos</td>
|
||||||
|
<td>Alive</td>
|
||||||
|
<td>Err</td>
|
||||||
|
<td>1m</td>
|
||||||
|
<td>5m</td>
|
||||||
|
<td>15m</td>
|
||||||
|
<td>Ping</td>
|
||||||
|
<td>Free</td>
|
||||||
|
<td>Min free</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each status.peers as peer}
|
||||||
|
<tr style="text-align: left"
|
||||||
|
class:highlight_red={peer.free_space < peer.min_free_space / 2 || !peer.reachable}
|
||||||
|
class:highlight_yellow={peer.free_space < peer.min_free_space}
|
||||||
|
class:highlight_green={peer.reachable}
|
||||||
|
>
|
||||||
|
<td>{peer.address}</td>
|
||||||
|
<td>{peer.position}</td>
|
||||||
|
<td>{peer.reachable}</td>
|
||||||
|
<td>{peer.unreachable_count}</td>
|
||||||
|
<td>{peer.load_1_min.toFixed(1)}</td>
|
||||||
|
<td>{peer.load_5_min.toFixed(1)}</td>
|
||||||
|
<td>{peer.load_15_min.toFixed(1)}</td>
|
||||||
|
<td>{formatDuration(peer.latency, 3)}</td>
|
||||||
|
<td>{formatDataVolume(peer.free_space, 4)}</td>
|
||||||
|
<td>{formatDataVolume(peer.min_free_space, 3)}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<h3>Pixelstore stats</h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Local reads</td>
|
||||||
|
<td>Local read size</td>
|
||||||
|
<td>Remote reads</td>
|
||||||
|
<td>Remote read size</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{status.local_reads}</td>
|
||||||
|
<td>{formatDataVolume(status.local_read_size, 4)}</td>
|
||||||
|
<td>{status.remote_reads}</td>
|
||||||
|
<td>{formatDataVolume(status.remote_read_size, 4)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{status.local_reads_per_sec.toPrecision(4)} / s</td>
|
||||||
|
<td>{formatDataVolume(status.local_read_size_per_sec, 4)} / s</td>
|
||||||
|
<td>{status.remote_reads_per_sec.toPrecision(4)} / s</td>
|
||||||
|
<td>{formatDataVolume(status.remote_read_size_per_sec, 4)} /s</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3>Socket statistics</h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Watcher</td>
|
||||||
|
<td>Threads</td>
|
||||||
|
<td>Listeners</td>
|
||||||
|
<td>Avg</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>File statistics</td>
|
||||||
|
<td>{status.stats_watcher_threads}</td>
|
||||||
|
<td>{status.stats_watcher_listeners}</td>
|
||||||
|
<td>{(status.stats_watcher_listeners / status.stats_watcher_threads).toPrecision(3)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Downloads</td>
|
||||||
|
<td>{status.download_clients}</td>
|
||||||
|
<td>{status.download_connections}</td>
|
||||||
|
<td>{(status.download_connections / status.download_clients).toPrecision(3)}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3>Query statistics</h3>
|
||||||
|
<div class="table_scroll" style="text-align: left;">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td style="cursor: pointer;" on:click={() => { getStats('query_name') }}>Query</td>
|
||||||
|
<td style="cursor: pointer;" on:click={() => { getStats('calls') }}>Calls</td>
|
||||||
|
<td style="cursor: pointer;" on:click={() => { getStats('average_duration') }}>Avg dur</td>
|
||||||
|
<td style="cursor: pointer;" on:click={() => { getStats('total_duration') }}>Total dur</td>
|
||||||
|
<td>Callers</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tstat_body">
|
||||||
|
{#each status.query_statistics as q}
|
||||||
|
<tr>
|
||||||
|
<td>{q.query_name}</td>
|
||||||
|
<td>{q.calls}</td>
|
||||||
|
<td>{q.average_duration}ms</td>
|
||||||
|
<td>{formatDuration(q.total_duration, 0)}</td>
|
||||||
|
<td>
|
||||||
|
{#each q.callers as caller}
|
||||||
|
{caller.count}x {caller.name}<br/>
|
||||||
|
{/each}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@@ -80,91 +80,89 @@ const delete_ban = async (addr) => {
|
|||||||
onMount(get_bans);
|
onMount(get_bans);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="toolbar" style="text-align: left;">
|
||||||
|
<div class="toolbar_spacer"></div>
|
||||||
|
<button class:button_highlight={creating} on:click={() => {creating = !creating}}>
|
||||||
|
<i class="icon">create</i> Add IP ban
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{#if creating}
|
||||||
|
<div class="highlight_light">
|
||||||
|
<form on:submit|preventDefault={create_ban}>
|
||||||
|
<table class="form">
|
||||||
|
<tr>
|
||||||
|
<td>IP address</td>
|
||||||
|
<td><input type="text" bind:this={new_ban_address}/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Reason</td>
|
||||||
|
<td>
|
||||||
|
<input id="reason_unknown" name="reporter_type" type="radio" bind:group={new_ban_reason} value="unknown" />
|
||||||
|
<label for="reason_unknown">unknown</label>
|
||||||
|
<br/>
|
||||||
|
<input id="reason_copyright" name="reporter_type" type="radio" bind:group={new_ban_reason} value="copyright" />
|
||||||
|
<label for="reason_copyright">copyright</label>
|
||||||
|
<br/>
|
||||||
|
<input id="reason_child_abuse" name="reporter_type" type="radio" bind:group={new_ban_reason} value="child_abuse" />
|
||||||
|
<label for="reason_child_abuse">child_abuse</label>
|
||||||
|
<br/>
|
||||||
|
<input id="reason_terrorism" name="reporter_type" type="radio" bind:group={new_ban_reason} value="terorrism" />
|
||||||
|
<label for="reason_terrorism">terrorism</label>
|
||||||
|
<br/>
|
||||||
|
<input id="reason_gore" name="reporter_type" type="radio" bind:group={new_ban_reason} value="gore" />
|
||||||
|
<label for="reason_gore">gore</label>
|
||||||
|
<br/>
|
||||||
|
<input id="reason_malware" name="reporter_type" type="radio" bind:group={new_ban_reason} value="malware" />
|
||||||
|
<label for="reason_malware">malware</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<button class="button_highlight" type="submit" style="float: right;">
|
||||||
|
<i class="icon">save</i> Save
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
</section>
|
||||||
|
|
||||||
<div class="limit_width">
|
<br/>
|
||||||
<div class="toolbar" style="text-align: left;">
|
|
||||||
<div class="toolbar_spacer"></div>
|
|
||||||
<button class:button_highlight={creating} on:click={() => {creating = !creating}}>
|
|
||||||
<i class="icon">create</i> Add IP ban
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{#if creating}
|
|
||||||
<div class="highlight_light">
|
|
||||||
<form on:submit|preventDefault={create_ban}>
|
|
||||||
<table class="form">
|
|
||||||
<tr>
|
|
||||||
<td>IP address</td>
|
|
||||||
<td><input type="text" bind:this={new_ban_address}/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Reason</td>
|
|
||||||
<td>
|
|
||||||
<input id="reason_unknown" name="reporter_type" type="radio" bind:group={new_ban_reason} value="unknown" />
|
|
||||||
<label for="reason_unknown">unknown</label>
|
|
||||||
<br/>
|
|
||||||
<input id="reason_copyright" name="reporter_type" type="radio" bind:group={new_ban_reason} value="copyright" />
|
|
||||||
<label for="reason_copyright">copyright</label>
|
|
||||||
<br/>
|
|
||||||
<input id="reason_child_abuse" name="reporter_type" type="radio" bind:group={new_ban_reason} value="child_abuse" />
|
|
||||||
<label for="reason_child_abuse">child_abuse</label>
|
|
||||||
<br/>
|
|
||||||
<input id="reason_terrorism" name="reporter_type" type="radio" bind:group={new_ban_reason} value="terorrism" />
|
|
||||||
<label for="reason_terrorism">terrorism</label>
|
|
||||||
<br/>
|
|
||||||
<input id="reason_gore" name="reporter_type" type="radio" bind:group={new_ban_reason} value="gore" />
|
|
||||||
<label for="reason_gore">gore</label>
|
|
||||||
<br/>
|
|
||||||
<input id="reason_malware" name="reporter_type" type="radio" bind:group={new_ban_reason} value="malware" />
|
|
||||||
<label for="reason_malware">malware</label>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<button class="button_highlight" type="submit" style="float: right;">
|
|
||||||
<i class="icon">save</i> Save
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br/>
|
<div class="table_scroll">
|
||||||
|
<table style="text-align: left;">
|
||||||
<div class="table_scroll">
|
<tr>
|
||||||
<table style="text-align: left;">
|
<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>
|
<tr>
|
||||||
<td>Address</td>
|
<td>{row.address}</td>
|
||||||
<td>Reason</td>
|
<td>{row.reason}</td>
|
||||||
<td>Ban time</td>
|
<td>{formatDate(row.ban_time, true, true, false)}</td>
|
||||||
<td>Expire time</td>
|
<td>{formatDate(row.expire_time, true, true, false)}</td>
|
||||||
<td>Offences</td>
|
<td>{row.offences}</td>
|
||||||
<td></td>
|
<td>
|
||||||
|
<button on:click|preventDefault={() => {delete_ban(row.address)}} class="button button_red round">
|
||||||
|
<i class="icon">delete</i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{#each rows as row (row.address)}
|
{/each}
|
||||||
<tr>
|
</table>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@@ -26,7 +26,7 @@ onMount(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>Admin Panel</h1>
|
<h1>Admin Panel</h1>
|
||||||
|
|
||||||
<div class="tab_bar">
|
<div class="tab_bar">
|
||||||
@@ -77,7 +77,7 @@ onMount(() => {
|
|||||||
Update global settings
|
Update global settings
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</header>
|
||||||
|
|
||||||
{#if page === "status"}
|
{#if page === "status"}
|
||||||
<Home></Home>
|
<Home></Home>
|
||||||
|
@@ -173,7 +173,7 @@ onMount(get_coupons)
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="limit_width">
|
<section>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="spinner_container">
|
<div class="spinner_container">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
@@ -221,7 +221,7 @@ onMount(get_coupons)
|
|||||||
{/each}
|
{/each}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
|
@@ -386,18 +386,18 @@ const keydown = (e) => {
|
|||||||
<div>
|
<div>
|
||||||
<!-- If the user is logged in and has used more than 50% of their storage space we will show a progress bar -->
|
<!-- If the user is logged in and has used more than 50% of their storage space we will show a progress bar -->
|
||||||
{#if window.user.username !== "" && window.user.storage_space_used/window.user.subscription.storage_space > 0.5}
|
{#if window.user.username !== "" && window.user.storage_space_used/window.user.subscription.storage_space > 0.5}
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<StorageProgressBar used={window.user.storage_space_used} total={window.user.subscription.storage_space}></StorageProgressBar>
|
<StorageProgressBar used={window.user.storage_space_used} total={window.user.subscription.storage_space}></StorageProgressBar>
|
||||||
</div>
|
</section>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="instruction limit_width" style="margin-top: 0; border-top: none;">
|
<section class="instruction" style="margin-top: 0; border-top: none;">
|
||||||
<span class="big_number">1</span>
|
<span class="big_number">1</span>
|
||||||
<span class="instruction_text">Select files to upload</span>
|
<span class="instruction_text">Select files to upload</span>
|
||||||
<br/>
|
<br/>
|
||||||
You can also drop files on this page from your file manager or
|
You can also drop files on this page from your file manager or
|
||||||
paste an image from your clipboard
|
paste an image from your clipboard
|
||||||
</div>
|
</section>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
<input bind:this={file_input_field} on:change={file_input_change} type="file" name="file" multiple="multiple"/>
|
<input bind:this={file_input_field} on:change={file_input_change} type="file" name="file" multiple="multiple"/>
|
||||||
@@ -416,7 +416,7 @@ const keydown = (e) => {
|
|||||||
<a href="/about#content-policy">content policy</a>.
|
<a href="/about#content-policy">content policy</a>.
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
<div class="instruction limit_width" style="margin-bottom: 0;">
|
<section class="instruction" style="margin-bottom: 0;">
|
||||||
<span class="big_number">2</span>
|
<span class="big_number">2</span>
|
||||||
<span class="instruction_text">Wait for the files to finish uploading</span>
|
<span class="instruction_text">Wait for the files to finish uploading</span>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -426,7 +426,7 @@ const keydown = (e) => {
|
|||||||
<div>ETA {formatDuration(remaining_time, 0)}</div>
|
<div>ETA {formatDuration(remaining_time, 0)}</div>
|
||||||
<div>Rate {formatDataVolume(total_rate, 3)}/s</div>
|
<div>Rate {formatDataVolume(total_rate, 3)}/s</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
<div class="progress_bar_outer" style="margin-bottom: 1.5em;">
|
<div class="progress_bar_outer" style="margin-bottom: 1.5em;">
|
||||||
<div bind:this={progress_bar_inner} class="progress_bar_inner"></div>
|
<div bind:this={progress_bar_inner} class="progress_bar_inner"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -441,10 +441,10 @@ const keydown = (e) => {
|
|||||||
<UploadProgressBar bind:this={file.component} job={file}></UploadProgressBar>
|
<UploadProgressBar bind:this={file.component} job={file}></UploadProgressBar>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<div class="instruction limit_width">
|
<section class="instruction">
|
||||||
<span class="big_number">3</span>
|
<span class="big_number">3</span>
|
||||||
<span class="instruction_text">Share the files</span>
|
<span class="instruction_text">Share the files</span>
|
||||||
</div>
|
</section>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
{#if upload_queue.length > 1}
|
{#if upload_queue.length > 1}
|
||||||
@@ -518,11 +518,11 @@ const keydown = (e) => {
|
|||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
{#if window.user.subscription.name === ""}
|
{#if window.user.subscription.name === ""}
|
||||||
<div class="instruction limit_width">
|
<section>
|
||||||
<span class="big_number">4</span>
|
<div class="instruction">
|
||||||
<span class="instruction_text">Support me on Patreon!</span>
|
<span class="big_number">4</span>
|
||||||
</div>
|
<span class="instruction_text">Support me on Patreon!</span>
|
||||||
<div class="limit_width">
|
</div>
|
||||||
<p>
|
<p>
|
||||||
Pixeldrain is struggling to get by financially. Because anyone
|
Pixeldrain is struggling to get by financially. Because anyone
|
||||||
can upload anything it's hard to find reputable advertisers who
|
can upload anything it's hard to find reputable advertisers who
|
||||||
@@ -537,13 +537,15 @@ const keydown = (e) => {
|
|||||||
help with making pixeldrain the easiest and fastest way to share
|
help with making pixeldrain the easiest and fastest way to share
|
||||||
files online!
|
files online!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
<br/>
|
||||||
<br/>
|
<div style="text-align: center;">
|
||||||
<a href="#pro" class="button big_button" style="min-width: 350px;">
|
<a href="#pro" class="button big_button" style="min-width: 350px;">
|
||||||
<i class="icon">arrow_downward</i>
|
<i class="icon">arrow_downward</i>
|
||||||
Check out Pro
|
Check out Pro
|
||||||
<i class="icon">arrow_downward</i>
|
<i class="icon">arrow_downward</i>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -1,13 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_delete_bucket } from "../filesystem/FilesystemAPI.svelte";
|
import { fs_delete_bucket } from "../filesystem/FilesystemAPI.svelte";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
|
import Expandable from "../util/Expandable.svelte";
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
|
|
||||||
export let bucket
|
export let bucket
|
||||||
let details_hidden = true
|
|
||||||
const expand_bucket = () => {
|
|
||||||
details_hidden = !details_hidden
|
|
||||||
}
|
|
||||||
|
|
||||||
const save_bucket = () => {
|
const save_bucket = () => {
|
||||||
alert("save")
|
alert("save")
|
||||||
@@ -32,21 +29,14 @@ const delete_bucket = async () => {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="bucket">
|
<Expandable>
|
||||||
<div class="bucket_header">
|
<div slot="header">
|
||||||
<a href={'/d/' + bucket.id} class="bucket_title">
|
<a href={'/d/' + bucket.id} class="bucket_title">
|
||||||
<img class="bucket_icon" src="/res/img/mime/folder-remote.png" alt="Bucket icon"/>
|
<img class="bucket_icon" src="/res/img/mime/folder-remote.png" alt="Bucket icon"/>
|
||||||
{bucket.name}
|
{bucket.name}
|
||||||
</a>
|
</a>
|
||||||
<button class="bucket_expand" on:click={expand_bucket}>
|
|
||||||
{#if details_hidden}
|
|
||||||
<i class="icon">expand_more</i>
|
|
||||||
{:else}
|
|
||||||
<i class="icon">expand_less</i>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="bucket_details" class:hidden={details_hidden}>
|
<div>
|
||||||
<form on:submit|preventDefault={save_bucket}>
|
<form on:submit|preventDefault={save_bucket}>
|
||||||
<table class="form">
|
<table class="form">
|
||||||
<tr class="form">
|
<tr class="form">
|
||||||
@@ -66,26 +56,9 @@ const delete_bucket = async () => {
|
|||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Expandable>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.bucket {
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: var(--layer_3_color);
|
|
||||||
transition: box-shadow 0.5s;
|
|
||||||
box-shadow: 1px 1px 5px 0 var(--shadow_color);
|
|
||||||
margin: 1em 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.bucket_header {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
color: var(--text_color);
|
|
||||||
}
|
|
||||||
.bucket_header:hover {
|
|
||||||
background-color: var(--input_color_dark)
|
|
||||||
}
|
|
||||||
.bucket_title {
|
.bucket_title {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
@@ -98,18 +71,4 @@ const delete_bucket = async () => {
|
|||||||
margin: 4px;
|
margin: 4px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
.bucket_expand {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
.bucket_details {
|
|
||||||
display: flex;
|
|
||||||
padding: 0.4em;
|
|
||||||
flex-direction: column;
|
|
||||||
text-decoration: none;
|
|
||||||
border-top: 1px solid var(--layer_3_color_border);
|
|
||||||
color: var(--text_color);
|
|
||||||
}
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -41,51 +41,49 @@ const create_bucket = async () => {
|
|||||||
onMount(get_buckets);
|
onMount(get_buckets);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="toolbar" style="text-align: right;">
|
||||||
|
<button
|
||||||
|
class:button_highlight={creating_bucket}
|
||||||
|
on:click={() => {creating_bucket = !creating_bucket}}
|
||||||
|
>
|
||||||
|
<i class="icon">create_new_folder</i> New bucket
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{#if creating_bucket}
|
||||||
|
<div class="highlight_light">
|
||||||
|
<form on:submit|preventDefault={create_bucket}>
|
||||||
|
<table class="form">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Name
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" bind:this={new_bucket_name}/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<button class="button_highlight" type="submit" style="float: right;">
|
||||||
|
<i class="icon">save</i> Save
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="limit_width">
|
{#each buckets as bucket (bucket.id)}
|
||||||
<div class="toolbar" style="text-align: right;">
|
<UserBucket bucket={bucket} on:refresh={get_buckets}></UserBucket>
|
||||||
<button
|
{/each}
|
||||||
class:button_highlight={creating_bucket}
|
</section>
|
||||||
on:click={() => {creating_bucket = !creating_bucket}}
|
|
||||||
>
|
|
||||||
<i class="icon">create_new_folder</i> New bucket
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{#if creating_bucket}
|
|
||||||
<div class="highlight_light">
|
|
||||||
<form on:submit|preventDefault={create_bucket}>
|
|
||||||
<table class="form">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Name
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input type="text" bind:this={new_bucket_name}/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<button class="button_highlight" type="submit" style="float: right;">
|
|
||||||
<i class="icon">save</i> Save
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#each buckets as bucket}
|
|
||||||
<UserBucket bucket={bucket} on:refresh={get_buckets}></UserBucket>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
|
@@ -82,87 +82,85 @@ const logout = async (key) => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
{#if !loaded}
|
||||||
|
<div class="highlight_yellow">
|
||||||
|
<h2>Warning</h2>
|
||||||
|
<p>
|
||||||
|
API keys are sensitive information. They can be used to gain
|
||||||
|
full control over your account. Do not show your API keys to
|
||||||
|
someone or something you don't trust!
|
||||||
|
</p>
|
||||||
|
<button class="button_red" on:click={load_keys}>
|
||||||
|
<i class="icon">lock_open</i> Show API keys
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="toolbar" style="text-align: left;">
|
||||||
|
<div class="toolbar_spacer"></div>
|
||||||
|
<button on:click={create_key}>
|
||||||
|
<i class="icon">add</i> Create new API key
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="limit_width">
|
<p>
|
||||||
{#if !loaded}
|
If you delete the API key that you are currently using you will be
|
||||||
<div class="highlight_yellow">
|
logged out of your account. API keys expire 90 days after the last
|
||||||
<h2>Warning</h2>
|
time they're used. If you think someone is using your account
|
||||||
<p>
|
without your authorization it's probably a good idea to delete all
|
||||||
API keys are sensitive information. They can be used to gain
|
your keys.
|
||||||
full control over your account. Do not show your API keys to
|
</p>
|
||||||
someone or something you don't trust!
|
</section>
|
||||||
</p>
|
<div class="table_scroll">
|
||||||
<button class="button_red" on:click={load_keys}>
|
<table style="text-align: left;">
|
||||||
<i class="icon">lock_open</i> Show API keys
|
<tr>
|
||||||
</button>
|
<td>Key</td>
|
||||||
</div>
|
<td>Created</td>
|
||||||
{:else}
|
<td>Last used ▼</td>
|
||||||
<div class="toolbar" style="text-align: left;">
|
<td>IP address</td>
|
||||||
<div class="toolbar_spacer"></div>
|
<td></td>
|
||||||
<button on:click={create_key}>
|
</tr>
|
||||||
<i class="icon">add</i> Create new API key
|
{#each rows as row (row.auth_key)}
|
||||||
</button>
|
<tr style="border-bottom: none;">
|
||||||
</div>
|
<td>{row.auth_key}</td>
|
||||||
{/if}
|
<td>{formatDate(row.creation_time, true, true, false)}</td>
|
||||||
|
<td>{formatDate(row.last_used_time, true, true, false)}</td>
|
||||||
<p>
|
<td>{row.creation_ip_address}</td>
|
||||||
If you delete the API key that you are currently using you will be
|
<td>
|
||||||
logged out of your account. API keys expire 90 days after the last
|
<button on:click|preventDefault={() => {logout(row.auth_key)}} class="button button_red round">
|
||||||
time they're used. If you think someone is using your account
|
<i class="icon">delete</i>
|
||||||
without your authorization it's probably a good idea to delete all
|
</button>
|
||||||
your keys.
|
</td>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table_scroll">
|
|
||||||
<table style="text-align: left;">
|
|
||||||
<tr>
|
|
||||||
<td>Key</td>
|
|
||||||
<td>Created</td>
|
|
||||||
<td>Last used ▼</td>
|
|
||||||
<td>IP address</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{#each rows as row (row.auth_key)}
|
<tr>
|
||||||
<tr style="border-bottom: none;">
|
<td colspan="1">
|
||||||
<td>{row.auth_key}</td>
|
{#if row.app_name === "website login"}
|
||||||
<td>{formatDate(row.creation_time, true, true, false)}</td>
|
<img src="/res/img/pixeldrain_32.png" alt="Pixeldrain logo" class="app_icon"/>
|
||||||
<td>{formatDate(row.last_used_time, true, true, false)}</td>
|
Pixeldrain website
|
||||||
<td>{row.creation_ip_address}</td>
|
{:else if row.app_name === "website keys page"}
|
||||||
<td>
|
<i class="icon">vpn_key</i>
|
||||||
<button on:click|preventDefault={() => {logout(row.auth_key)}} class="button button_red round">
|
Pixeldrain keys page
|
||||||
<i class="icon">delete</i>
|
{:else if row.app_name === "sharex"}
|
||||||
</button>
|
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon"/>
|
||||||
</td>
|
ShareX
|
||||||
</tr>
|
{:else if row.app_name === "jdownloader"}
|
||||||
<tr>
|
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon"/>
|
||||||
<td colspan="1">
|
JDownloader
|
||||||
{#if row.app_name === "website login"}
|
{:else}
|
||||||
<img src="/res/img/pixeldrain_32.png" alt="Pixeldrain logo" class="app_icon"/>
|
Unknown app: {row.app_name}
|
||||||
Pixeldrain website
|
{/if}
|
||||||
{:else if row.app_name === "website keys page"}
|
</td>
|
||||||
<i class="icon">vpn_key</i>
|
<td colspan="4">User-Agent: {row.user_agent}</td>
|
||||||
Pixeldrain keys page
|
</tr>
|
||||||
{:else if row.app_name === "sharex"}
|
{/each}
|
||||||
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon"/>
|
</table>
|
||||||
ShareX
|
|
||||||
{:else if row.app_name === "jdownloader"}
|
|
||||||
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon"/>
|
|
||||||
JDownloader
|
|
||||||
{:else}
|
|
||||||
Unknown app: {row.app_name}
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td colspan="4">User-Agent: {row.user_agent}</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@@ -137,29 +137,24 @@ let delete_account = {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<section>
|
||||||
<div class="limit_width">
|
<h2>Change password</h2>
|
||||||
<h2>Change password</h2>
|
<div class="highlight_dark">
|
||||||
<div class="highlight_dark">
|
<Form config={password_change}></Form>
|
||||||
<Form config={password_change}></Form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Change e-mail address</h2>
|
|
||||||
<div class="highlight_dark">
|
|
||||||
<Form config={email_change}></Form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Change name</h2>
|
|
||||||
<div class="highlight_dark">
|
|
||||||
<Form config={name_change}></Form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Delete account</h2>
|
|
||||||
<div class="highlight_dark">
|
|
||||||
<Form config={delete_account}></Form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<h2>Change e-mail address</h2>
|
||||||
</style>
|
<div class="highlight_dark">
|
||||||
|
<Form config={email_change}></Form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Change name</h2>
|
||||||
|
<div class="highlight_dark">
|
||||||
|
<Form config={name_change}></Form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Delete account</h2>
|
||||||
|
<div class="highlight_dark">
|
||||||
|
<Form config={delete_account}></Form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@@ -56,114 +56,113 @@ onMount(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<div class="limit_width">
|
|
||||||
{#if app_name === "jdownloader"}
|
|
||||||
<h2>
|
|
||||||
Connect
|
|
||||||
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon_small"/>
|
|
||||||
JDownloader to your pixeldrain account
|
|
||||||
</h2>
|
|
||||||
<p>
|
|
||||||
To connect JDownloader to pixeldrain you need to generate an API
|
|
||||||
key and enter it in JDownloader's Account Manager.
|
|
||||||
<br/>
|
|
||||||
<strong>Do not show the generated key to anyone</strong>, it can
|
|
||||||
be used to gain access to your pixeldrain account!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{#if !api_key}
|
|
||||||
<div class="center">
|
|
||||||
<button class="button_highlight" on:click={create_key}>
|
|
||||||
<i class="icon">add</i>
|
|
||||||
Generate key
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<h3>Key created</h3>
|
|
||||||
|
|
||||||
<div class="copy_container">
|
|
||||||
<button on:click={copy_key} class="copy_button" class:button_highlight={copied}>
|
|
||||||
<i class="icon">content_copy</i>
|
|
||||||
{#if copied}
|
|
||||||
Copied!
|
|
||||||
{:else}
|
|
||||||
Copy key to clipboard
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
<button on:click={toggle_show_key} class="copy_button" class:button_highlight={show_key !== ""}>
|
|
||||||
<i class="icon">visibility</i>
|
|
||||||
{#if show_key === ""}
|
|
||||||
Show key
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
<input bind:value={show_key} class="copy_textarea" type="text" placeholder="Your key will show up here" disabled={show_key === ""}/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Paste the key in JDownloader to authenticate the app.
|
|
||||||
</p>
|
|
||||||
{:else if app_name === "sharex"}
|
|
||||||
<h2>
|
|
||||||
Connect
|
|
||||||
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon_small"/>
|
|
||||||
ShareX to your pixeldrain account
|
|
||||||
</h2>
|
|
||||||
<p>
|
|
||||||
ShareX is a Screen capture, file sharing and productivity tool.
|
|
||||||
Pixeldrain is supported as a custom uploader. You can <a
|
|
||||||
href="https://getsharex.com/" target="_blank">get ShareX
|
|
||||||
here</a>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here you can download our custom ShareX uploader which uses
|
|
||||||
pixeldrain to upload your files. This uploader is configured to
|
|
||||||
upload files to your personal pixeldrain account. <strong>Do not
|
|
||||||
share the configuration file with anyone</strong>, it contains
|
|
||||||
your account credentials.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="center">
|
|
||||||
<a href="/misc/sharex/pixeldrain.com.sxcu" class="button button_highlight">
|
|
||||||
<i class="icon small">save</i>
|
|
||||||
Download ShareX Uploader
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3>Setting pixeldrain as default uploader</h3>
|
|
||||||
<p>
|
|
||||||
Download the uploader config and choose 'Open file'
|
|
||||||
<br/>
|
|
||||||
<img src="/res/img/sharex_download.png" style="max-width: 100%;" alt=""/><br/>
|
|
||||||
Set pixeldrain.com as active uploader. Choose Yes
|
|
||||||
<br/>
|
|
||||||
<img src="/res/img/sharex_default.png" style="max-width: 100%;" alt=""/><br/>
|
|
||||||
</p>
|
|
||||||
{:else}
|
|
||||||
<h2>Connect an app to your pixeldrain account</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<button on:click={() => {app_name = "jdownloader"}}>
|
|
||||||
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon"/>
|
|
||||||
Connect JDownloader
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button on:click={() => {app_name = "sharex"}}>
|
|
||||||
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon"/>
|
|
||||||
Connect ShareX
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
{#if app_name === "jdownloader"}
|
||||||
|
<h2>
|
||||||
|
Connect
|
||||||
|
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon_small"/>
|
||||||
|
JDownloader to your pixeldrain account
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
To connect JDownloader to pixeldrain you need to generate an API
|
||||||
|
key and enter it in JDownloader's Account Manager.
|
||||||
|
<br/>
|
||||||
|
<strong>Do not show the generated key to anyone</strong>, it can
|
||||||
|
be used to gain access to your pixeldrain account!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{#if !api_key}
|
||||||
|
<div class="center">
|
||||||
|
<button class="button_highlight" on:click={create_key}>
|
||||||
|
<i class="icon">add</i>
|
||||||
|
Generate key
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<h3>Key created</h3>
|
||||||
|
|
||||||
|
<div class="copy_container">
|
||||||
|
<button on:click={copy_key} class="copy_button" class:button_highlight={copied}>
|
||||||
|
<i class="icon">content_copy</i>
|
||||||
|
{#if copied}
|
||||||
|
Copied!
|
||||||
|
{:else}
|
||||||
|
Copy key to clipboard
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
<button on:click={toggle_show_key} class="copy_button" class:button_highlight={show_key !== ""}>
|
||||||
|
<i class="icon">visibility</i>
|
||||||
|
{#if show_key === ""}
|
||||||
|
Show key
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
<input bind:value={show_key} class="copy_textarea" type="text" placeholder="Your key will show up here" disabled={show_key === ""}/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Paste the key in JDownloader to authenticate the app.
|
||||||
|
</p>
|
||||||
|
{:else if app_name === "sharex"}
|
||||||
|
<h2>
|
||||||
|
Connect
|
||||||
|
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon_small"/>
|
||||||
|
ShareX to your pixeldrain account
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
ShareX is a Screen capture, file sharing and productivity tool.
|
||||||
|
Pixeldrain is supported as a custom uploader. You can <a
|
||||||
|
href="https://getsharex.com/" target="_blank">get ShareX
|
||||||
|
here</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Here you can download our custom ShareX uploader which uses
|
||||||
|
pixeldrain to upload your files. This uploader is configured to
|
||||||
|
upload files to your personal pixeldrain account. <strong>Do not
|
||||||
|
share the configuration file with anyone</strong>, it contains
|
||||||
|
your account credentials.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="center">
|
||||||
|
<a href="/misc/sharex/pixeldrain.com.sxcu" class="button button_highlight">
|
||||||
|
<i class="icon small">save</i>
|
||||||
|
Download ShareX Uploader
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Setting pixeldrain as default uploader</h3>
|
||||||
|
<p>
|
||||||
|
Download the uploader config and choose 'Open file'
|
||||||
|
<br/>
|
||||||
|
<img src="/res/img/sharex_download.png" style="max-width: 100%;" alt=""/><br/>
|
||||||
|
Set pixeldrain.com as active uploader. Choose Yes
|
||||||
|
<br/>
|
||||||
|
<img src="/res/img/sharex_default.png" style="max-width: 100%;" alt=""/><br/>
|
||||||
|
</p>
|
||||||
|
{:else}
|
||||||
|
<h2>Connect an app to your pixeldrain account</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button on:click={() => {app_name = "jdownloader"}}>
|
||||||
|
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon"/>
|
||||||
|
Connect JDownloader
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button on:click={() => {app_name = "sharex"}}>
|
||||||
|
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon"/>
|
||||||
|
Connect ShareX
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
|
@@ -174,142 +174,142 @@ onDestroy(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<section>
|
||||||
<div class="limit_width">
|
<h2>Account information</h2>
|
||||||
<h2>Account information</h2>
|
<ul>
|
||||||
<ul>
|
<li>Username: {window.user.username}</li>
|
||||||
<li>Username: {window.user.username}</li>
|
<li>E-mail address: {window.user.email}</li>
|
||||||
<li>E-mail address: {window.user.email}</li>
|
<li>
|
||||||
<li>
|
Supporter level: {window.user.subscription.name}
|
||||||
Supporter level: {window.user.subscription.name}
|
{#if window.user.subscription.type === "patreon"}
|
||||||
{#if window.user.subscription.type === "patreon"}
|
(<a href="https://www.patreon.com/join/pixeldrain/checkout?edit=1">Manage subscription</a>)
|
||||||
(<a href="https://www.patreon.com/join/pixeldrain/checkout?edit=1">Manage subscription</a>)
|
|
||||||
{/if}
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Max file size: {formatDataVolume(window.user.subscription.file_size_limit, 3)}
|
|
||||||
</li>
|
|
||||||
{#if window.user.subscription.file_expiry_days > 0}
|
|
||||||
<li>Files expire after {window.user.subscription.file_expiry_days} days</li>
|
|
||||||
{:else}
|
|
||||||
<li>Files never expire</li>
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{#if window.user.balance_micro_eur !== 0}
|
|
||||||
<li>
|
|
||||||
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
|
||||||
</li>
|
|
||||||
{/if}
|
{/if}
|
||||||
</ul>
|
<ul>
|
||||||
|
<li>
|
||||||
{#if window.user.subscription.storage_space === -1}
|
Max file size: {formatDataVolume(window.user.subscription.file_size_limit, 3)}
|
||||||
Storage space used: {formatDataVolume(storage_space_used, 3)}<br/>
|
</li>
|
||||||
{:else}
|
{#if window.user.subscription.file_expiry_days > 0}
|
||||||
<StorageProgressBar used={storage_space_used} total={window.user.subscription.storage_space}></StorageProgressBar>
|
<li>Files expire after {window.user.subscription.file_expiry_days} days</li>
|
||||||
|
{:else}
|
||||||
|
<li>Files never expire</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{#if window.user.balance_micro_eur !== 0}
|
||||||
|
<li>
|
||||||
|
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
||||||
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
|
</ul>
|
||||||
|
|
||||||
{#if transfer_cap === -1}
|
{#if window.user.subscription.storage_space === -1}
|
||||||
Paid transfers in the last 30 days: {formatDataVolume(transfer_used, 3)}<br/>
|
Storage space used: {formatDataVolume(storage_space_used, 3)}<br/>
|
||||||
{:else}
|
{:else}
|
||||||
Paid transfers:
|
<StorageProgressBar used={storage_space_used} total={window.user.subscription.storage_space}></StorageProgressBar>
|
||||||
{formatDataVolume(transfer_used, 3)}
|
{/if}
|
||||||
out of
|
|
||||||
{formatDataVolume(transfer_cap, 3)}
|
|
||||||
(<a href="/user/subscription">Set your transfer limit on the subscription page</a>)
|
|
||||||
<HotlinkProgressBar used={transfer_used} total={transfer_cap}></HotlinkProgressBar>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<h3>Exports</h3>
|
{#if transfer_cap === -1}
|
||||||
<div style="text-align: center;">
|
Paid transfers in the last 30 days: {formatDataVolume(transfer_used, 3)}<br/>
|
||||||
<a href="/user/export/files" class="button">
|
{:else}
|
||||||
<i class="icon">list</i>
|
Paid transfers:
|
||||||
Export uploaded files to CSV
|
{formatDataVolume(transfer_used, 3)}
|
||||||
</a>
|
out of
|
||||||
<a href="/user/export/lists" class="button">
|
{formatDataVolume(transfer_cap, 3)}
|
||||||
<i class="icon">list</i>
|
(<a href="/user/subscription">Set your transfer limit on the subscription page</a>)
|
||||||
Export created lists to CSV
|
<HotlinkProgressBar used={transfer_used} total={transfer_cap}></HotlinkProgressBar>
|
||||||
</a>
|
{/if}
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Statistics</h2>
|
<h3>Exports</h3>
|
||||||
<p>
|
<div style="text-align: center;">
|
||||||
Here you can see how often your files are viewed, downloaded
|
<a href="/user/export/files" class="button">
|
||||||
and how much bandwidth they consume. The buttons at the top
|
<i class="icon">list</i>
|
||||||
can be pressed to adjust the timeframe. If you choose 'Day'
|
Export uploaded files to CSV
|
||||||
the statistics will be updated periodically. No need to
|
</a>
|
||||||
refresh the page.
|
<a href="/user/export/lists" class="button">
|
||||||
</p>
|
<i class="icon">list</i>
|
||||||
|
Export created lists to CSV
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="highlight_light">
|
|
||||||
<button
|
<h2>Statistics</h2>
|
||||||
on:click={() => { update_graphs(1440, 1, true) }}
|
<p>
|
||||||
class:button_highlight={graph_timespan == 1440}>
|
Here you can see how often your files are viewed, downloaded
|
||||||
Day (1m)
|
and how much bandwidth they consume. The buttons at the top
|
||||||
</button>
|
can be pressed to adjust the timeframe. If you choose 'Day'
|
||||||
<button
|
the statistics will be updated periodically. No need to
|
||||||
on:click={() => { update_graphs(10080, 10, false) }}
|
refresh the page.
|
||||||
class:button_highlight={graph_timespan == 10080}>
|
</p>
|
||||||
Week (10m)
|
</section>
|
||||||
</button>
|
|
||||||
<button
|
<div class="highlight_light">
|
||||||
on:click={() => { update_graphs(20160, 60, false) }}
|
<button
|
||||||
class:button_highlight={graph_timespan == 20160}>
|
on:click={() => { update_graphs(1440, 1, true) }}
|
||||||
Two Weeks (1h)
|
class:button_highlight={graph_timespan == 1440}>
|
||||||
</button>
|
Day (1m)
|
||||||
<button
|
</button>
|
||||||
on:click={() => { update_graphs(43200, 1440, false) }}
|
<button
|
||||||
class:button_highlight={graph_timespan == 43200}>
|
on:click={() => { update_graphs(10080, 10, false) }}
|
||||||
Month (1d)
|
class:button_highlight={graph_timespan == 10080}>
|
||||||
</button>
|
Week (10m)
|
||||||
<button
|
</button>
|
||||||
on:click={() => { update_graphs(131400, 1440, false) }}
|
<button
|
||||||
class:button_highlight={graph_timespan == 131400}>
|
on:click={() => { update_graphs(20160, 60, false) }}
|
||||||
Quarter (1d)
|
class:button_highlight={graph_timespan == 20160}>
|
||||||
</button>
|
Two Weeks (1h)
|
||||||
<button
|
</button>
|
||||||
on:click={() => { update_graphs(525600, 1440, false) }}
|
<button
|
||||||
class:button_highlight={graph_timespan == 525600}>
|
on:click={() => { update_graphs(43200, 1440, false) }}
|
||||||
Year (1d)
|
class:button_highlight={graph_timespan == 43200}>
|
||||||
</button>
|
Month (1d)
|
||||||
<button
|
</button>
|
||||||
on:click={() => { update_graphs(1051200, 1440, false) }}
|
<button
|
||||||
class:button_highlight={graph_timespan == 1051200}>
|
on:click={() => { update_graphs(131400, 1440, false) }}
|
||||||
Two Years (1d)
|
class:button_highlight={graph_timespan == 131400}>
|
||||||
</button>
|
Quarter (1d)
|
||||||
<br/>
|
</button>
|
||||||
Total usage from {time_start} to {time_end}<br/>
|
<button
|
||||||
{formatThousands(total_views)} views,
|
on:click={() => { update_graphs(525600, 1440, false) }}
|
||||||
{formatThousands(total_downloads)} downloads,
|
class:button_highlight={graph_timespan == 525600}>
|
||||||
{formatDataVolume(total_bandwidth, 3)} bandwidth and
|
Year (1d)
|
||||||
{formatDataVolume(total_transfer_paid, 3)} paid transfers
|
</button>
|
||||||
</div>
|
<button
|
||||||
<div class="limit_width">
|
on:click={() => { update_graphs(1051200, 1440, false) }}
|
||||||
<h3>Premium transfers and total bandwidth usage</h3>
|
class:button_highlight={graph_timespan == 1051200}>
|
||||||
<p>
|
Two Years (1d)
|
||||||
A premium transfer is when a file is downloaded using the data cap
|
</button>
|
||||||
on your subscription plan. These can be files you downloaded from
|
<br/>
|
||||||
other people, or other people downloading your files if you have
|
Total usage from {time_start} to {time_end}<br/>
|
||||||
bandwidth sharing enabled. Bandwidth sharing can be changed on
|
{formatThousands(total_views)} views,
|
||||||
<a href="/user/subscription">the subscription page</a>.
|
{formatThousands(total_downloads)} downloads,
|
||||||
</p>
|
{formatDataVolume(total_bandwidth, 3)} bandwidth and
|
||||||
<p>
|
{formatDataVolume(total_transfer_paid, 3)} paid transfers
|
||||||
Total bandwidth usage is the combined bandwidth usage of all the
|
|
||||||
files on your account. This includes paid transfers.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Chart bind:this={graph_bandwidth} data_type="bytes"/>
|
|
||||||
<div class="limit_width">
|
|
||||||
<h3>Views and downloads</h3>
|
|
||||||
<p>
|
|
||||||
A view is counted when someone visits the download page of one of
|
|
||||||
your files. Views are unique per user per file.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Downloads are counted when a user clicks the download button on one
|
|
||||||
of your files. It does not matter whether the download is completed
|
|
||||||
or not, only the start of the download is counted.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Chart bind:this={graph_views_downloads} data_type="number"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<section>
|
||||||
|
<h3>Premium transfers and total bandwidth usage</h3>
|
||||||
|
<p>
|
||||||
|
A premium transfer is when a file is downloaded using the data cap
|
||||||
|
on your subscription plan. These can be files you downloaded from
|
||||||
|
other people, or other people downloading your files if you have
|
||||||
|
bandwidth sharing enabled. Bandwidth sharing can be changed on
|
||||||
|
<a href="/user/subscription">the subscription page</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Total bandwidth usage is the combined bandwidth usage of all the
|
||||||
|
files on your account. This includes paid transfers.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<Chart bind:this={graph_bandwidth} data_type="bytes"/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Views and downloads</h3>
|
||||||
|
<p>
|
||||||
|
A view is counted when someone visits the download page of one of
|
||||||
|
your files. Views are unique per user per file.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Downloads are counted when a user clicks the download button on one
|
||||||
|
of your files. It does not matter whether the download is completed
|
||||||
|
or not, only the start of the download is counted.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<Chart bind:this={graph_views_downloads} data_type="number"/>
|
||||||
|
@@ -8,29 +8,27 @@ export let used = 0
|
|||||||
$: frac = used / total
|
$: frac = used / total
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<ProgressBar total={total} used={used}></ProgressBar>
|
||||||
<ProgressBar total={total} used={used}></ProgressBar>
|
|
||||||
|
|
||||||
{#if frac > 0.99}
|
{#if frac > 0.99}
|
||||||
<div class="highlight_red">
|
<div class="highlight_red">
|
||||||
You have used all of your data cap. People can still download your
|
You have used all of your data cap. People can still download your
|
||||||
files, but not directly from the API anymore. The file viewer shows
|
files, but not directly from the API anymore. The file viewer shows
|
||||||
ads on your files and download speeds are limited.
|
ads on your files and download speeds are limited.
|
||||||
<br/>
|
<br/>
|
||||||
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
||||||
Upgrade options
|
Upgrade options
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{:else if frac > 0.8}
|
{:else if frac > 0.8}
|
||||||
<div class="highlight_yellow">
|
<div class="highlight_yellow">
|
||||||
You have used {(frac*100).toFixed(0)}% of your data cap. If your
|
You have used {(frac*100).toFixed(0)}% of your data cap. If your
|
||||||
data runs out people won't be able to download your files directly
|
data runs out people won't be able to download your files directly
|
||||||
from the API anymore, ads will be shown on the file viewer and
|
from the API anymore, ads will be shown on the file viewer and
|
||||||
transfer rates will be limited.
|
transfer rates will be limited.
|
||||||
<br/>
|
<br/>
|
||||||
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
||||||
Upgrade options
|
Upgrade options
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
|
@@ -33,7 +33,7 @@ onMount(() => {
|
|||||||
|
|
||||||
<svelte:window on:popstate={get_page} />
|
<svelte:window on:popstate={get_page} />
|
||||||
|
|
||||||
<div class="checkers inset">
|
<header>
|
||||||
<h1>Welcome home, {window.user.username}!</h1>
|
<h1>Welcome home, {window.user.username}!</h1>
|
||||||
|
|
||||||
<div class="tab_bar">
|
<div class="tab_bar">
|
||||||
@@ -75,7 +75,7 @@ onMount(() => {
|
|||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</header>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
{#if page === "home"}
|
{#if page === "home"}
|
||||||
|
@@ -7,56 +7,54 @@ export let used = 0
|
|||||||
$: frac = used / total
|
$: frac = used / total
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
Storage:
|
||||||
Storage:
|
{formatDataVolume(used, 3)}
|
||||||
{formatDataVolume(used, 3)}
|
out of
|
||||||
out of
|
{formatDataVolume(total, 3)}
|
||||||
{formatDataVolume(total, 3)}
|
<br/>
|
||||||
<br/>
|
<ProgressBar total={total} used={used}></ProgressBar>
|
||||||
<ProgressBar total={total} used={used}></ProgressBar>
|
|
||||||
|
|
||||||
{#if frac > 2.0}
|
{#if frac > 2.0}
|
||||||
<div class="highlight_red">
|
<div class="highlight_red">
|
||||||
<span class="warn_text">You are using more than 200% of your allowed storage space!</span>
|
<span class="warn_text">You are using more than 200% of your allowed storage space!</span>
|
||||||
<p>
|
<p>
|
||||||
We have started deleting your files to free up space. If you do
|
We have started deleting your files to free up space. If you do
|
||||||
not want to lose any more files please upgrade to a storage plan
|
not want to lose any more files please upgrade to a storage plan
|
||||||
which supports the volume of storage which you need:
|
which supports the volume of storage which you need:
|
||||||
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
||||||
Upgrade options
|
Upgrade options
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{:else if frac > 0.99}
|
{:else if frac > 0.99}
|
||||||
<div class="highlight_red">
|
<div class="highlight_red">
|
||||||
<p>
|
<p>
|
||||||
You have used all of your storage space. You won't be able to
|
You have used all of your storage space. You won't be able to
|
||||||
upload new files anymore. Please upgrade to a higher support
|
upload new files anymore. Please upgrade to a higher support
|
||||||
tier to continue uploading files:
|
tier to continue uploading files:
|
||||||
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
||||||
Upgrade options
|
Upgrade options
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Your files will not be deleted any sooner than normal at this
|
Your files will not be deleted any sooner than normal at this
|
||||||
moment. When your storage usage is over 200% we will start
|
moment. When your storage usage is over 200% we will start
|
||||||
deleting your files to free up the space.
|
deleting your files to free up the space.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{:else if frac > 0.8}
|
{:else if frac > 0.8}
|
||||||
<div class="highlight_yellow">
|
<div class="highlight_yellow">
|
||||||
<p>
|
<p>
|
||||||
You have used {(frac*100).toFixed(0)}% of your
|
You have used {(frac*100).toFixed(0)}% of your
|
||||||
storage space. If your storage space runs out you won't be able
|
storage space. If your storage space runs out you won't be able
|
||||||
to upload new files anymore. Please upgrade to a higher support
|
to upload new files anymore. Please upgrade to a higher support
|
||||||
tier to continue uploading files:
|
tier to continue uploading files:
|
||||||
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain">
|
||||||
Upgrade options
|
Upgrade options
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.warn_text {
|
.warn_text {
|
||||||
|
@@ -74,170 +74,169 @@ onMount(load_tranfer_used)
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
|
||||||
<div class="limit_width">
|
|
||||||
<h2>Manage subscription</h2>
|
|
||||||
{#if window.user.subscription.type !== "patreon"}
|
|
||||||
<p>
|
|
||||||
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
When your prepaid subscription is active you will be charged daily
|
|
||||||
based on usage. Hotlink bandwidth is charged per TB based on the
|
|
||||||
usage of the previous day. The amount charged for storage each day
|
|
||||||
is your storage usage at the end of the day multiplied by the
|
|
||||||
storage price (€4 / TB) and divided by the average number of days in
|
|
||||||
a month (30.4375). So if you have exactly 1 TB on your account you
|
|
||||||
will be charged €0.131416838 per day.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The prepaid subscription will stay active for as long as you have
|
|
||||||
credit on your account. When you reach negative balance the
|
|
||||||
subscription will automatically end. You will need a positive
|
|
||||||
balance to activate the subscription again.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Prepaid plans</h3>
|
<section>
|
||||||
{#if result !== ""}
|
<h2>Manage subscription</h2>
|
||||||
<div class:highlight_green={result_success} class:highlight_red={!result_success}>
|
{#if window.user.subscription.type !== "patreon"}
|
||||||
{result}
|
<p>
|
||||||
</div>
|
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
||||||
{/if}
|
</p>
|
||||||
|
<p>
|
||||||
|
When your prepaid subscription is active you will be charged daily
|
||||||
|
based on usage. Hotlink bandwidth is charged per TB based on the
|
||||||
|
usage of the previous day. The amount charged for storage each day
|
||||||
|
is your storage usage at the end of the day multiplied by the
|
||||||
|
storage price (€4 / TB) and divided by the average number of days in
|
||||||
|
a month (30.4375). So if you have exactly 1 TB on your account you
|
||||||
|
will be charged €0.131416838 per day.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The prepaid subscription will stay active for as long as you have
|
||||||
|
credit on your account. When you reach negative balance the
|
||||||
|
subscription will automatically end. You will need a positive
|
||||||
|
balance to activate the subscription again.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="feat_table">
|
<h3>Prepaid plans</h3>
|
||||||
<div>
|
{#if result !== ""}
|
||||||
<div class="feat_label" class:feat_highlight={subscription === "prepaid"}>
|
<div class:highlight_green={result_success} class:highlight_red={!result_success}>
|
||||||
Prepaid<br/>
|
{result}
|
||||||
{#if subscription === "prepaid"}
|
|
||||||
Currently active
|
|
||||||
{:else}
|
|
||||||
<button on:click={() => {subscription = "prepaid"; update("subscription")}}>
|
|
||||||
<i class="icon">attach_money</i>
|
|
||||||
Activate
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="feat_normal round_tr">
|
|
||||||
<ul>
|
|
||||||
<li>Base price of €1 per month</li>
|
|
||||||
<li>€4 per TB per month for storage</li>
|
|
||||||
<li>€2 per TB for data transfer</li>
|
|
||||||
<li>Files never expire as long as subscription is active</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="feat_label" class:feat_highlight={subscription === "prepaid_temp_storage_120d"}>
|
|
||||||
120 days storage<br/>
|
|
||||||
{#if subscription === "prepaid_temp_storage_120d"}
|
|
||||||
Currently active
|
|
||||||
{:else}
|
|
||||||
<button on:click={() => {subscription = "prepaid_temp_storage_120d"; update("subscription")}}>
|
|
||||||
<i class="icon">attach_money</i>
|
|
||||||
Activate
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="feat_normal">
|
|
||||||
<ul>
|
|
||||||
<li>Base price of €1 per month</li>
|
|
||||||
<li>€2 per TB per month for storage</li>
|
|
||||||
<li>€2 per TB for data transfer</li>
|
|
||||||
<li>Files expire 120 days after the last time they're viewed</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="feat_label" class:feat_highlight={subscription === "prepaid_temp_storage_60d"}>
|
|
||||||
60 days storage<br/>
|
|
||||||
{#if subscription === "prepaid_temp_storage_60d"}
|
|
||||||
Currently active
|
|
||||||
{:else}
|
|
||||||
<button on:click={() => {subscription = "prepaid_temp_storage_60d"; update("subscription")}}>
|
|
||||||
<i class="icon">attach_money</i>
|
|
||||||
Activate
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="feat_normal">
|
|
||||||
<ul>
|
|
||||||
<li>Base price of €1 per month</li>
|
|
||||||
<li>€1 per TB per month for storage</li>
|
|
||||||
<li>€2 per TB for data transfer</li>
|
|
||||||
<li>Files expire 60 days after the last time they're viewed</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="feat_label" class:feat_highlight={subscription === ""}>
|
|
||||||
Free<br/>
|
|
||||||
{#if subscription === ""}
|
|
||||||
Currently active
|
|
||||||
{:else}
|
|
||||||
<button on:click={() => {subscription = ""; update("subscription")}}>
|
|
||||||
<i class="icon">money_off</i>
|
|
||||||
Activate
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="feat_normal round_br">
|
|
||||||
<ul>
|
|
||||||
<li>Standard free plan, files expire after 30 days.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<h3>Bandwidth sharing</h3>
|
<div class="feat_table">
|
||||||
{#if hotlinking}
|
<div>
|
||||||
<button on:click={() => { hotlinking = false; update("limits") }}>
|
<div class="feat_label" class:feat_highlight={subscription === "prepaid"}>
|
||||||
<i class="icon green">check</i> ON (click to turn off)
|
Prepaid<br/>
|
||||||
</button>
|
{#if subscription === "prepaid"}
|
||||||
{:else}
|
Currently active
|
||||||
<button on:click={() => { hotlinking = true; update("limits") }}>
|
{:else}
|
||||||
<i class="icon red">close</i> OFF (click to turn on)
|
<button on:click={() => {subscription = "prepaid"; update("subscription")}}>
|
||||||
</button>
|
<i class="icon">attach_money</i>
|
||||||
{/if}
|
Activate
|
||||||
<p>
|
</button>
|
||||||
When bandwidth sharing is enabled all the bandwidth that your files
|
{/if}
|
||||||
use will be subtracted from your data cap. Advertisements will be
|
</div>
|
||||||
disabled on the download pages for your files and download speed
|
<div class="feat_normal round_tr">
|
||||||
will be unlimited. The rate limiting captcha for files is also
|
<ul>
|
||||||
disabled when bandwidth sharing is on. You can directly embed your
|
<li>Base price of €1 per month</li>
|
||||||
file's download link anywhere, you don't need to use the file viewer
|
<li>€4 per TB per month for storage</li>
|
||||||
page.
|
<li>€2 per TB for data transfer</li>
|
||||||
</p>
|
<li>Files never expire as long as subscription is active</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="feat_label" class:feat_highlight={subscription === "prepaid_temp_storage_120d"}>
|
||||||
|
120 days storage<br/>
|
||||||
|
{#if subscription === "prepaid_temp_storage_120d"}
|
||||||
|
Currently active
|
||||||
|
{:else}
|
||||||
|
<button on:click={() => {subscription = "prepaid_temp_storage_120d"; update("subscription")}}>
|
||||||
|
<i class="icon">attach_money</i>
|
||||||
|
Activate
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="feat_normal">
|
||||||
|
<ul>
|
||||||
|
<li>Base price of €1 per month</li>
|
||||||
|
<li>€2 per TB per month for storage</li>
|
||||||
|
<li>€2 per TB for data transfer</li>
|
||||||
|
<li>Files expire 120 days after the last time they're viewed</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="feat_label" class:feat_highlight={subscription === "prepaid_temp_storage_60d"}>
|
||||||
|
60 days storage<br/>
|
||||||
|
{#if subscription === "prepaid_temp_storage_60d"}
|
||||||
|
Currently active
|
||||||
|
{:else}
|
||||||
|
<button on:click={() => {subscription = "prepaid_temp_storage_60d"; update("subscription")}}>
|
||||||
|
<i class="icon">attach_money</i>
|
||||||
|
Activate
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="feat_normal">
|
||||||
|
<ul>
|
||||||
|
<li>Base price of €1 per month</li>
|
||||||
|
<li>€1 per TB per month for storage</li>
|
||||||
|
<li>€2 per TB for data transfer</li>
|
||||||
|
<li>Files expire 60 days after the last time they're viewed</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="feat_label" class:feat_highlight={subscription === ""}>
|
||||||
|
Free<br/>
|
||||||
|
{#if subscription === ""}
|
||||||
|
Currently active
|
||||||
|
{:else}
|
||||||
|
<button on:click={() => {subscription = ""; update("subscription")}}>
|
||||||
|
<i class="icon">money_off</i>
|
||||||
|
Activate
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="feat_normal round_br">
|
||||||
|
<ul>
|
||||||
|
<li>Standard free plan, files expire after 30 days.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<h3>Bill shock limit</h3>
|
<h3>Bandwidth sharing</h3>
|
||||||
<p>
|
{#if hotlinking}
|
||||||
Billshock limit in gigabytes per month (1 TB = 1000 GB). Set to 0 to disable.
|
<button on:click={() => { hotlinking = false; update("limits") }}>
|
||||||
</p>
|
<i class="icon green">check</i> ON (click to turn off)
|
||||||
<form on:submit|preventDefault={() => {update("limits")}} class="billshock_container">
|
</button>
|
||||||
<input type="number" bind:value={transfer_cap} step="100" min="0"/>
|
{:else}
|
||||||
<div style="margin: 0.5em;">GB</div>
|
<button on:click={() => { hotlinking = true; update("limits") }}>
|
||||||
<button type="submit">
|
<i class="icon red">close</i> OFF (click to turn on)
|
||||||
<i class="icon">save</i> Save
|
</button>
|
||||||
</button>
|
{/if}
|
||||||
</form>
|
<p>
|
||||||
|
When bandwidth sharing is enabled all the bandwidth that your files
|
||||||
|
use will be subtracted from your data cap. Advertisements will be
|
||||||
|
disabled on the download pages for your files and download speed
|
||||||
|
will be unlimited. The rate limiting captcha for files is also
|
||||||
|
disabled when bandwidth sharing is on. You can directly embed your
|
||||||
|
file's download link anywhere, you don't need to use the file viewer
|
||||||
|
page.
|
||||||
|
</p>
|
||||||
|
|
||||||
Bandwidth used in the last 30 days: {formatDataVolume(transfer_used, 3)},
|
<h3>Bill shock limit</h3>
|
||||||
new limit: {formatDataVolume(transfer_cap*1e9, 3)}
|
<p>
|
||||||
<ProgressBar used={transfer_used} total={transfer_cap*1e9}></ProgressBar>
|
Billshock limit in gigabytes per month (1 TB = 1000 GB). Set to 0 to disable.
|
||||||
<p>
|
</p>
|
||||||
The billshock limit limits how much bandwidth your account can use
|
<form on:submit|preventDefault={() => {update("limits")}} class="billshock_container">
|
||||||
in a 30 day window. When this limit is reached files will show ads
|
<input type="number" bind:value={transfer_cap} step="100" min="0"/>
|
||||||
again and can only be downloaded from the file viewer page. This is
|
<div style="margin: 0.5em;">GB</div>
|
||||||
mostly useful for prepaid plans, but it works for patreon plans too.
|
<button type="submit">
|
||||||
Set to 0 to disable the limit.
|
<i class="icon">save</i> Save
|
||||||
</p>
|
</button>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
|
||||||
|
Bandwidth used in the last 30 days: {formatDataVolume(transfer_used, 3)},
|
||||||
|
new limit: {formatDataVolume(transfer_cap*1e9, 3)}
|
||||||
|
<ProgressBar used={transfer_used} total={transfer_cap*1e9}></ProgressBar>
|
||||||
|
<p>
|
||||||
|
The billshock limit limits how much bandwidth your account can use
|
||||||
|
in a 30 day window. When this limit is reached files will show ads
|
||||||
|
again and can only be downloaded from the file viewer page. This is
|
||||||
|
mostly useful for prepaid plans, but it works for patreon plans too.
|
||||||
|
Set to 0 to disable the limit.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
|
@@ -120,157 +120,156 @@ onMount(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
{#if loading}
|
||||||
{#if loading}
|
<div class="spinner_container">
|
||||||
<div class="spinner_container">
|
<Spinner />
|
||||||
<Spinner />
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
|
||||||
<div class="limit_width">
|
<section>
|
||||||
<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,
|
||||||
Lightning network (<a
|
Lightning network (<a
|
||||||
href="https://btcpay.pixeldrain.com/embed/uS2mbWjXUuaAqMh8XLjkjwi8oehFuxeBZxekMxv68LN/BTC/ln"
|
href="https://btcpay.pixeldrain.com/embed/uS2mbWjXUuaAqMh8XLjkjwi8oehFuxeBZxekMxv68LN/BTC/ln"
|
||||||
target="_blank">node info</a>) and Dogecoin. You must pay the full
|
target="_blank">node info</a>) and Dogecoin. You must pay the full
|
||||||
amount as stated on the invoice, else your payment will fail.
|
amount as stated on the invoice, else your payment will fail.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Do note that it is not possible to withdraw coins from your
|
Do note that it is not possible to withdraw coins from your
|
||||||
pixeldrain account. It's not a wallet. Any amount of money you
|
pixeldrain account. It's not a wallet. Any amount of money you
|
||||||
deposit has to be used up.
|
deposit has to be used up.
|
||||||
</p>
|
</p>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
Deposit amount €
|
Deposit amount €
|
||||||
<input type="number" bind:value={credit_amount} min="1"/>
|
<input type="number" bind:value={credit_amount} min="1"/>
|
||||||
<br/>
|
<br/>
|
||||||
Pay with:<br/>
|
Pay with:<br/>
|
||||||
<button on:click={() => {checkout("btc")}}>
|
<button on:click={() => {checkout("btc")}}>
|
||||||
<span class="icon_unicode">₿</span> Bitcoin
|
<span class="icon_unicode">₿</span> Bitcoin
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {checkout("btc_lightning")}}>
|
<button on:click={() => {checkout("btc_lightning")}}>
|
||||||
<i class="icon">bolt</i> Lightning network
|
<i class="icon">bolt</i> Lightning network
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {checkout("doge")}}>
|
<button on:click={() => {checkout("doge")}}>
|
||||||
<span class="icon_unicode">Ð</span> Dogecoin
|
<span class="icon_unicode">Ð</span> Dogecoin
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h3>Open invoices</h3>
|
||||||
|
<div class="table_scroll">
|
||||||
|
<table style="text-align: left;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Created</td>
|
||||||
|
<td>Amount</td>
|
||||||
|
<td>Status</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each invoices as row (row.id)}
|
||||||
|
{#if row.status === "New" ||
|
||||||
|
row.status === "InvoiceCreated" ||
|
||||||
|
row.status === "InvoiceProcessing" ||
|
||||||
|
show_expired
|
||||||
|
}
|
||||||
|
<tr>
|
||||||
|
<td>{formatDate(row.time, true, true, false)}</td>
|
||||||
|
<td><Euro amount={row.amount}></Euro></td>
|
||||||
|
<td>
|
||||||
|
{#if row.status === "InvoiceCreated"}
|
||||||
|
New (waiting for payment)
|
||||||
|
{:else if row.status === "InvoiceProcessing"}
|
||||||
|
Payment received, waiting for confirmations
|
||||||
|
{:else if row.status === "InvoiceSettled"}
|
||||||
|
Paid
|
||||||
|
{:else if row.status === "InvoiceExpired"}
|
||||||
|
Expired
|
||||||
|
{:else}
|
||||||
|
{row.status}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if row.status === "New" || row.status === "InvoiceCreated"}
|
||||||
|
<a href={row.checkout_url} class="button button_highlight">
|
||||||
|
<i class="icon">paid</i> Pay
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<button on:click={() => {show_expired = !show_expired}}>
|
||||||
|
{#if show_expired}
|
||||||
|
Hide
|
||||||
|
{:else}
|
||||||
|
Show
|
||||||
|
{/if}
|
||||||
|
expired and settled invoices
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Transaction log</h2>
|
||||||
|
<p>
|
||||||
|
Here is a log of all transactions on your account balance.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{#each months as month}
|
||||||
|
<h3>{month.month}</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Subscription charge: <Euro amount={month.total_subscription_charge}></Euro></li>
|
||||||
|
<li>Storage charge: <Euro amount={month.total_storage_charge}></Euro></li>
|
||||||
|
<li>Bandwidth charge: <Euro amount={month.total_bandwidth_charge}></Euro></li>
|
||||||
|
<li>Total charge: <Euro amount={month.total_deducted}></Euro></li>
|
||||||
|
<li>Deposited: <Euro amount={month.total_deposited}></Euro></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<h3>Open invoices</h3>
|
|
||||||
<div class="table_scroll">
|
<div class="table_scroll">
|
||||||
<table style="text-align: left;">
|
<table style="text-align: left;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Created</td>
|
<td>Time</td>
|
||||||
<td>Amount</td>
|
<td>Balance</td>
|
||||||
<td>Status</td>
|
<td>Subscription</td>
|
||||||
|
<td colspan="2">Storage</td>
|
||||||
|
<td colspan="2">Bandwidth</td>
|
||||||
|
<td>Deposited</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>Charged</td>
|
||||||
|
<td>Charged</td>
|
||||||
|
<td>Used</td>
|
||||||
|
<td>Charged</td>
|
||||||
|
<td>Used</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each invoices as row (row.id)}
|
{#each month.rows as row}
|
||||||
{#if row.status === "New" ||
|
<tr>
|
||||||
row.status === "InvoiceCreated" ||
|
<td>{formatDate(row.time, true, true, false)}</td>
|
||||||
row.status === "InvoiceProcessing" ||
|
<td><Euro amount={row.new_balance}></Euro></td>
|
||||||
show_expired
|
<td><Euro amount={row.subscription_charge} precision="4"></Euro></td>
|
||||||
}
|
<td><Euro amount={row.storage_charge} precision="4"></Euro></td>
|
||||||
<tr>
|
<td>{formatDataVolume(row.storage_used, 3)}</td>
|
||||||
<td>{formatDate(row.time, true, true, false)}</td>
|
<td><Euro amount={row.bandwidth_charge} precision="4"></Euro></td>
|
||||||
<td><Euro amount={row.amount}></Euro></td>
|
<td>{formatDataVolume(row.bandwidth_used, 3)}</td>
|
||||||
<td>
|
<td><Euro amount={row.deposit_amount}></Euro></td>
|
||||||
{#if row.status === "InvoiceCreated"}
|
</tr>
|
||||||
New (waiting for payment)
|
|
||||||
{:else if row.status === "InvoiceProcessing"}
|
|
||||||
Payment received, waiting for confirmations
|
|
||||||
{:else if row.status === "InvoiceSettled"}
|
|
||||||
Paid
|
|
||||||
{:else if row.status === "InvoiceExpired"}
|
|
||||||
Expired
|
|
||||||
{:else}
|
|
||||||
{row.status}
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{#if row.status === "New" || row.status === "InvoiceCreated"}
|
|
||||||
<a href={row.checkout_url} class="button button_highlight">
|
|
||||||
<i class="icon">paid</i> Pay
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div style="text-align: center;">
|
|
||||||
<button on:click={() => {show_expired = !show_expired}}>
|
|
||||||
{#if show_expired}
|
|
||||||
Hide
|
|
||||||
{:else}
|
|
||||||
Show
|
|
||||||
{/if}
|
|
||||||
expired and settled invoices
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
{/each}
|
||||||
|
</section>
|
||||||
<h2>Transaction log</h2>
|
|
||||||
<p>
|
|
||||||
Here is a log of all transactions on your account balance.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{#each months as month}
|
|
||||||
<h3>{month.month}</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Subscription charge: <Euro amount={month.total_subscription_charge}></Euro></li>
|
|
||||||
<li>Storage charge: <Euro amount={month.total_storage_charge}></Euro></li>
|
|
||||||
<li>Bandwidth charge: <Euro amount={month.total_bandwidth_charge}></Euro></li>
|
|
||||||
<li>Total charge: <Euro amount={month.total_deducted}></Euro></li>
|
|
||||||
<li>Deposited: <Euro amount={month.total_deposited}></Euro></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="table_scroll">
|
|
||||||
<table style="text-align: left;">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>Time</td>
|
|
||||||
<td>Balance</td>
|
|
||||||
<td>Subscription</td>
|
|
||||||
<td colspan="2">Storage</td>
|
|
||||||
<td colspan="2">Bandwidth</td>
|
|
||||||
<td>Deposited</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>Charged</td>
|
|
||||||
<td>Charged</td>
|
|
||||||
<td>Used</td>
|
|
||||||
<td>Charged</td>
|
|
||||||
<td>Used</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{#each month.rows as row}
|
|
||||||
<tr>
|
|
||||||
<td>{formatDate(row.time, true, true, false)}</td>
|
|
||||||
<td><Euro amount={row.new_balance}></Euro></td>
|
|
||||||
<td><Euro amount={row.subscription_charge} precision="4"></Euro></td>
|
|
||||||
<td><Euro amount={row.storage_charge} precision="4"></Euro></td>
|
|
||||||
<td>{formatDataVolume(row.storage_used, 3)}</td>
|
|
||||||
<td><Euro amount={row.bandwidth_charge} precision="4"></Euro></td>
|
|
||||||
<td>{formatDataVolume(row.bandwidth_used, 3)}</td>
|
|
||||||
<td><Euro amount={row.deposit_amount}></Euro></td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spinner_container {
|
.spinner_container {
|
||||||
|
@@ -28,10 +28,8 @@ export const toggle = () => {
|
|||||||
.expandable {
|
.expandable {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: var(--layer_3_color);
|
background-color: var(--layer_3_color);
|
||||||
transition: box-shadow 0.5s;
|
margin: 0.8em 0;
|
||||||
box-shadow: 1px 1px 6px -2px var(--shadow_color);
|
border-radius: 6px;
|
||||||
margin: 1em 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
|
Reference in New Issue
Block a user