Redesign petition SVG share image; remove flag/report button
SVG: clean two-zone layout — dark header with RADICAL wordmark + PETITION badge, full-width text area with left accent bar and large quote mark, footer band with signature count, author, date and CTA. Proper word-wrap centred in the card. Looks like a real share card now. Remove flag button and handleFlag from proposal cards entirely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a07d3f6887
commit
b726dc1e24
2 changed files with 64 additions and 74 deletions
|
|
@ -1131,7 +1131,6 @@ function initializeShareButtons() {
|
|||
<img src="https://theradicalparty.com/memes/share-arrow-icon-md.png" alt="Share" style="width: 20px; height: 14px; filter: brightness(0) invert(1); pointer-events: none;">
|
||||
</div>
|
||||
<button class="share-img-btn" onclick="event.stopPropagation();event.preventDefault();window.open('${API_BASE_URL}/petition-svg?id=${proposal.id}','_blank')" title="Share as image">🖼</button>
|
||||
<button class="flag-btn" data-proposal-id="${proposal.id}" onclick="event.stopPropagation();event.preventDefault();handleFlag('${proposal.id}',this)" title="Report this proposal">⚑</button>
|
||||
</div>
|
||||
<div class="proposal-time">${formatDate(proposal.timestamp)}</div>
|
||||
</div>
|
||||
|
|
|
|||
137
worker.js
137
worker.js
|
|
@ -2024,82 +2024,73 @@ async function servePetitionSVG(request, env) {
|
|||
* @returns {string} - SVG markup as a string
|
||||
*/
|
||||
function generatePetitionSVG(proposal) {
|
||||
// Get data with fallbacks
|
||||
const petitionText = proposal.text || "Unknown petition";
|
||||
const text = escapeHTML(proposal.text || 'Untitled petition');
|
||||
const upvotes = proposal.upvotes || 0;
|
||||
const downvotes = proposal.downvotes || 0;
|
||||
const netVotes = upvotes - downvotes;
|
||||
const netVotesDisplay = netVotes > 0 ? `+${netVotes}` : netVotes;
|
||||
const netVotesColor = netVotes > 0 ? "#11cc77" : (netVotes < 0 ? "#ff0099" : "#ffffff");
|
||||
const proposalId = proposal.id || "unknown";
|
||||
|
||||
// Format timestamp
|
||||
const timestamp = new Date(proposal.timestamp || Date.now()).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
const author = escapeHTML(proposal.author_name || 'Anonymous');
|
||||
const date = new Date(proposal.timestamp || Date.now()).toLocaleDateString('en-AU', {
|
||||
day: 'numeric', month: 'short', year: 'numeric'
|
||||
});
|
||||
|
||||
// Base SVG template
|
||||
const svgTemplate = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
|
||||
<!-- Background -->
|
||||
<rect width="1200" height="630" fill="#000000" />
|
||||
|
||||
<!-- Border frame with glowing effect -->
|
||||
<rect x="10" y="10" width="1180" height="610" fill="none" stroke="#ff0099" stroke-width="4" rx="0" />
|
||||
<rect x="20" y="20" width="1160" height="590" fill="rgba(0, 0, 0, 0.8)" stroke="#ff0099" stroke-width="1" rx="0"
|
||||
style="filter: drop-shadow(0 0 10px #ff0099)" />
|
||||
|
||||
<!-- RADICAL Header -->
|
||||
<text x="600" y="90" font-family="'Roboto Mono', monospace" font-size="72" font-weight="700" text-anchor="middle"
|
||||
fill="#ff0099" style="text-transform: uppercase;">RADICAL</text>
|
||||
|
||||
<!-- Tagline -->
|
||||
<rect x="450" y="110" width="300" height="36" fill="#ff0099" />
|
||||
<text x="600" y="135" font-family="'Roboto Mono', monospace" font-size="20" font-weight="600" text-anchor="middle"
|
||||
fill="#000000" style="text-transform: uppercase;">VIBE, VOTE, VETO</text>
|
||||
|
||||
<!-- Petition text container -->
|
||||
<rect x="100" y="180" width="1000" height="280" fill="rgba(17, 17, 17, 0.7)" stroke="#333333" stroke-width="1" />
|
||||
|
||||
<!-- Petition text (dynamically generated) -->
|
||||
${generateSVGTextLines(petitionText, 120, 220, 960)}
|
||||
|
||||
<!-- Vote statistics -->
|
||||
<g transform="translate(200, 510)">
|
||||
<!-- Upvotes -->
|
||||
<text x="0" y="0" font-family="'Roboto Mono', monospace" font-size="24" fill="#ff0099">▲</text>
|
||||
<text x="30" y="0" font-family="'Roboto Mono', monospace" font-size="24" fill="#ffffff">${upvotes}</text>
|
||||
|
||||
<!-- Downvotes -->
|
||||
<text x="120" y="0" font-family="'Roboto Mono', monospace" font-size="24" fill="#ff0099">▼</text>
|
||||
<text x="150" y="0" font-family="'Roboto Mono', monospace" font-size="24" fill="#ffffff">${downvotes}</text>
|
||||
|
||||
<!-- Net votes -->
|
||||
<text x="240" y="0" font-family="'Roboto Mono', monospace" font-size="24" fill="#ff0099">NET:</text>
|
||||
<text x="300" y="0" font-family="'Roboto Mono', monospace" font-size="24" fill="${netVotesColor}">${netVotesDisplay}</text>
|
||||
</g>
|
||||
|
||||
<!-- Timestamp and ID -->
|
||||
<text x="600" y="560" font-family="'Roboto Mono', monospace" font-size="18" fill="#aaaaaa" text-anchor="middle">
|
||||
Petition ID: ${proposalId} • Created: ${timestamp}
|
||||
</text>
|
||||
|
||||
<!-- Radical Logo / Brand (right corner) -->
|
||||
<g transform="translate(940, 460)">
|
||||
<!-- Pink square for the logo -->
|
||||
<rect x="0" y="0" width="120" height="120" fill="#111111" stroke="#ff0099" stroke-width="2" />
|
||||
<text x="60" y="50" font-family="'Roboto Mono', monospace" font-size="16" fill="#ffffff" text-anchor="middle">RADICAL</text>
|
||||
<text x="60" y="75" font-family="'Roboto Mono', monospace" font-size="14" fill="#ff0099" text-anchor="middle">PETITION</text>
|
||||
<text x="60" y="100" font-family="'Roboto Mono', monospace" font-size="12" fill="#aaaaaa" text-anchor="middle">#${proposalId.slice(-6)}</text>
|
||||
</g>
|
||||
|
||||
<!-- URL -->
|
||||
<text x="600" y="600" font-family="'Roboto Mono', monospace" font-size="20" fill="#ff0099" text-anchor="middle"
|
||||
style="text-transform: uppercase;">theradicalparty.com</text>
|
||||
</svg>`;
|
||||
|
||||
return svgTemplate;
|
||||
// Word-wrap the petition text into lines (max ~52 chars per line at font-size 28)
|
||||
const words = text.split(' ');
|
||||
const lines = [];
|
||||
let line = '';
|
||||
for (const word of words) {
|
||||
if ((line + ' ' + word).trim().length > 52) { lines.push(line.trim()); line = word; }
|
||||
else line = (line + ' ' + word).trim();
|
||||
}
|
||||
if (line) lines.push(line);
|
||||
const displayLines = lines.slice(0, 7);
|
||||
if (lines.length > 7) displayLines[6] = displayLines[6].replace(/.{3}$/, '...');
|
||||
|
||||
const textY = 310 - (displayLines.length * 38) / 2;
|
||||
const textEls = displayLines.map((l, i) =>
|
||||
`<text x="600" y="${textY + i * 38}" font-family="monospace" font-size="28" font-weight="500" fill="#ffffff" text-anchor="middle">${l}</text>`
|
||||
).join('\n ');
|
||||
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
|
||||
<!-- bg -->
|
||||
<rect width="1200" height="630" fill="#000"/>
|
||||
<!-- left accent bar -->
|
||||
<rect x="0" y="0" width="8" height="630" fill="#ff0099"/>
|
||||
<!-- header band -->
|
||||
<rect x="0" y="0" width="1200" height="80" fill="#0a0a0a"/>
|
||||
<!-- RADICAL wordmark -->
|
||||
<text x="60" y="54" font-family="monospace" font-size="48" font-weight="700" fill="#ff0099" letter-spacing="8">RADICAL</text>
|
||||
<!-- tagline -->
|
||||
<text x="60" y="74" font-family="monospace" font-size="13" fill="#555" letter-spacing="3">VIBE · VOTE · VETO — theradicalparty.com</text>
|
||||
<!-- PETITION label top right -->
|
||||
<rect x="980" y="18" width="180" height="44" fill="#ff0099"/>
|
||||
<text x="1070" y="46" font-family="monospace" font-size="18" font-weight="700" fill="#000" text-anchor="middle" letter-spacing="2">PETITION</text>
|
||||
|
||||
<!-- petition text area -->
|
||||
<rect x="60" y="108" width="1080" height="380" fill="#0a0a0a" rx="0"/>
|
||||
<rect x="60" y="108" width="4" height="380" fill="#ff0099"/>
|
||||
<!-- quote mark -->
|
||||
<text x="100" y="185" font-family="monospace" font-size="80" fill="#1a1a1a" font-weight="700">"</text>
|
||||
<!-- wrapped petition text -->
|
||||
${textEls}
|
||||
|
||||
<!-- footer band -->
|
||||
<rect x="0" y="508" width="1200" height="122" fill="#0a0a0a"/>
|
||||
<line x1="0" y1="508" x2="1200" y2="508" stroke="#222" stroke-width="1"/>
|
||||
|
||||
<!-- upvote count -->
|
||||
<text x="68" y="560" font-family="monospace" font-size="15" fill="#666" letter-spacing="1">SIGNATURES</text>
|
||||
<text x="68" y="598" font-family="monospace" font-size="40" font-weight="700" fill="#ff0099">${upvotes.toLocaleString()}</text>
|
||||
|
||||
<!-- divider -->
|
||||
<line x1="300" y1="524" x2="300" y2="618" stroke="#222" stroke-width="1"/>
|
||||
|
||||
<!-- author + date -->
|
||||
<text x="330" y="556" font-family="monospace" font-size="13" fill="#555" letter-spacing="1">PROPOSED BY</text>
|
||||
<text x="330" y="585" font-family="monospace" font-size="20" fill="#aaa">${author}</text>
|
||||
<text x="330" y="612" font-family="monospace" font-size="14" fill="#444">${date}</text>
|
||||
|
||||
<!-- CTA -->
|
||||
<text x="1140" y="570" font-family="monospace" font-size="13" fill="#666" text-anchor="end">Sign this petition at</text>
|
||||
<text x="1140" y="592" font-family="monospace" font-size="16" fill="#ff0099" text-anchor="end" font-weight="700">theradicalparty.com</text>
|
||||
</svg>`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue