Refactor media search rendering to be less redundant

This commit is contained in:
Timothy Warren 2021-10-08 12:15:34 -04:00
parent 1de4580ee7
commit 52d6cd797a
4 changed files with 54 additions and 42 deletions

View File

@ -628,6 +628,14 @@ picture.cover {
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
/* There are two .name elements, just darken them both in this case! */
.media.search.disabled .name {
background-color: #000;
background-color: rgba(0, 0, 0, 0.75);
background-size: cover;
background-size: contain;
background-repeat: no-repeat;
}
.media.search > .row { .media.search > .row {
z-index: 6; z-index: 6;

View File

@ -1,5 +1,5 @@
import _ from './anime-client.js' import _ from './anime-client.js'
import { renderAnimeSearchResults } from './template-helpers.js' import { renderSearchResults } from './template-helpers.js'
const search = (query) => { const search = (query) => {
// Show the loader // Show the loader
@ -13,7 +13,7 @@ const search = (query) => {
_.hide('.cssload-loader'); _.hide('.cssload-loader');
// Show the results // Show the results
_.$('#series-list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults); _.$('#series-list')[ 0 ].innerHTML = renderSearchResults('anime', searchResults);
}); });
}; };

View File

@ -1,12 +1,12 @@
import _ from './anime-client.js' import _ from './anime-client.js'
import { renderMangaSearchResults } from './template-helpers.js' import { renderSearchResults } from './template-helpers.js'
const search = (query) => { const search = (query) => {
_.show('.cssload-loader'); _.show('.cssload-loader');
return _.get(_.url('/manga/search'), { query }, (searchResults, status) => { return _.get(_.url('/manga/search'), { query }, (searchResults, status) => {
searchResults = JSON.parse(searchResults); searchResults = JSON.parse(searchResults);
_.hide('.cssload-loader'); _.hide('.cssload-loader');
_.$('#series-list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults); _.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);
}); });
}; };

View File

@ -7,20 +7,55 @@ _.on('main', 'change', '.big-check', (e) => {
document.getElementById(`mal_${id}`).checked = true; document.getElementById(`mal_${id}`).checked = true;
}); });
export function renderAnimeSearchResults (data) { /**
* On search results with an existing library entry, this shows that fact, with an edit link for the existing
* library entry
*
* @param {'anime'|'manga'} type
* @param {Object} item
* @returns {String}
*/
function renderEditLink (type, item) {
if (item.libraryEntry === null) {
return '';
}
return `
<div class="row">
<span class="edit"><big>[ Already in List ]</big></span>
</div>
<div class="row">
<span class="edit">
<a class="bracketed" href="/${type}/edit/${item.libraryEntry.id}/${item.libraryEntry.status}">Edit</a>
</span>
</div>
<div class="row"><span class="edit">&nbsp;</span></div>
`
}
/**
* Show the search results for a media item
*
* @param {'anime'|'manga'} type
* @param {Object} data
* @returns {String}
*/
export function renderSearchResults (type, data) {
return data.map(item => { return data.map(item => {
const titles = item.titles.join('<br />'); const titles = item.titles.join('<br />');
const disabled = item.libraryEntry !== null ? 'disabled' : '';
const editLink = renderEditLink(type, item);
return ` return `
<article class="media search"> <article class="media search ${disabled}">
<div class="name"> <div class="name">
<input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${item.mal_id}" /> <input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${item.mal_id}" ${disabled} />
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" /> <input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" ${disabled} />
<label for="${item.slug}"> <label for="${item.slug}">
<picture width="220"> <picture width="220">
<source srcset="/public/images/anime/${item.id}.webp" type="image/webp" /> <source srcset="/public/images/${type}/${item.id}.webp" type="image/webp" />
<source srcset="/public/images/anime/${item.id}.jpg" type="image/jpeg" /> <source srcset="/public/images/${type}/${item.id}.jpg" type="image/jpeg" />
<img src="/public/images/anime/${item.id}.jpg" alt="" width="220" /> <img src="/public/images/${type}/${item.id}.jpg" alt="" width="220" />
</picture> </picture>
<span class="name"> <span class="name">
${item.canonicalTitle}<br /> ${item.canonicalTitle}<br />
@ -29,41 +64,10 @@ export function renderAnimeSearchResults (data) {
</label> </label>
</div> </div>
<div class="table"> <div class="table">
${editLink}
<div class="row"> <div class="row">
<span class="edit"> <span class="edit">
<a class="bracketed" href="/anime/details/${item.slug}">Info Page</a> <a class="bracketed" href="/${type}/details/${item.slug}">Info Page</a>
</span>
</div>
</div>
</article>
`;
}).join('');
}
export function renderMangaSearchResults (data) {
return data.map(item => {
const titles = item.titles.join('<br />');
return `
<article class="media search">
<div class="name">
<input type="radio" id="mal_${item.slug}" name="mal_id" value="${item.mal_id}" />
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" />
<label for="${item.slug}">
<picture width="220">
<source srcset="/public/images/manga/${item.id}.webp" type="image/webp" />
<source srcset="/public/images/manga/${item.id}.jpg" type="image/jpeg" />
<img src="/public/images/manga/${item.id}.jpg" alt="" width="220" />
</picture>
<span class="name">
${item.canonicalTitle}<br />
<small>${titles}</small>
</span>
</label>
</div>
<div class="table">
<div class="row">
<span class="edit">
<a class="bracketed" href="/manga/details/${item.slug}">Info Page</a>
</span> </span>
</div> </div>
</div> </div>