Update backend format for search; Delay cover image load
This commit is contained in:
parent
63c7d3676d
commit
8283c1987a
|
@ -6,7 +6,8 @@ import { modal } from '../partials/modal';
|
|||
|
||||
export const resultDetails = (searchController, result, emit = () => {}) => {
|
||||
const { __ } = searchController.i18n;
|
||||
const modalId = `result_${result.uri}`;
|
||||
const source = result.sources[0];
|
||||
const modalId = `result_${source.uri}`;
|
||||
|
||||
const hasReviews = typeof result.averageRating !== 'undefined' && typeof result.numberOfReviews !== 'undefined';
|
||||
|
||||
|
@ -27,37 +28,41 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
|
||||
const tabNames = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty'];
|
||||
|
||||
const coversHTMLArray = result.covers.map((cover, index, allCovers) => {
|
||||
return html`<div>
|
||||
<img src=${cover.url} alt="${cover.sourceId.replace(':', ' ').toUpperCase()}, Published: ${cover.publishDate}">
|
||||
${typeof allCovers[index - 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index - 1].sourceId}" style="margin-right:8px;">
|
||||
${'<'}
|
||||
</label>`
|
||||
}
|
||||
${typeof allCovers[index + 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index + 1].sourceId}">
|
||||
${'>'}
|
||||
</label>`
|
||||
}
|
||||
</div>`;
|
||||
});
|
||||
|
||||
const modalContent = html`<article class="flex">
|
||||
<div class="sixth-700" style="text-align:center;">
|
||||
<h4>${__('search.covers')}</h4>
|
||||
${typeof result.covers === 'undefined'
|
||||
? html`<span style="font-size:3em;"><i class="icon-loading animate-spin"></i></span>`
|
||||
: html`<div class="tabs ${typeof tabNames[result.covers.length - 1] !== 'undefined' ? tabNames[result.covers.length - 1] : null}">
|
||||
: html`<div class="tabs ${typeof tabNames[result.covers.length - 1] !== 'undefined' ? tabNames[result.covers.length - 1] : tabNames[19]}">
|
||||
${result.covers.map((cover, index) => {
|
||||
return [
|
||||
html`<input id="cover_${cover.uri}" type="radio" name="${modalId}_covers" ${index === 0 ? 'checked' : null} />`,
|
||||
// html`<label class="small pseudo button toggle" for="cover_${cover.uri}">•</label>`,
|
||||
html`<input id="cover_${cover.sourceId}" type="radio" name="${modalId}_covers" ${index === 0 ? 'checked' : null} />`,
|
||||
// html`<label class="small pseudo button toggle" for="cover_${cover.sourceId}">•</label>`,
|
||||
];
|
||||
})}
|
||||
<div class="row">
|
||||
${result.covers.map((cover, index, allCovers) => {
|
||||
return html`<div>
|
||||
<img src=${cover.url} alt="${cover.uri.replace(':', ' ').toUpperCase()}, Published: ${cover.publishDate}">
|
||||
${typeof allCovers[index - 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index - 1].uri}" style="margin-right:8px;">
|
||||
${'<'}
|
||||
</label>`
|
||||
}
|
||||
${typeof allCovers[index + 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index + 1].uri}">
|
||||
${'>'}
|
||||
</label>`
|
||||
}
|
||||
</div>`;
|
||||
})}
|
||||
</div>
|
||||
<div class="row" id="covers_${modalId}">${
|
||||
searchController.openModal === modalId
|
||||
? coversHTMLArray
|
||||
: '' /* Leave the covers column empty until opened to prevent loading too many images */
|
||||
}</div>
|
||||
</div>`
|
||||
}
|
||||
</div>
|
||||
|
@ -72,7 +77,7 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
<h4>Top Reviews</h4>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/book/${result.uri}" class="small button">
|
||||
<a href="/book/${source.uri}" class="small button">
|
||||
<span style="margin-right:8px;"><i class="icon-chat"></i></span>
|
||||
<span>${result.numberOfReviews}</span>
|
||||
<span>${__('search.see_interaction_details')}</span>
|
||||
|
@ -92,27 +97,29 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
</p>
|
||||
${!searchController.showShelves ? null : html`<ul>${searchController.shelves.map(shelf => {
|
||||
return html`<li>
|
||||
<button class="pseudo" onclick=${() => searchController.addToShelf({source: 'inventaire', uri: result.uri}, shelf.id)}>
|
||||
<button class="pseudo" onclick=${() => searchController.addToShelf({ id: result.id, ...source }, shelf.id)}>
|
||||
${shelf.name}
|
||||
</button>
|
||||
</li>`;
|
||||
})}</ul>`}
|
||||
<p>
|
||||
<a class="small button" href=${result.link} target="_blank">
|
||||
<a class="small button" href=${source.link} target="_blank">
|
||||
${__('search.see_book_details')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</article>`;
|
||||
|
||||
const onShow = () => {
|
||||
const coversColumn = document.getElementById(`covers_${modalId}`);
|
||||
coversColumn.innerHTML = '';
|
||||
coversHTMLArray.forEach(element => coversColumn.appendChild(element));
|
||||
};
|
||||
|
||||
return modal(modalId, searchController, modalContent, {
|
||||
styles: "width:90%;",
|
||||
buttonHTML, // This should be replaced with buttonHTML containing the ratings and number of reviews etc.
|
||||
headerText: result.name,
|
||||
onShow: () => {
|
||||
if (typeof result.covers === 'undefined') {
|
||||
searchController.getCovers(result.uri).then(() => emit('render'));
|
||||
}
|
||||
},
|
||||
onShow,
|
||||
});
|
||||
}
|
|
@ -15,6 +15,7 @@ class Inventaire {
|
|||
|
||||
static handleQuickEntity(entityObject) {
|
||||
return {
|
||||
id: null,
|
||||
name: (
|
||||
typeof entityObject.label !== 'undefined'
|
||||
? entityObject.label
|
||||
|
@ -25,22 +26,26 @@ class Inventaire {
|
|||
? entityObject.description
|
||||
: null
|
||||
),
|
||||
source: 'inventaire',
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
sources: [
|
||||
{
|
||||
source: 'inventaire',
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
},
|
||||
],
|
||||
covers: (
|
||||
typeof entityObject.image !== 'undefined'
|
||||
? entityObject.image.map(imageId => {
|
||||
return {
|
||||
uri: imageId.toString(),
|
||||
sourceId: imageId.toString(),
|
||||
url: `${Inventaire.url}/img/entities/${imageId}`,
|
||||
}
|
||||
})
|
||||
|
@ -72,17 +77,21 @@ class Inventaire {
|
|||
: null
|
||||
)
|
||||
),
|
||||
source: 'inventaire',
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
sources: [
|
||||
{
|
||||
source: 'inventaire',
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -109,7 +118,7 @@ class Inventaire {
|
|||
|
||||
if (typeof bookData.entities !== 'undefined' && typeof bookData.entities[uri] !== 'undefined') {
|
||||
bookData = Inventaire.handleEntity(bookData.entities[uri], this.lang);
|
||||
bookData['covers'] = await this.getCovers(bookData.uri);
|
||||
bookData['covers'] = await this.getCovers(bookData.sources[0].uri);
|
||||
|
||||
return bookData;
|
||||
}
|
||||
|
@ -126,7 +135,7 @@ class Inventaire {
|
|||
}
|
||||
|
||||
// Note: property `wdt:P629` is a given entity (uri)'s list of editions (ISBNs).
|
||||
const editionsRequest = fetch(`${Inventaire.url}/api/entities?action=reverse-claims&uri=${encodeURIComponent(uri)}&property=wdt:P629`)
|
||||
const editionsRequest = fetch(`${Inventaire.url}/api/entities?action=reverse-claims&value=${encodeURIComponent(uri)}&property=wdt:P629`)
|
||||
editionsRequest.catch(exception => {
|
||||
console.error(exception);
|
||||
return {
|
||||
|
@ -180,7 +189,7 @@ class Inventaire {
|
|||
}).map(key => {
|
||||
const entity = responseJSON.entities[key];
|
||||
return {
|
||||
uri: entity.uri,
|
||||
sourceId: entity.uri,
|
||||
url: typeof entity.claims['invp:P2'] !== 'undefined' ? `${Inventaire.url}/img/entities/${entity.claims['invp:P2'][0]}` : null,
|
||||
publishDate: typeof entity.claims['wdt:P577'] !== 'undefined' ? entity.claims['wdt:P577'][0] : null,
|
||||
}
|
||||
|
@ -193,7 +202,10 @@ class Inventaire {
|
|||
return a.publishDate < b.publishDate ? -1 : 1;
|
||||
});
|
||||
|
||||
return covers;
|
||||
return covers.map(cover => {
|
||||
delete cover.publishDate;
|
||||
return cover;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class BookReferenceController {
|
|||
}
|
||||
|
||||
// Get formatted book data from source
|
||||
const bookData = dataClass.getBookData(sourceId);
|
||||
const bookData = await dataClass.getBookData(sourceId);
|
||||
|
||||
if (typeof bookData.uri !== 'undefined') {
|
||||
// Check for references by exact name and author from source
|
||||
|
|
|
@ -43,7 +43,14 @@ function searchInventaire(searchTerm, language) {
|
|||
message: 'An error occurred when trying read the response from Inventaire as JSON.',
|
||||
}
|
||||
});
|
||||
return json.then(responseJSON => responseJSON.results.map(work => Inventaire.handleEntity(work, language)));
|
||||
return json.then(responseJSON => {
|
||||
return responseJSON.results.map(async work => {
|
||||
const inventaire = new Inventaire(langauge);
|
||||
const bookData = Inventaire.handleEntity(work, language);
|
||||
bookData['covers'] = await inventaire.getCovers(bookData.sources[0].uri);
|
||||
return bookData;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ const { Op, fn, col } = require('sequelize');
|
|||
|
||||
const BooksController = require('../bookData');
|
||||
const { quickSearchInventaire } = require('./Inventaire');
|
||||
const Inventaire = require('../bookData/Inventaire');
|
||||
|
||||
const defaultSearchOptions = {
|
||||
searchBy: 'name', // A column name in the BookReference model, mainly 'name' or 'description'
|
||||
|
@ -57,6 +58,30 @@ class SearchController {
|
|||
};
|
||||
}
|
||||
|
||||
static formatReferenceSources(reference) {
|
||||
const referenceSources = Object.keys(reference.sources);
|
||||
const reformattedSources = referenceSources.map(source => {
|
||||
const uri = reference.sources[source];
|
||||
let link;
|
||||
switch (source) {
|
||||
default:
|
||||
case 'inventaire': {
|
||||
link = `${Inventaire.url}/entity/${uri}`
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
source,
|
||||
uri,
|
||||
link,
|
||||
}
|
||||
});
|
||||
|
||||
reference.sources = reformattedSources;
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
async search(searchTerm, options = defaultSearchOptions) {
|
||||
const searchBy = options.searchBy.replace('title', 'name').replace('author', 'description');
|
||||
const { source, language } = options;
|
||||
|
@ -77,22 +102,23 @@ class SearchController {
|
|||
|
||||
// Add any search results that match refs with the same URI and delete from results array
|
||||
const urisToCheck = searchResults.filter(
|
||||
result => !bookReferences.some(ref => result.uri === ref.sources[source])
|
||||
).map(result => result.uri);
|
||||
result => !bookReferences.some(ref => result.sources[0].uri === ref.sources[source])
|
||||
).map(result => result.sources[0].uri);
|
||||
|
||||
let extraReferences = [];
|
||||
if (urisToCheck.length > 0) {
|
||||
// Need to figure this out
|
||||
extraReferences = await this.searchReferencesBySourceCodes(source, urisToCheck);
|
||||
}
|
||||
searchResults = searchResults.filter( // Only show the rest of the search results
|
||||
result => !extraReferences.some(
|
||||
ref => result.sources[0].uri === ref.sources[source]
|
||||
)
|
||||
);
|
||||
return [
|
||||
...bookReferences,
|
||||
...extraReferences,
|
||||
...searchResults.filter( // Only show the rest of the search results
|
||||
result => !extraReferences.some(
|
||||
ref => result.uri === ref.sources[source]
|
||||
)
|
||||
),
|
||||
...bookReferences.map(match => SearchController.formatReferenceSources(match)),
|
||||
...extraReferences.map(match => SearchController.formatReferenceSources(match)),
|
||||
...searchResults,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue