mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 03:39:26 +00:00
Add cookie disclaimer
This commit is contained in:
@@ -2063,3 +2063,90 @@ button:disabled:hover {
|
|||||||
background: #60a5fa;
|
background: #60a5fa;
|
||||||
box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.2);
|
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();
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -300,6 +300,7 @@
|
|||||||
const UPLOAD_LIMIT_BYTES = /*[[${uploadLimitBytes}]]*/ 0;
|
const UPLOAD_LIMIT_BYTES = /*[[${uploadLimitBytes}]]*/ 0;
|
||||||
const SETTINGS = /*[[${settingsJson}]]*/;
|
const SETTINGS = /*[[${settingsJson}]]*/;
|
||||||
</script>
|
</script>
|
||||||
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/toast.js"></script>
|
<script src="/js/toast.js"></script>
|
||||||
<script src="/js/admin.js"></script>
|
<script src="/js/admin.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
const broadcaster = /*[[${broadcaster}]]*/ "";
|
const broadcaster = /*[[${broadcaster}]]*/ "";
|
||||||
</script>
|
</script>
|
||||||
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/toast.js"></script>
|
<script src="/js/toast.js"></script>
|
||||||
<script src="/js/broadcast.js"></script>
|
<script src="/js/broadcast.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/landing.js"></script>
|
<script src="/js/landing.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -156,6 +156,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/toast.js"></script>
|
<script src="/js/toast.js"></script>
|
||||||
<script src="/js/downloads.js"></script>
|
<script src="/js/downloads.js"></script>
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
|
|||||||
@@ -90,6 +90,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/downloads.js"></script>
|
<script src="/js/downloads.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -248,6 +248,7 @@
|
|||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
const serverRenderedSettings = /*[[${settingsJson}]]*/;
|
const serverRenderedSettings = /*[[${settingsJson}]]*/;
|
||||||
</script>
|
</script>
|
||||||
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/settings.js"></script>
|
<script src="/js/settings.js"></script>
|
||||||
<script src="/js/toast.js"></script>
|
<script src="/js/toast.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user