+5
files/index.tmpl.html
+5
files/index.tmpl.html
+3
-4
files/saves.tmpl.html
+3
-4
files/saves.tmpl.html
···
11
11
12
12
vore's save system is unique:
13
13
when you click the "save" button, vore will:
14
-
- store the article title & domain
15
-
- submit an https://archive.is request on your behalf
16
-
- store the archive.is link
14
+
- submit an https://archive.org request on your behalf for the linked page
15
+
- store the article + archive link together
17
16
18
17
this ensures that all saved articles will remain
19
-
accessible indefinitely.
18
+
accessible forever!
20
19
21
20
it also means that you may save the same article
22
21
more than once, if you'd like!
+35
-1
files/user.tmpl.html
+35
-1
files/user.tmpl.html
···
22
22
published {{ .Date | timeSince }} via
23
23
<a href="//{{ .Link | printDomain }}">
24
24
{{ .Link | printDomain }}</a>
25
-
| <a href="/save/{{ .Link | escapeURL }}">save</a>
25
+
| <a href="#"
26
+
data-save-url="/save/{{ .Link | escapeURL }}"
27
+
onclick="saveItem(this); return false;">
28
+
save
29
+
</a>
26
30
</span>
27
31
</li>
28
32
{{ end }}
29
33
</ul>
34
+
35
+
<script>
36
+
function saveItem(element) {
37
+
const url = element.dataset.saveUrl;
38
+
const states = [".", "..", "..."];
39
+
let index = 0;
40
+
41
+
const intervalId = setInterval(() => {
42
+
element.textContent = "saving" + states[index];
43
+
index = (index + 1) % states.length;
44
+
}, 300);
45
+
46
+
fetch(url)
47
+
.then(response => {
48
+
if (!response.ok) {
49
+
throw new Error(`Request failed with status ${response.status}`);
50
+
}
51
+
return response.text();
52
+
})
53
+
.then(data => {
54
+
clearInterval(intervalId);
55
+
element.textContent = "saved!";
56
+
})
57
+
.catch(error => {
58
+
console.error(error);
59
+
clearInterval(intervalId);
60
+
element.textContent = "error!";
61
+
});
62
+
}
63
+
</script>
30
64
31
65
{{ template "tail" . }}
32
66
{{ end }}
+2
-2
readme
+2
-2
readme
···
29
29
- do not natively display posts
30
30
posts always look like shit away from their home websites. instead
31
31
of doing any of that nonsense, vore just takes website snapshots
32
-
via archive.is and presents them to the user.
32
+
via archive.org and presents them to the user.
33
33
34
34
- saved entries will NEVER change/expire
35
35
if a user uses the "save" feature, the data they were looking at
36
36
must never be lost.
37
37
therefore, we just copy whatever the active post state was from
38
-
memory & also snapshot the website via archive.is & link to the
38
+
memory & also snapshot the website via archive.org & link to the
39
39
snapshot. this way, there's always a cached version available
40
40
to use.
41
41
+2
-3
site.go
+2
-3
site.go
···
117
117
http.Redirect(w, r, "/", http.StatusSeeOther)
118
118
}
119
119
120
-
// saveHandler is an HTMX endpoint that returns the text "saved!" when
121
-
// a post has been saved to a user's account
120
+
// saveHandler is an endpoint that takes a url, archives it
121
+
// via archive.org, and then saves it to the user's account.
122
122
func (s *Site) saveHandler(w http.ResponseWriter, r *http.Request) {
123
123
if !s.loggedIn(r) {
124
124
s.renderErr(w, "", http.StatusUnauthorized)
···
159
159
fmt.Fprintf(w, "error!!!")
160
160
return
161
161
}
162
-
fmt.Fprintf(w, "saved! you can go back now. this will eventually be async. lol.")
163
162
}
164
163
165
164
func (s *Site) userHandler(w http.ResponseWriter, r *http.Request) {