diff --git a/svelte/package-lock.json b/svelte/package-lock.json
index 98b9f5b..277dfa3 100644
--- a/svelte/package-lock.json
+++ b/svelte/package-lock.json
@@ -106,9 +106,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.16",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz",
- "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==",
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
@@ -187,9 +187,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.8.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz",
- "integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==",
+ "version": "18.11.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz",
+ "integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==",
"dev": true
},
"node_modules/@types/resolve": {
@@ -202,9 +202,9 @@
}
},
"node_modules/acorn": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
- "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -226,9 +226,9 @@
}
},
"node_modules/anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"dependencies": {
"normalize-path": "^3.0.0",
@@ -527,9 +527,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
- "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
@@ -816,6 +816,7 @@
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
"integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
+ "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
@@ -894,6 +895,7 @@
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "deprecated": "Please use @jridgewell/sourcemap-codec instead",
"dev": true
},
"node_modules/supports-color": {
@@ -921,18 +923,18 @@
}
},
"node_modules/svelte": {
- "version": "3.51.0",
- "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.51.0.tgz",
- "integrity": "sha512-PBITYIrsNOuW+Dtds00gSY68raNZQn7i59Dg/fjgf6WwyawPKeBwle692coO7ILZqSO+UJe9899aDn9sMdeOHA==",
+ "version": "3.55.0",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.0.tgz",
+ "integrity": "sha512-uGu2FVMlOuey4JoKHKrpZFkoYyj0VLjJdz47zX5+gVK5odxHM40RVhar9/iK2YFRVxvfg9FkhfVlR0sjeIrOiA==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"node_modules/terser": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
- "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz",
+ "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
@@ -1054,9 +1056,9 @@
"dev": true
},
"@jridgewell/trace-mapping": {
- "version": "0.3.16",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz",
- "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==",
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "3.1.0",
@@ -1117,9 +1119,9 @@
"dev": true
},
"@types/node": {
- "version": "18.8.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz",
- "integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==",
+ "version": "18.11.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz",
+ "integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==",
"dev": true
},
"@types/resolve": {
@@ -1132,9 +1134,9 @@
}
},
"acorn": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
- "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"dev": true
},
"ansi-styles": {
@@ -1147,9 +1149,9 @@
}
},
"anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
@@ -1385,9 +1387,9 @@
}
},
"is-core-module": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
- "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"requires": {
"has": "^1.0.3"
@@ -1690,15 +1692,15 @@
"dev": true
},
"svelte": {
- "version": "3.51.0",
- "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.51.0.tgz",
- "integrity": "sha512-PBITYIrsNOuW+Dtds00gSY68raNZQn7i59Dg/fjgf6WwyawPKeBwle692coO7ILZqSO+UJe9899aDn9sMdeOHA==",
+ "version": "3.55.0",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.0.tgz",
+ "integrity": "sha512-uGu2FVMlOuey4JoKHKrpZFkoYyj0VLjJdz47zX5+gVK5odxHM40RVhar9/iK2YFRVxvfg9FkhfVlR0sjeIrOiA==",
"dev": true
},
"terser": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
- "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz",
+ "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==",
"dev": true,
"requires": {
"@jridgewell/source-map": "^0.3.2",
diff --git a/svelte/src/file_viewer/DownloadLimitStore.js b/svelte/src/file_viewer/DownloadLimitStore.js
new file mode 100644
index 0000000..4570efd
--- /dev/null
+++ b/svelte/src/file_viewer/DownloadLimitStore.js
@@ -0,0 +1,62 @@
+import { readable } from 'svelte/store';
+
+let limits = {
+ download_limit: 0,
+ download_limit_used: 0,
+ transfer_limit: 0,
+ transfer_limit_used: 0,
+ ipv6_bonus: 0,
+ loaded: false,
+}
+
+export const download_limits = readable(
+ limits,
+ function start(set) {
+ set_func = set;
+ loop();
+
+ return function stop() {
+ clearTimeout(timeout_ref);
+ };
+ }
+);
+
+let set_func;
+let timeout_ref = 0;
+let timeout_ms = 10000;
+
+const loop = async () => {
+ let new_limits;
+ try {
+ let resp = await fetch(window.api_endpoint + "/misc/rate_limits")
+ if (resp.status >= 400) {
+ throw new Error(await resp.text())
+ }
+ new_limits = await resp.json()
+ new_limits.loaded = true
+ } catch (err) {
+ console.error("Failed to get rate limits: " + err)
+ timeout_ref = setTimeout(loop, 30000)
+ return
+ }
+
+ // If the usage has not changed we increase the timeout with one second. If
+ // it did change we halve the timeout
+ if (new_limits.transfer_limit_used === limits.transfer_limit_used) {
+ timeout_ms += 1000
+ if (timeout_ms > 60000) {
+ timeout_ms = 60000
+ }
+ } else {
+ timeout_ms /= 2
+ if (timeout_ms < 5000) {
+ timeout_ms = 5000
+ }
+
+ limits = new_limits
+ set_func(new_limits)
+ }
+
+ console.debug("Sleep", timeout_ms / 1000, "seconds")
+ timeout_ref = setTimeout(loop, timeout_ms)
+}
diff --git a/svelte/src/file_viewer/FileViewer.svelte b/svelte/src/file_viewer/FileViewer.svelte
index 0e6170b..8824e9f 100644
--- a/svelte/src/file_viewer/FileViewer.svelte
+++ b/svelte/src/file_viewer/FileViewer.svelte
@@ -20,6 +20,7 @@ import GalleryView from "./GalleryView.svelte";
import Downloader from "./Downloader.svelte";
import CustomBanner from "./CustomBanner.svelte";
import LoadingIndicator from "../util/LoadingIndicator.svelte";
+import TransferLimit from "./TransferLimit.svelte";
let loading = true
let embedded = false
@@ -389,7 +390,7 @@ const keyboard_event = evt => {
{#if file.name !== ""}{file.name}{/if}
{#if embedded}
-
+
open_in_new
{/if}
@@ -581,6 +582,8 @@ const keyboard_event = evt => {
- You have used {formatDataVolume(limits.transfer_limit_used, 3)} of - your weekly {formatDataVolume(limits.transfer_limit, 3)} transfer + You have used {formatDataVolume($download_limits.transfer_limit_used, 3)} of + your weekly {formatDataVolume($download_limits.transfer_limit, 3)} transfer limit. When the transfer limit is exceeded your download speed will be reduced.
- + bolt Support Pixeldrain on Patreon to disable the transfer limit
-You have reached your download limit for today. Without a pixeldrain - account you are limited to downloading {limits.download_limit} files - or {formatDataVolume(limits.transfer_limit, 3)} per 48 hours. This limit + account you are limited to downloading {$download_limits.download_limit} files + or {formatDataVolume($download_limits.transfer_limit, 3)} per 48 hours. This limit is counted per IP address, so if you're on a shared network it's possible that others have also contributed to this limit.
In the last 24 hours you have downloaded - {limits.download_limit_used} files and used - {formatDataVolume(limits.transfer_limit_used, 3)} bandwidth. + {$download_limits.download_limit_used} files and used + {formatDataVolume($download_limits.transfer_limit_used, 3)} bandwidth.
{/if}@@ -89,7 +72,7 @@ onMount(async () => { - + bolt Support Pixeldrain on Patreon
Pixeldrain's free tier is supported by advertisements. There's only so much that you can do with the budget those ads provide (spoiler: it's - not a lot). {formatDataVolume(limits.transfer_limit, 3)} per week is + not a lot). {formatDataVolume($download_limits.transfer_limit, 3)} per week is about the most I can give away for free, and according to our records you have already downloaded - {formatDataVolume(limits.transfer_limit_used, 3)}. + {formatDataVolume($download_limits.transfer_limit_used, 3)}.
It's not that I want to withold this file from you, it's just that I @@ -57,7 +41,7 @@ onMount(async () => { {formatDuration((file.size/file.download_speed_limit)*1000)}