feat: initpage com sync Go + auth + frontend em web/
This commit is contained in:
153
web/ads.js
Normal file
153
web/ads.js
Normal file
@@ -0,0 +1,153 @@
|
||||
window.InitPageAds = [
|
||||
{
|
||||
matchCategory: "Produtividade",
|
||||
name: "Semana Flow",
|
||||
url: "https://renderpage.weltonmoura.com.br/?page=1izF8H4Gefbw4y6YwxVFO2ituUNOCrRlK",
|
||||
desc: "Flow da semana em quadro Kanbam.",
|
||||
icon: "https://play-lh.googleusercontent.com/4fzfggNueiSzUQbpVGLQDP3CX0T4KBvt4OvxddZWz24IYx2b4H1DOKtijG5od_g7WPWOF3IV-nTrkcH8HhNf",
|
||||
cover: "https://cdn-icons-png.flaticon.com/512/645/645939.png",
|
||||
clickEndpoint: null
|
||||
},
|
||||
{
|
||||
matchCategory: "Lazer",
|
||||
name: "Raul Rock Bar",
|
||||
url: "https://raulrockbar.com.br/",
|
||||
desc: "O melhor bar alternativo do Cariri🍻",
|
||||
icon: "https://raulrockbar.com.br/assets/logo.jpeg",
|
||||
cover: "https://raulrockbar.com.br/assets/logo.jpeg",
|
||||
clickEndpoint: null
|
||||
}
|
||||
];
|
||||
|
||||
(function () {
|
||||
const ADS = window.InitPageAds || [];
|
||||
|
||||
function safeUrl(url) {
|
||||
try {
|
||||
const u = new URL(url);
|
||||
if (u.protocol === "https:" || u.protocol === "http:") return u.href;
|
||||
} catch (err) { }
|
||||
return null;
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str == null ? "" : str)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function getIconFallback(ad) {
|
||||
return safeUrl(ad.icon) || `https://www.google.com/s2/favicons?domain=${encodeURIComponent(ad.url)}&sz=128`;
|
||||
}
|
||||
|
||||
function getCoverHtml(ad) {
|
||||
const cover = safeUrl(ad.cover);
|
||||
if (!cover) {
|
||||
return '<div class="w-full h-full bg-gradient-to-tr from-slate-800 via-indigo-950 to-slate-800 flex items-center justify-center">' +
|
||||
'<svg class="w-8 h-8 text-white/25" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.4-9A4.5 4.5 0 1112.5 8H10a5 5 0 00-5 5"/></svg>' +
|
||||
"</div>";
|
||||
}
|
||||
return `<img src="${escapeHtml(cover)}" alt="${escapeHtml(ad.name)}" loading="lazy" class="w-full h-full object-cover" onerror="this.onerror=null;this.style.display='none';">`;
|
||||
}
|
||||
|
||||
function buildCard(ad, layout, cardSize) {
|
||||
const card = document.createElement("div");
|
||||
card.className = "group relative glass-card rounded-2xl overflow-hidden cursor-pointer select-none";
|
||||
card.setAttribute("role", "link");
|
||||
card.setAttribute("tabindex", "0");
|
||||
card.setAttribute("aria-label", `Conteúdo patrocinado: ${ad.name}`);
|
||||
card.dataset.sponsored = "true";
|
||||
card.title = "Patrocinado";
|
||||
|
||||
const icon = escapeHtml(getIconFallback(ad));
|
||||
const name = escapeHtml(ad.name);
|
||||
const desc = escapeHtml(ad.desc || "");
|
||||
|
||||
if (layout === "dock") {
|
||||
card.classList.add("p-2.5", "flex", "flex-col", "items-center", "w-20");
|
||||
card.innerHTML = `
|
||||
<div class="w-11 h-11 rounded-2xl glass-panel p-2 flex items-center justify-center shadow-md relative">
|
||||
<span class="absolute -top-1.5 -right-1.5 text-[8px] font-extrabold tracking-tighter bg-amber-400 text-slate-900 rounded-full w-4 h-4 flex items-center justify-center">AD</span>
|
||||
<img src="${icon}" alt="" class="w-full h-full object-contain" onerror="this.onerror=null; this.src='https://www.google.com/s2/favicons?domain=example.com';">
|
||||
</div>
|
||||
<span class="text-[10px] font-semibold text-slate-200 mt-1.5 truncate w-full text-center">${name}</span>
|
||||
`;
|
||||
} else if (layout === "list") {
|
||||
card.classList.add("flex", "items-center", "p-3", "gap-4");
|
||||
card.innerHTML = `
|
||||
<div class="w-14 h-14 rounded-xl overflow-hidden relative flex-shrink-0 bg-slate-900 border border-white/10">
|
||||
${getCoverHtml(ad)}
|
||||
<img src="${icon}" class="w-5 h-5 absolute bottom-1.5 right-1.5 glass-panel p-0.5 rounded shadow" onerror="this.onerror=null; this.src='https://www.google.com/s2/favicons?domain=example.com';">
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<h4 class="text-sm font-bold text-white truncate">${name}</h4>
|
||||
<span class="px-2 py-0.5 rounded-full bg-amber-400/90 text-[10px] font-bold text-slate-900 flex-shrink-0">Patrocinado</span>
|
||||
</div>
|
||||
<p class="text-xs text-slate-400 line-clamp-3">${desc}</p>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
const bannerHeight = cardSize === "sm"
|
||||
? "h-16 sm:h-20"
|
||||
: cardSize === "lg"
|
||||
? "h-32 sm:h-36"
|
||||
: "h-24 sm:h-28";
|
||||
card.innerHTML = `
|
||||
<div class="w-full ${bannerHeight} relative overflow-hidden bg-slate-900">
|
||||
${getCoverHtml(ad)}
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-slate-950/80 via-transparent to-black/20"></div>
|
||||
<div class="absolute top-2 left-2 px-2 py-0.5 rounded-md bg-amber-400/95 text-slate-900 text-[10px] font-bold shadow">Patrocinado</div>
|
||||
<div class="shortcut-icon-box absolute bottom-2 left-3 w-8 h-8 rounded-xl glass-panel p-1.5 flex items-center justify-center shadow-lg">
|
||||
<img src="${icon}" alt="" class="w-full h-full object-contain" onerror="this.onerror=null; this.src='https://www.google.com/s2/favicons?domain=example.com';">
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3 pt-2">
|
||||
<h4 class="text-xs sm:text-sm font-bold text-white truncate group-hover:text-accent transition-colors">${name}</h4>
|
||||
<p class="text-[10px] sm:text-xs text-slate-400 line-clamp-3 mt-0.5">${desc}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
const url = safeUrl(ad.url);
|
||||
const open = () => {
|
||||
if (ad.clickEndpoint && navigator.sendBeacon) {
|
||||
try {
|
||||
navigator.sendBeacon(ad.clickEndpoint, new Blob([JSON.stringify({ ad: ad.url, t: Date.now() })], { type: "application/json" }));
|
||||
} catch (err) { }
|
||||
}
|
||||
if (url) window.open(url, "_blank", "noopener,noreferrer");
|
||||
};
|
||||
card.addEventListener("click", open);
|
||||
card.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
open();
|
||||
}
|
||||
});
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
function matchingAd(categoryName) {
|
||||
if (!categoryName) return null;
|
||||
const target = String(categoryName).trim().toLowerCase();
|
||||
return ADS.find(a => target.includes(String(a.matchCategory || "").trim().toLowerCase())) || null;
|
||||
}
|
||||
|
||||
function renderSponsored(detail) {
|
||||
if (!detail || detail.activeTabId === "all") return;
|
||||
const container = document.getElementById("shortcuts-container");
|
||||
if (!container) return;
|
||||
const ad = matchingAd(detail.activeTabName);
|
||||
if (!ad) return;
|
||||
container.appendChild(buildCard(ad, detail.layout || "grid", detail.cardSize || "md"));
|
||||
}
|
||||
|
||||
window.addEventListener("initpage:shortcuts-rendered", (e) => {
|
||||
renderSponsored((e && e.detail) || {});
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user