mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 11:49:25 +00:00
Add cookie disclaimer
This commit is contained in:
@@ -2063,3 +2063,90 @@ button:disabled:hover {
|
||||
background: #60a5fa;
|
||||
box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.2);
|
||||
}
|
||||
|
||||
.cookie-consent {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
max-width: 520px;
|
||||
margin-left: auto;
|
||||
padding: 16px 52px 14px 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 12px;
|
||||
background: linear-gradient(135deg, rgba(124, 58, 237, 0.25), rgba(59, 130, 246, 0.18));
|
||||
border: 1px solid rgba(148, 163, 184, 0.35);
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
|
||||
color: #e2e8f0;
|
||||
z-index: 11000;
|
||||
backdrop-filter: blur(4px);
|
||||
transition:
|
||||
opacity 150ms ease,
|
||||
transform 150ms ease;
|
||||
}
|
||||
|
||||
.cookie-consent-exit {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
|
||||
.cookie-consent-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.cookie-consent-copy {
|
||||
margin: 0;
|
||||
line-height: 1.45;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.cookie-consent-copy a {
|
||||
color: #a5b4fc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cookie-consent-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cookie-consent-close {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(226, 232, 240, 0.3);
|
||||
color: #e2e8f0;
|
||||
border-radius: 50%;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
transition: all 120ms ease;
|
||||
}
|
||||
|
||||
.cookie-consent-close:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-color: rgba(226, 232, 240, 0.45);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.cookie-consent {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.cookie-consent-actions {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
86
src/main/resources/static/js/cookie-consent.js
Normal file
86
src/main/resources/static/js/cookie-consent.js
Normal file
@@ -0,0 +1,86 @@
|
||||
(() => {
|
||||
const CONSENT_STORAGE_KEY = "imgfloat.cookie-consent.dismissed";
|
||||
const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365; // 1 year
|
||||
|
||||
const readConsentCookie = () => {
|
||||
return document.cookie
|
||||
.split("; ")
|
||||
.find((entry) => entry.startsWith(`${CONSENT_STORAGE_KEY}=`))
|
||||
?.split("=")[1];
|
||||
};
|
||||
|
||||
const persistDismissal = () => {
|
||||
try {
|
||||
window.localStorage.setItem(CONSENT_STORAGE_KEY, "true");
|
||||
} catch { }
|
||||
document.cookie = `${CONSENT_STORAGE_KEY}=true; max-age=${COOKIE_MAX_AGE_SECONDS}; path=/; SameSite=Lax`;
|
||||
};
|
||||
|
||||
const hasDismissed = () => {
|
||||
try {
|
||||
if (window.localStorage.getItem(CONSENT_STORAGE_KEY) === "true") {
|
||||
return true;
|
||||
}
|
||||
} catch { }
|
||||
return readConsentCookie() === "true";
|
||||
};
|
||||
|
||||
const shouldShowBanner = () => {
|
||||
if (!document.body) {
|
||||
return false;
|
||||
}
|
||||
if (document.body.classList.contains("broadcast-body")) {
|
||||
return false;
|
||||
}
|
||||
return !hasDismissed();
|
||||
};
|
||||
|
||||
const dismissBanner = (banner) => {
|
||||
if (!banner) {
|
||||
return;
|
||||
}
|
||||
persistDismissal();
|
||||
banner.classList.add("cookie-consent-exit");
|
||||
window.setTimeout(() => banner.remove(), 180);
|
||||
};
|
||||
|
||||
const renderBanner = () => {
|
||||
if (!shouldShowBanner()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const banner = document.createElement("section");
|
||||
banner.className = "cookie-consent";
|
||||
banner.setAttribute("role", "dialog");
|
||||
banner.setAttribute("aria-live", "polite");
|
||||
banner.setAttribute("aria-label", "Cookie usage notice");
|
||||
|
||||
banner.innerHTML = `
|
||||
<div class="cookie-consent-body">
|
||||
<p class="eyebrow subtle">Cookies & privacy</p>
|
||||
<p class="cookie-consent-copy">
|
||||
Imgfloat uses essential cookies to keep you signed in. By continuing to use the site, you agree to this use.
|
||||
</p>
|
||||
</div>
|
||||
<div class="cookie-consent-actions">
|
||||
<button type="button" class="button" data-consent-action="accept">Accept</button>
|
||||
<button type="button" class="button ghost" data-consent-action="dismiss">Dismiss</button>
|
||||
</div>
|
||||
<button type="button" class="cookie-consent-close" aria-label="Close cookie notice" data-consent-action="dismiss">
|
||||
×
|
||||
</button>
|
||||
`;
|
||||
|
||||
banner.querySelectorAll("[data-consent-action]").forEach((element) => {
|
||||
element.addEventListener("click", () => dismissBanner(banner));
|
||||
});
|
||||
|
||||
document.body.appendChild(banner);
|
||||
};
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", renderBanner);
|
||||
} else {
|
||||
renderBanner();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user