wee
This commit is contained in:
@@ -107,6 +107,7 @@
|
||||
let shopModalObserver = null;
|
||||
|
||||
const DEFAULT_SOCIAL_ORDER = ['discord', 'twitter', 'bluesky', 'instagram', 'youtube', 'tiktok', 'reddit', 'github'];
|
||||
const DEFAULT_FOOTER_LINK_ORDER = ['terms', 'privacy', 'refund', 'ban-appeal', 'suggestions', 'bug-report'];
|
||||
|
||||
// Find the button container in the DOM
|
||||
function findButtonContainer() {
|
||||
@@ -401,6 +402,184 @@
|
||||
return link;
|
||||
}
|
||||
|
||||
function getDefaultFooterOrder(id) {
|
||||
const index = DEFAULT_FOOTER_LINK_ORDER.indexOf(id);
|
||||
return index === -1 ? DEFAULT_FOOTER_LINK_ORDER.length + 10 : index;
|
||||
}
|
||||
|
||||
function ensureFooterEntry(map, id) {
|
||||
if (!map[id]) {
|
||||
map[id] = { id, order: getDefaultFooterOrder(id) };
|
||||
}
|
||||
return map[id];
|
||||
}
|
||||
|
||||
function formatFooterLabel(id) {
|
||||
if (!id) return '';
|
||||
return id
|
||||
.split('-')
|
||||
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
function buildFooterEntriesFromContent(content) {
|
||||
const data = content || {};
|
||||
const entries = {};
|
||||
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
if (!value) return;
|
||||
const match = key.match(/^modal\.footer\.links\.([^.]+)\.(url|text|order|target)$/);
|
||||
if (!match) return;
|
||||
|
||||
const [, id, field] = match;
|
||||
const entry = ensureFooterEntry(entries, id);
|
||||
|
||||
if (field === 'order') {
|
||||
const numericOrder = Number(value);
|
||||
if (!Number.isNaN(numericOrder)) {
|
||||
entry.order = numericOrder;
|
||||
}
|
||||
} else {
|
||||
entry[field] = value;
|
||||
}
|
||||
});
|
||||
|
||||
const legacyFooterLinks = [
|
||||
['terms', 'modal.footer.terms'],
|
||||
['privacy', 'modal.footer.privacy'],
|
||||
['refund', 'modal.footer.refund'],
|
||||
['ban-appeal', 'modal.footer.banAppeal'],
|
||||
['suggestions', 'modal.footer.suggestions'],
|
||||
['bug-report', 'modal.footer.bugReport']
|
||||
];
|
||||
|
||||
legacyFooterLinks.forEach(([id, baseKey]) => {
|
||||
const url = data[`${baseKey}.url`] || data[baseKey];
|
||||
if (!url) return;
|
||||
|
||||
const entry = ensureFooterEntry(entries, id);
|
||||
entry.url = url;
|
||||
|
||||
const textValue = data[`${baseKey}.text`];
|
||||
if (!entry.text && textValue) {
|
||||
entry.text = textValue;
|
||||
}
|
||||
|
||||
const orderValue = data[`${baseKey}.order`];
|
||||
if (orderValue !== undefined) {
|
||||
const numericOrder = Number(orderValue);
|
||||
if (!Number.isNaN(numericOrder)) {
|
||||
entry.order = numericOrder;
|
||||
}
|
||||
}
|
||||
|
||||
const targetValue = data[`${baseKey}.target`];
|
||||
if (targetValue) {
|
||||
entry.target = targetValue;
|
||||
}
|
||||
});
|
||||
|
||||
return Object.values(entries)
|
||||
.filter(entry => entry.url)
|
||||
.map(entry => {
|
||||
if (!entry.text) {
|
||||
entry.text = formatFooterLabel(entry.id);
|
||||
}
|
||||
return entry;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (a.order !== b.order) {
|
||||
return a.order - b.order;
|
||||
}
|
||||
return a.id.localeCompare(b.id);
|
||||
});
|
||||
}
|
||||
|
||||
function createFooterLinkElement(entry) {
|
||||
const link = document.createElement('a');
|
||||
link.href = entry.url;
|
||||
link.className = 'link';
|
||||
|
||||
if (entry.target) {
|
||||
link.target = entry.target;
|
||||
} else if (!entry.url.startsWith('mailto:')) {
|
||||
link.target = '_blank';
|
||||
}
|
||||
|
||||
if (link.target === '_blank') {
|
||||
link.rel = 'noopener noreferrer';
|
||||
}
|
||||
|
||||
link.textContent = entry.text || formatFooterLabel(entry.id);
|
||||
link.setAttribute('data-footer-id', entry.id);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
async function rebuildInfoModalFooter(modalBox) {
|
||||
try {
|
||||
const footerSection = Array.from(modalBox.querySelectorAll('section')).find(section =>
|
||||
section.classList.contains('text-base-content/80') && section.classList.contains('text-sm')
|
||||
);
|
||||
|
||||
if (!footerSection) return;
|
||||
|
||||
const locale = getPreferredLocale();
|
||||
if (
|
||||
footerSection.dataset.fpFooterLocale === locale &&
|
||||
footerSection.dataset.fpFooterLoaded === 'true'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const content = await getSiteContent(locale);
|
||||
if (!content) return;
|
||||
|
||||
const email = content['modal.footer.email'];
|
||||
const footerEntries = buildFooterEntriesFromContent(content);
|
||||
|
||||
footerSection.innerHTML = '';
|
||||
|
||||
const items = [];
|
||||
if (email) {
|
||||
const emailSpan = document.createElement('span');
|
||||
emailSpan.className = 'inline-flex items-center gap-1';
|
||||
const emailLink = document.createElement('a');
|
||||
emailLink.href = `mailto:${email}`;
|
||||
emailLink.className = 'link';
|
||||
emailLink.textContent = email;
|
||||
emailSpan.append('Email: ', emailLink);
|
||||
items.push(emailSpan);
|
||||
}
|
||||
|
||||
footerEntries.forEach(entry => {
|
||||
const link = createFooterLinkElement(entry);
|
||||
items.push(link);
|
||||
});
|
||||
|
||||
if (items.length === 0) {
|
||||
footerSection.dataset.fpFooterLocale = locale;
|
||||
footerSection.dataset.fpFooterLoaded = 'false';
|
||||
return;
|
||||
}
|
||||
|
||||
items.forEach((node, index) => {
|
||||
footerSection.appendChild(node);
|
||||
if (index < items.length - 1) {
|
||||
const separator = document.createElement('span');
|
||||
separator.className = 'mx-1 text-base-content/60';
|
||||
separator.textContent = ' · ';
|
||||
footerSection.appendChild(separator);
|
||||
}
|
||||
});
|
||||
|
||||
footerSection.dataset.fpFooterLocale = locale;
|
||||
footerSection.dataset.fpFooterLoaded = 'true';
|
||||
} catch (error) {
|
||||
console.warn('[FurryPlace SDK] Failed to rebuild info modal footer:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function rebuildInfoModalSocialLinks(modalBox) {
|
||||
try {
|
||||
const contentContainer = modalBox.querySelector('div[class*="flex"]');
|
||||
@@ -511,6 +690,7 @@
|
||||
});
|
||||
|
||||
rebuildInfoModalSocialLinks(modalBox);
|
||||
rebuildInfoModalFooter(modalBox);
|
||||
}
|
||||
|
||||
// Watch for info modal opening
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebApplication",
|
||||
"name": "FurryPlace",
|
||||
"url": "https://github.com/FurryPlaceteam/FurryPlace"
|
||||
"url": "https://gitea.goocat.gay/zack3d/my_openplace"
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ app.use(async (req, res, next) => {
|
||||
if (ext === ".html") {
|
||||
res.setHeader("Content-Security-Policy",
|
||||
"script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' https://challenges.cloudflare.com https://js.hcaptcha.com https://*.hcaptcha.com https://www.google.com https://www.gstatic.com blob:; " +
|
||||
"frame-src 'self' https://challenges.cloudflare.com https://*.hcaptcha.com https://www.google.com https://www.gstatic.com; " +
|
||||
"frame-src 'self' https://challenges.cloudflare.com https://*.hcaptcha.com https://www.google.com https://www.gstatic.com https://www.youtube.com; " +
|
||||
"style-src 'self' 'unsafe-inline' https://*.hcaptcha.com https://www.gstatic.com; " +
|
||||
"connect-src 'self' https://*.hcaptcha.com https://www.google.com https://www.gstatic.com https://tiles.openfreemap.org;"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user