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:
@@ -221,7 +221,7 @@ app.get('/s/:code', async (req, res) => {
|
|||||||
|
|
||||||
const sharedTitle = (payload.title || '').trim();
|
const sharedTitle = (payload.title || '').trim();
|
||||||
const ogTitle = sharedTitle ? `${sharedTitle} - WARIO SYNTH` : 'WARIO SYNTH';
|
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>
|
const html = `<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|||||||
+40
-14
@@ -185,7 +185,7 @@ class MotifApp {
|
|||||||
this.motifProgressBar.addEventListener('input', seekHandler);
|
this.motifProgressBar.addEventListener('input', seekHandler);
|
||||||
this.motifProgressBar.addEventListener('change', 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)
|
// Embed snippet copy (may be disabled / not-live)
|
||||||
this.copyEmbedBtn?.addEventListener('click', () => void this.copyEmbedSnippet());
|
this.copyEmbedBtn?.addEventListener('click', () => void this.copyEmbedSnippet());
|
||||||
@@ -671,26 +671,52 @@ class MotifApp {
|
|||||||
this.status.textContent = message;
|
this.status.textContent = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleCopyLink(): void {
|
private async handleCopyLink(): Promise<void> {
|
||||||
if (!this.hasGenerated) return;
|
if (!this.hasGenerated) return;
|
||||||
const result = this.searchResults[this.selectedResultIndex];
|
const result = this.searchResults[this.selectedResultIndex];
|
||||||
if (!result?.midiUrl) return;
|
if (!result?.midiUrl) return;
|
||||||
|
|
||||||
// Build share URL with title
|
const title = result.title || '';
|
||||||
const title = encodeURIComponent(result.title || '');
|
|
||||||
let shareUrl: string;
|
// Try to get a short link with dynamic OG tags
|
||||||
if (result.source === 'bitmidi') {
|
let shareUrl: string | null = null;
|
||||||
const m = String(result.midiUrl).match(/\/uploads\/(\d+)\.mid/i);
|
try {
|
||||||
if (m?.[1]) {
|
let payload: any = null;
|
||||||
shareUrl = `${window.location.origin}/play?src=bitmidi&id=${encodeURIComponent(m[1])}&title=${title}`;
|
if (result.source === 'bitmidi') {
|
||||||
} else {
|
const m = String(result.midiUrl).match(/\/uploads\/(\d+)\.mid/i);
|
||||||
shareUrl = `${window.location.origin}/play?u=${encodeURIComponent(result.midiUrl)}&title=${title}`;
|
if (m?.[1]) payload = { src: 'bitmidi', id: m[1], title };
|
||||||
}
|
}
|
||||||
} else {
|
if (!payload) payload = { u: result.midiUrl, title };
|
||||||
shareUrl = `${window.location.origin}/play?u=${encodeURIComponent(result.midiUrl)}&title=${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.shareLinkInput.value = shareUrl;
|
||||||
this.shareLinkBox.style.display = 'block';
|
this.shareLinkBox.style.display = 'block';
|
||||||
this.shareLinkInput.select();
|
this.shareLinkInput.select();
|
||||||
|
|||||||
Reference in New Issue
Block a user