better ui for anilist entries & fixes
This commit is contained in:
@@ -46,6 +46,7 @@ function getBookEntryType(bookData) {
|
||||
return (format === 'MANGA' || format === 'ONE_SHOT' || format === 'MANHWA') ? 'MANGA' : 'NOVEL';
|
||||
}
|
||||
|
||||
// CORRECCIÓN: Usar el endpoint /list/entry/{id} y esperar 'found'
|
||||
async function checkIfInList() {
|
||||
if (!currentBookData) return;
|
||||
|
||||
@@ -54,6 +55,7 @@ async function checkIfInList() {
|
||||
|
||||
const entryType = getBookEntryType(currentBookData);
|
||||
|
||||
// URL CORRECTA: /list/entry/{id}?source={source}&entry_type={entryType}
|
||||
const fetchUrl = `${API_BASE}/list/entry/${entryId}?source=${source}&entry_type=${entryType}`;
|
||||
|
||||
try {
|
||||
@@ -64,6 +66,7 @@ async function checkIfInList() {
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
|
||||
// LÓGICA CORRECTA: Comprobar data.found
|
||||
if (data.found && data.entry) {
|
||||
|
||||
isInList = true;
|
||||
@@ -73,6 +76,11 @@ async function checkIfInList() {
|
||||
currentListEntry = null;
|
||||
}
|
||||
updateAddToListButton();
|
||||
} else if (response.status === 404) {
|
||||
// Manejar 404 como 'no encontrado' si la API lo devuelve así
|
||||
isInList = false;
|
||||
currentListEntry = null;
|
||||
updateAddToListButton();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking single list entry:', error);
|
||||
@@ -103,40 +111,71 @@ function updateAddToListButton() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* REFACTORIZADO para usar la estructura del modal completo.
|
||||
* Asume que el HTML usa IDs como 'entry-status', 'entry-progress', 'entry-score', etc.
|
||||
*/
|
||||
function openAddToListModal() {
|
||||
if (!currentBookData) return;
|
||||
|
||||
const totalUnits = currentBookData.chapters || currentBookData.volumes || 999;
|
||||
const entryType = getBookEntryType(currentBookData);
|
||||
|
||||
if (isInList) {
|
||||
// Referencias a los elementos del nuevo modal (usando 'entry-' prefix)
|
||||
const modalTitle = document.getElementById('modal-title');
|
||||
const deleteBtn = document.getElementById('modal-delete-btn');
|
||||
const progressLabel = document.getElementById('progress-label');
|
||||
|
||||
document.getElementById('modal-status').value = currentListEntry.status || 'PLANNING';
|
||||
document.getElementById('modal-progress').value = currentListEntry.progress || 0;
|
||||
document.getElementById('modal-score').value = currentListEntry.score || '';
|
||||
|
||||
document.getElementById('modal-title').textContent = 'Edit Library Entry';
|
||||
document.getElementById('modal-delete-btn').style.display = 'block';
|
||||
} else {
|
||||
|
||||
document.getElementById('modal-status').value = 'PLANNING';
|
||||
document.getElementById('modal-progress').value = 0;
|
||||
document.getElementById('modal-score').value = '';
|
||||
|
||||
document.getElementById('modal-title').textContent = 'Add to Library';
|
||||
document.getElementById('modal-delete-btn').style.display = 'none';
|
||||
// **VERIFICACIÓN CRÍTICA**
|
||||
if (!modalTitle || !deleteBtn || !progressLabel) {
|
||||
console.error("Error: Uno o más elementos críticos del modal (título, botón eliminar, o etiqueta de progreso) no se encontraron. Verifique los IDs en el HTML.");
|
||||
return;
|
||||
}
|
||||
|
||||
const progressLabel = document.getElementById('modal-progress-label');
|
||||
// --- Población de Datos ---
|
||||
|
||||
if (isInList && currentListEntry) {
|
||||
// Datos comunes
|
||||
document.getElementById('entry-status').value = currentListEntry.status || 'PLANNING';
|
||||
document.getElementById('entry-progress').value = currentListEntry.progress || 0;
|
||||
document.getElementById('entry-score').value = currentListEntry.score || '';
|
||||
|
||||
// Nuevos datos
|
||||
// Usar formato ISO si viene como ISO, o limpiar si es necesario. Tu ejemplo JSON no tenía fechas.
|
||||
document.getElementById('entry-start-date').value = currentListEntry.start_date ? currentListEntry.start_date.split('T')[0] : '';
|
||||
document.getElementById('entry-end-date').value = currentListEntry.end_date ? currentListEntry.end_date.split('T')[0] : '';
|
||||
document.getElementById('entry-repeat-count').value = currentListEntry.repeat_count || 0;
|
||||
document.getElementById('entry-notes').value = currentListEntry.notes || '';
|
||||
document.getElementById('entry-is-private').checked = currentListEntry.is_private === true || currentListEntry.is_private === 1;
|
||||
|
||||
modalTitle.textContent = 'Edit Library Entry';
|
||||
deleteBtn.style.display = 'block';
|
||||
} else {
|
||||
// Valores por defecto
|
||||
document.getElementById('entry-status').value = 'PLANNING';
|
||||
document.getElementById('entry-progress').value = 0;
|
||||
document.getElementById('entry-score').value = '';
|
||||
document.getElementById('entry-start-date').value = '';
|
||||
document.getElementById('entry-end-date').value = '';
|
||||
document.getElementById('entry-repeat-count').value = 0;
|
||||
document.getElementById('entry-notes').value = '';
|
||||
document.getElementById('entry-is-private').checked = false;
|
||||
|
||||
modalTitle.textContent = 'Add to Library';
|
||||
deleteBtn.style.display = 'none';
|
||||
}
|
||||
|
||||
// --- Configuración de Etiquetas y Máximo ---
|
||||
|
||||
if (progressLabel) {
|
||||
const format = currentBookData.format?.toUpperCase() || 'MANGA';
|
||||
if (format === 'MANGA' || format === 'ONE_SHOT' || format === 'MANHWA') {
|
||||
if (entryType === 'MANGA') {
|
||||
progressLabel.textContent = 'Chapters Read';
|
||||
} else {
|
||||
progressLabel.textContent = 'Volumes/Parts Read';
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('modal-progress').max = totalUnits;
|
||||
document.getElementById('entry-progress').max = totalUnits;
|
||||
document.getElementById('add-list-modal').classList.add('active');
|
||||
}
|
||||
|
||||
@@ -144,10 +183,23 @@ function closeAddToListModal() {
|
||||
document.getElementById('add-list-modal').classList.remove('active');
|
||||
}
|
||||
|
||||
/**
|
||||
* REFACTORIZADO para guardar TODOS los campos del modal.
|
||||
*/
|
||||
async function saveToList() {
|
||||
const status = document.getElementById('modal-status').value;
|
||||
const progress = parseInt(document.getElementById('modal-progress').value) || 0;
|
||||
const score = parseFloat(document.getElementById('modal-score').value) || null;
|
||||
// Datos comunes
|
||||
const status = document.getElementById('entry-status').value;
|
||||
const progress = parseInt(document.getElementById('entry-progress').value) || 0;
|
||||
const scoreValue = document.getElementById('entry-score').value;
|
||||
const score = scoreValue ? parseFloat(scoreValue) : null;
|
||||
|
||||
// Nuevos datos
|
||||
const start_date = document.getElementById('entry-start-date').value || null;
|
||||
const end_date = document.getElementById('entry-end-date').value || null;
|
||||
const repeat_count = parseInt(document.getElementById('entry-repeat-count').value) || 0;
|
||||
const notes = document.getElementById('entry-notes').value || null;
|
||||
const is_private = document.getElementById('entry-is-private').checked;
|
||||
|
||||
|
||||
if (!currentBookData) {
|
||||
showNotification('Cannot save: Book data not loaded.', 'error');
|
||||
@@ -167,7 +219,13 @@ async function saveToList() {
|
||||
entry_type: entryType,
|
||||
status: status,
|
||||
progress: progress,
|
||||
score: score
|
||||
score: score,
|
||||
// Nuevos campos
|
||||
start_date: start_date,
|
||||
end_date: end_date,
|
||||
repeat_count: repeat_count,
|
||||
notes: notes,
|
||||
is_private: is_private
|
||||
})
|
||||
});
|
||||
|
||||
@@ -175,8 +233,10 @@ async function saveToList() {
|
||||
throw new Error('Failed to save entry');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
isInList = true;
|
||||
currentListEntry = { entry_id: idToSave, source: extensionName || 'anilist', entry_type: entryType, status, progress, score };
|
||||
currentListEntry = data.entry; // Usar la respuesta del servidor si está disponible
|
||||
updateAddToListButton();
|
||||
closeAddToListModal();
|
||||
showNotification(isInList ? 'Updated successfully!' : 'Added to your library!', 'success');
|
||||
@@ -186,16 +246,19 @@ async function saveToList() {
|
||||
}
|
||||
}
|
||||
|
||||
// CORRECCIÓN: Usar el endpoint /list/entry/{id} con los parámetros correctos.
|
||||
async function deleteFromList() {
|
||||
if (!confirm('Remove this book from your library?')) return;
|
||||
|
||||
const idToDelete = extensionName ? bookSlug : bookId;
|
||||
const source = extensionName || 'anilist';
|
||||
const entryType = getBookEntryType(currentBookData); // Obtener el tipo de entrada
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/list/entry/${idToDelete}`, {
|
||||
// URL CORRECTA para DELETE: /list/entry/{id}?source={source}&entry_type={entryType}
|
||||
const response = await fetch(`${API_BASE}/list/entry/${idToDelete}?source=${source}&entry_type=${entryType}`, {
|
||||
method: 'DELETE',
|
||||
headers: getSimpleAuthHeaders()
|
||||
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -519,6 +582,7 @@ function openReader(bookId, chapterId, provider) {
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// El ID del modal sigue siendo 'add-list-modal' para mantener la compatibilidad con el código original.
|
||||
const modal = document.getElementById('add-list-modal');
|
||||
if (modal) {
|
||||
modal.addEventListener('click', (e) => {
|
||||
|
||||
Reference in New Issue
Block a user