Share the short link, not the file

A link straight to the file cannot be counted — the recipient fetches bytes
from the file host and we never hear about it. The short link runs through our
own domain, so every open is a page load, and it is 33 characters against 74.
This commit is contained in:
gator 2026-09-09 01:14:44 +00:00
parent a82e95d9cc
commit 9051af0f3d

View file

@ -74,15 +74,11 @@ function card(p) {
+ esc(p.video_url) + '" download>Download</a>';
}
// The file URL ends in /public with no filename. Headers are already right
// (video/mp4), but clients that sniff the URL string are not, and a filename
// query is accepted and ignored by the file service.
// Through our own domain, so an open is a page load we can count. A link
// straight to the file is invisible to us. 33 characters against 74.
window.__shareUrl = window.__shareUrl || function (p) {
var u = p.cut_url || p.video_url || "";
if (!u) return "";
var slug = ((p.pet_name || "video") + " " + (p.title || "")).toLowerCase()
.replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40) || "video";
return u + (u.indexOf("?") < 0 ? "?" : "&") + "v=" + slug + ".mp4";
if (!(p.cut_url || p.video_url)) return "";
return location.origin + "/v/" + String(p.id || "").slice(0, 8);
};
return '<div class="item">'
@ -117,6 +113,10 @@ async function load() {
if (!p) return;
var link = window.__shareUrl(p);
if (!link) { showMsg("msg", "That one has no video yet."); return; }
// Sharing is a decision: this is what makes the link resolve at all.
var s = await api("share_link", { email: email, project_id: p.id });
if (!s.ok) { showMsg("msg", s.error || "Could not make a link."); return; }
link = s.url || link;
var title = p.title || ((p.pet_name || "Your pet") + " has something to say");
// The native sheet is the shortest path into a text message on a phone.
if (navigator.share) {