diff --git a/src/templates/save.eta b/src/templates/save.eta
index 3e0299a..749491c 100644
--- a/src/templates/save.eta
+++ b/src/templates/save.eta
@@ -1,6 +1,30 @@
<% layout('./layout') %>
-
+<% /*
Saving videos should be stable again. Will try some more experiments in the coming days.
+
*/ %>
+
+
+
+
Please read before your first save
+
+
+ You are using PreserveTube to archive a video, not to casually download or proxy YouTube.
+
+
+ When you save here, the file is actually stored on PreserveTube infrastructure. Think of it like deciding to keep a file on your own hard drive.
+
+
+ - Only save videos that should be preserved as part of internet history.
+ - Do not use this as a normal YouTube viewing proxy or bulk downloader.
+ - Please only archive videos you feel are genuinely worth preserving long-term.
+
+
By continuing, you agree to use PreserveTube in that spirit.
+
+
+
@@ -16,45 +40,106 @@
const url = "<%= it.url %>"
const websocket = "<%= it.websocket %>"
const sitekey = "<%= it.sitekey %>"
- const ws = new WebSocket(`${websocket}/save?url=${encodeURIComponent(url)}`)
+ let ws = null
+ const hasSeenSaveInstructionsKey = "preservetube-save-instructions-seen"
const h1 = document.getElementById("title")
const h3 = document.getElementById("bottom")
const captcha = document.getElementById("captcha")
+ const backdrop = document.getElementById("backdrop")
+ const acceptInstructions = document.getElementById("accept-instructions")
+ const declineInstructions = document.getElementById("decline-instructions")
- ws.onopen = function () {
- document.querySelector("footer").innerHTML = `page rendered by <%= hostname %>, connected via ${websocket.split('-')[1].split('.')[0]}`
- }
+ function startSaveFlow() {
+ ws = new WebSocket(`${websocket}/save?url=${encodeURIComponent(url)}`)
- ws.onmessage = function (msg) {
- const text = msg.data.split(' - ').slice(1).join(' - ')
-
- if (msg.data == 'ERROR - Missing URL' || msg.data == 'ERROR - Whoops! What is that? That is not a Youtube url.') {
- h1.innerHTML = text
- return
- } else if (msg.data.startsWith('CAPTCHA -')) {
- captcha.style.display = 'block'
- turnstile.render('#captcha', {
- sitekey: sitekey,
- callback: function(token) {
- captcha.remove()
- ws.send(token)
- },
- })
- } else if (msg.data.startsWith('DONE -')) {
- window.location.href = text
+ ws.onopen = function () {
+ document.querySelector("footer").innerHTML = `page rendered by <%= hostname %>, connected via ${websocket.split('-')[1].split('.')[0]}`
}
- h3.innerHTML = `${h1.innerHTML}
${h3.innerHTML}`
- h1.innerHTML = text
+ ws.onmessage = function (msg) {
+ const text = msg.data.split(' - ').slice(1).join(' - ')
+
+ if (msg.data == 'ERROR - Missing URL' || msg.data == 'ERROR - Whoops! What is that? That is not a Youtube url.') {
+ h1.innerHTML = text
+ return
+ } else if (msg.data.startsWith('CAPTCHA -')) {
+ captcha.style.display = 'block'
+ turnstile.render('#captcha', {
+ sitekey: sitekey,
+ callback: function(token) {
+ captcha.remove()
+ ws.send(token)
+ },
+ })
+ } else if (msg.data.startsWith('DONE -')) {
+ window.location.href = text
+ }
+
+ h3.innerHTML = `${h1.innerHTML}
${h3.innerHTML}`
+ h1.innerHTML = text
+ }
+
+ ws.onclose = function (event) {
+ h3.innerHTML = `Websocket connection was closed: ${event.reason} (${event.code})
${h3.innerHTML}`
+ }
}
- ws.onclose = function (event) {
- h3.innerHTML = `Websocket connection was closed: ${event.reason} (${event.code})
${h3.innerHTML}`
- }
+ function runFirstSaveGate() {
+ let hasSeenInstructions = false
+ try {
+ hasSeenInstructions = localStorage.getItem(hasSeenSaveInstructionsKey) == "1"
+ } catch {
+ hasSeenInstructions = false
+ }
+
+ if (hasSeenInstructions) {
+ startSaveFlow()
+ return
+ }
+
+ backdrop.style.display = "block"
+ let secondsRemaining = 3
+ const timer = setInterval(() => {
+ secondsRemaining -= 1
+ if (secondsRemaining <= 0) {
+ clearInterval(timer)
+ acceptInstructions.disabled = false
+ acceptInstructions.innerText = "Continue"
+ return
+ }
+
+ acceptInstructions.innerText = `Continue (${secondsRemaining}s)`
+ }, 1000)
+
+ acceptInstructions.addEventListener("click", () => {
+ try {
+ localStorage.setItem(hasSeenSaveInstructionsKey, "1")
+ } catch {
+ }
+
+ backdrop.remove()
+ startSaveFlow()
+ })
+
+ declineInstructions.addEventListener("click", () => {
+ if (window.history.length > 1) {
+ window.history.back()
+ return
+ }
+
+ window.location.href = "/"
+ })
+ }
setInterval(() => {
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
+ return
+ }
+
ws.send('alive')
}, 2000)
+
+ runFirstSaveGate()
\ No newline at end of file
+