Files
WaifuBoard/src/extensions/load-extensions.js
itsskaiya 652db0586b Updated headless browser (Should be as fast as it was before)
Added in Book Boards! (NEW!)
Updated rendering logic
Updated search logic
Updated extension loading logic
Updated image handling logic
2025-11-22 10:55:27 -05:00

130 lines
3.7 KiB
JavaScript

export async function populateSources(sourceList, targetType = 'image-board') {
console.log(`Requesting sources for type: ${targetType}...`);
const sources = await window.api.getSources();
sourceList.innerHTML = '';
let initialSource = '';
console.log("Raw sources received:", sources);
if (sources && sources.length > 0) {
sources.forEach((source) => {
if (targetType !== 'all' && source.type !== targetType) {
return;
}
const button = document.createElement('button');
button.className = 'source-button hover:bg-gray-700 hover:text-white transition-all duration-200';
button.dataset.source = source.name;
button.title = source.name;
let mainDomain = source.url;
try {
const urlToParse = source.url || source.baseUrl || "";
if (urlToParse) {
const hostname = new URL(urlToParse).hostname;
const parts = hostname.split('.');
if (parts.length > 2 && ['api', 'www'].includes(parts[0])) {
mainDomain = parts.slice(1).join('.');
} else {
mainDomain = hostname;
}
} else {
mainDomain = source.name;
}
} catch (e) {
mainDomain = source.name;
}
const favicon = document.createElement('img');
favicon.className = 'source-icon rounded';
favicon.src = `https://www.google.com/s2/favicons?domain=${mainDomain}&sz=32`;
favicon.alt = source.name;
const textWrapper = document.createElement('div');
textWrapper.className = 'source-text-wrapper';
const nameSpan = document.createElement('span');
nameSpan.className = 'source-name';
nameSpan.textContent = source.name;
const urlSpan = document.createElement('span');
urlSpan.className = 'source-url';
urlSpan.textContent = mainDomain;
textWrapper.appendChild(nameSpan);
textWrapper.appendChild(urlSpan);
favicon.onerror = () => {
favicon.remove();
const fallbackIcon = document.createElement('div');
fallbackIcon.className = 'source-icon fallback';
fallbackIcon.textContent = source.name.substring(0, 1).toUpperCase();
button.insertBefore(fallbackIcon, textWrapper);
};
button.appendChild(favicon);
button.appendChild(textWrapper);
sourceList.appendChild(button);
});
if (sourceList.children.length > 0) {
const firstButton = sourceList.children[0];
firstButton.classList.add('active');
initialSource = firstButton.dataset.source;
} else {
console.warn(`No sources found for type: ${targetType}`);
}
setupCarousel(sourceList);
} else {
console.warn('No sources loaded from API.');
}
return initialSource;
}
function setupCarousel(element) {
element.addEventListener('wheel', (evt) => {
if (evt.deltaY !== 0) {
if (element.scrollWidth > element.clientWidth) {
evt.preventDefault();
element.scrollLeft += evt.deltaY;
}
}
});
let isDown = false;
let startX;
let scrollLeft;
element.addEventListener('mousedown', (e) => {
isDown = true;
element.style.cursor = 'grabbing';
startX = e.pageX - element.offsetLeft;
scrollLeft = element.scrollLeft;
});
element.addEventListener('mouseleave', () => {
isDown = false;
element.style.cursor = 'grab';
});
element.addEventListener('mouseup', () => {
isDown = false;
element.style.cursor = 'grab';
});
element.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - element.offsetLeft;
const walk = (x - startX) * 2;
element.scrollLeft = scrollLeft - walk;
});
element.style.cursor = 'grab';
}