Add short links with song title in OG preview

- Re-enable /api/share for short links (/s/abc123)
- Title shows as "Song Name - WARIO SYNTH"
- Description: "I made this in WARIO SYNTH"
- Falls back to long URL if short link fails

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
b1rdmania
2025-12-29 13:25:27 +00:00
parent 853e274a9d
commit 1041be46f3
2 changed files with 41 additions and 15 deletions
+1 -1
View File
@@ -221,7 +221,7 @@ app.get('/s/:code', async (req, res) => {
const sharedTitle = (payload.title || '').trim();
const ogTitle = sharedTitle ? `${sharedTitle} - WARIO SYNTH` : 'WARIO SYNTH';
const ogDescription = 'Tap to play this Gameboy tune';
const ogDescription = sharedTitle ? 'I made this in WARIO SYNTH' : 'Tap to play this Gameboy tune';
const html = `<!doctype html>
<html lang="en">
+40 -14
View File
@@ -185,7 +185,7 @@ class MotifApp {
this.motifProgressBar.addEventListener('input', seekHandler);
this.motifProgressBar.addEventListener('change', seekHandler);
this.copyLinkBtn.addEventListener('click', () => this.handleCopyLink());
this.copyLinkBtn.addEventListener('click', () => void this.handleCopyLink());
// Embed snippet copy (may be disabled / not-live)
this.copyEmbedBtn?.addEventListener('click', () => void this.copyEmbedSnippet());
@@ -671,26 +671,52 @@ class MotifApp {
this.status.textContent = message;
}
private handleCopyLink(): void {
private async handleCopyLink(): Promise<void> {
if (!this.hasGenerated) return;
const result = this.searchResults[this.selectedResultIndex];
if (!result?.midiUrl) return;
// Build share URL with title
const title = encodeURIComponent(result.title || '');
let shareUrl: string;
if (result.source === 'bitmidi') {
const m = String(result.midiUrl).match(/\/uploads\/(\d+)\.mid/i);
if (m?.[1]) {
shareUrl = `${window.location.origin}/play?src=bitmidi&id=${encodeURIComponent(m[1])}&title=${title}`;
} else {
shareUrl = `${window.location.origin}/play?u=${encodeURIComponent(result.midiUrl)}&title=${title}`;
const title = result.title || '';
// Try to get a short link with dynamic OG tags
let shareUrl: string | null = null;
try {
let payload: any = null;
if (result.source === 'bitmidi') {
const m = String(result.midiUrl).match(/\/uploads\/(\d+)\.mid/i);
if (m?.[1]) payload = { src: 'bitmidi', id: m[1], title };
}
} else {
shareUrl = `${window.location.origin}/play?u=${encodeURIComponent(result.midiUrl)}&title=${title}`;
if (!payload) payload = { u: result.midiUrl, title };
const resp = await fetch('/api/share', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (resp.ok) {
const data = await resp.json();
if (data?.url) shareUrl = `${window.location.origin}${data.url}`;
}
} catch {
// Fall through to long URL
}
// Show the link in a text box for easy copying
// Fallback: direct /play link
if (!shareUrl) {
const encodedTitle = encodeURIComponent(title);
if (result.source === 'bitmidi') {
const m = String(result.midiUrl).match(/\/uploads\/(\d+)\.mid/i);
if (m?.[1]) {
shareUrl = `${window.location.origin}/play?src=bitmidi&id=${encodeURIComponent(m[1])}&title=${encodedTitle}`;
} else {
shareUrl = `${window.location.origin}/play?u=${encodeURIComponent(result.midiUrl)}&title=${encodedTitle}`;
}
} else {
shareUrl = `${window.location.origin}/play?u=${encodeURIComponent(result.midiUrl)}&title=${encodedTitle}`;
}
}
// Show the link
this.shareLinkInput.value = shareUrl;
this.shareLinkBox.style.display = 'block';
this.shareLinkInput.select();