const totalElementsToLoad = 2;
var totalElementsLoaded = 0;
var mainIndex = {};
var productPathUri = '';
var indexValues = {};
var contactPageBottomContent = '';
var productIdFound = {};
var searchResults = {};
var productInfo = {};
var indexMenu = {};
var announcementsContent = {};
var announcementToShow = false;
var synthesisActiveVoice = null;
var playbackType = null;
var playbackLang = 'pt-BR';
var leafletStatus = {
patient: true,
healthcare: true
}
var playbackStatus = {
patient: false,
healthcare: false
};
var synthesisLeafletTexts = {
patient: null,
healthcare: null
};
const init = () => {
console.log('[RIEP] Initializing the RIEP data');
if (indexValues.length === 0) {
showNotPageError(403, '[RIEP] Missing setup information');
return;
}
document.getElementById('contact-content').innerHTML = contactPageBottomContent;
document.getElementById('footer-year').innerHTML = new Date().getFullYear();
mainIndex = lunr(function () {
this.ref('id')
this.field('url')
this.field('name')
this.field('id')
indexValues.forEach((product) => {
this.add(product)
}, this)
})
showIndexMenuWith(indexValues);
if (!productPathUri) {
return showSearchPage();
}
searchResults = mainIndex.search(productPathUri);
if (searchResults.length === 0) {
return showSearchPage();
}
productIdFound = searchResults[0]['ref'];
let productJsonPath = window.indexJsonPath.replace('index.json', `products/${productIdFound}.json`);
console.log('[RIEP] Fechting product information...')
fetchJson(productJsonPath)
.then(json => {
productInfo = json;
setupProductPage();
setupDebugBar();
});
}
const displayPageWarn = (message) => {
document.getElementById('warning').innerHTML = `${message}`;
}
const showIndexMenuWith = (index) => {
document.getElementById('products-list').innerHTML = index.filter((e) => e.name !== undefined).map((el) => {
return `
${el.name}`;
}).join('');
}
const search = (e) => {
e.preventDefault();
let value = e.target.querySelector('input').value;
let results = mainIndex.search(value);
showIndexMenuWith(results.map((result) => {
return indexValues.find((e) => e.id === parseInt(result.ref));
}));
}
const loadedElementsCheck = () => {
totalElementsLoaded++
console.log(`[RIEP] Loaded ${totalElementsLoaded}/${totalElementsToLoad} elements`);
if (totalElementsLoaded === totalElementsToLoad) {
init();
}
}
const showNotPageError = (errorCode, errorMessage) => {
document.getElementsByTagName('body')[0].classList.add('show-error');
let errorBlock = document.getElementById('error-content');
errorBlock.querySelector('.error-code').innerHTML = errorCode;
errorBlock.querySelector('.error-message').innerHTML = errorMessage;
}
const setupProductPage = async () => {
console.log('[RIEP] Setup start ID:', productInfo.id)
document.title = `${window.siteName} Bulas - ${productInfo.title}`
let tagElement = document.querySelector('.tag-type');
if (productInfo.tags.length > 0) {
tagElement.innerHTML = productInfo.tags[0].name
tagElement.className = `tag-type ${productInfo.tags[0].slug}`;
} else {
tagElement.style.display = 'none';
}
let metadataValues = productInfo.metadata;
let pathReference = location.href.indexOf('/preview') !== -1 ? '/' : '';
leafletStatus.patient = !(!productInfo.metadata.patientLeaflet || productInfo.metadata.patientLeaflet === "");
leafletStatus.healthcare = !(!productInfo.metadata.healthcareLeaflet || productInfo.metadata.healthcareLeaflet === "");
if (!leafletStatus.patient || !leafletStatus.healthcare) {
document.querySelector(".btn.leaflet-modal-btn").remove();
if (productInfo.metadata.patientLeaflet && productInfo.metadata.patientLeaflet !== "") {
document.querySelector("#btn-ler-bula-paciente").classList.remove('hidden')
}
if (productInfo.metadata.healthcareLeaflet && productInfo.metadata.healthcareLeaflet !== "") {
document.querySelector("#btn-ler-bula-profissional-saude").classList.remove('hidden')
}
}
document.querySelectorAll('.fill').forEach((element) => {
let className = element.className;
if (className.indexOf('title') !== -1) {
element.innerHTML = productInfo.title
return;
}
if (className.indexOf('published_at') !== -1) {
element.innerHTML = productInfo.published_at
return;
}
if (className.indexOf('packageImage') !== -1) {
let imageElement = element.querySelector('img');
let packageImageReference = location.href.indexOf('/preview') !== -1 ? '' : '';
imageElement.setAttribute('src', `${packageImageReference}${productInfo.metadata.packageImage}`);
let altText = productInfo.metadata.packageImageAlt ? productInfo.metadata.packageImageAlt : 'Foto da caixa do produto';
imageElement.setAttribute('alt', altText);
return;
}
if (className.indexOf('patientLeaflet') !== -1 && productInfo.metadata.patientLeaflet !== '') {
let leafletPath = window.indexJsonPath.replace(`${pathReference}index.json`, productInfo.metadata.patientLeaflet);
const hrefValue = (location.href.indexOf('/preview') !== -1 ? '' : '.') + leafletPath;
element.setAttribute('href', hrefValue);
document.querySelector('#btn-ler-bula-paciente').setAttribute('href', hrefValue);
return;
}
if (className.indexOf('patientLeaflet') !== -1 && productInfo.metadata.patientLeaflet === '') {
element.remove();
return;
}
if (className.indexOf('healthcareLeaflet') !== -1 && productInfo.metadata.healthcareLeaflet !== '') {
let leafletPath = window.indexJsonPath.replace(`${pathReference}index.json`, productInfo.metadata.healthcareLeaflet);
const hrefValue = (location.href.indexOf('/preview') !== -1 ? '' : '.') + leafletPath;
element.setAttribute('href', hrefValue);
document.querySelector('#btn-ler-bula-profissional-saude').setAttribute('href', hrefValue);
return;
}
if (className.indexOf('healthcareLeaflet') !== -1 && productInfo.metadata.healthcareLeaflet === '') {
element.remove();
return;
}
if (className.indexOf('announcementPagesRelated') !== -1) {
let now = new Date();
let announcementModalElement = document.querySelector('.modal.announcement-modal');
let announcementUrls = Object.values(productInfo.metadata.announcementPagesRelated).filter((announcement) => {
if (announcement.date === '') return true;
let parts = announcement.date.split('/');
let date = new Date(`${parts[2]}-${parts[1]}-${parts[0]}`);
date.setDate(date.getDate() + 1);
return date > now;
}).map((announcement) => {
let path = document.URL.slice(0, document.URL.indexOf('?path=')) + `${pathReference}announcements/${announcement.id}.html`;
if (location.href.indexOf('/preview') !== false) {
path = path.replace('/preview', '/file-preview');
}
return path;
});
if (announcementUrls.length === 0) {
document.querySelector('.announcement-modal-btn').remove();
} else {
Promise.all(announcementUrls.map((u) => fetch(u).then((e) => {
return e.text();
}))).then((contentsArray) => {
announcementsContent = contentsArray.map((content, index) => {
let parts = announcementUrls[index].substring(announcementUrls[index].indexOf('/announcements/') + 15).split('.');
let date = productInfo.metadata.announcementPagesRelated[index].date;
let title = content.match(/(.*?)<\/h1>/);
if (title) {
title = title[1];
}
return {
id: parts[0],
title: title,
date: date,
content: content,
}
}).filter((a) => a.title)
announcementModalElement.querySelector('ul.announcementPagesRelated')
.innerHTML = announcementsContent.map((a) => {
return `
${a.title}
Clique aqui para conferir este comunicado na íntegra.
`;
}).join('');
announcementModalElement.classList.add('show');
announcementModalElement.querySelectorAll('a.announcement-link').forEach((e) => {
e.addEventListener('click', showAnnouncementPage);
})
})
}
return;
}
className = className.split(' ');
let fieldName = className.pop();
let valueElement = element.querySelector('.value');
if (!valueElement) {
console.warn('Field not found', fieldName);
return
}
valueElement.innerHTML = metadataValues[fieldName];
})
console.log('[Synthesis] checking Synthesis browser feature...');
if (!'speechSynthesis' in window) {
displayPageWarn('[Synthesis] Text-to-speech not supported.');
console.error('[Synthesis] Text-to-speech not supported.');
return
} else {
console.info('[Synthesis] Text-to-speech supported.');
}
if (speechSynthesis.getVoices().length === 0) {
window.speechSynthesis.addEventListener("voiceschanged", () => {
setupSynthesis(() => {
console.log('[RIEP] Setup done for product ID:', productInfo.id)
});
});
} else {
setupSynthesis(() => {
console.log('[RIEP] Setup done for product ID:', productInfo.id)
});
}
}
const showSearchPage = () => {
setupDebugBar();
document.getElementsByTagName('body')[0].classList.add('show-search')
}
const goBackToProduct = () => {
document.getElementsByTagName('body')[0].classList.remove('show-announcement')
}
const showAnnouncementPage = (event) => {
let announcementId = event.target.getAttribute('ref');
let announcement = announcementsContent.find((c) => c.id === announcementId);
if (!announcement) {
console.error('[RIEP] Missing announcement file');
return
}
;
document.getElementsByTagName('body')[0].classList.add('show-announcement');
document.getElementById('announcements-content').querySelector('.content').innerHTML = announcement.content;
}
const setupDebugBar = () => {
console.log('[DEBUG] Setup debug bar');
let debugbar = document.getElementById('debug-bar');
if (!debugbar) return;
debugbar.querySelector('.toggle-debug').addEventListener('click', () => debugbar.classList.toggle('hidden'));
document.getElementById('index-values').innerHTML = JSON.stringify(indexValues, null, 2);
debugbar.querySelector('.show-index').addEventListener('click', () =>
document.getElementById('index-values').classList.toggle('show'));
document.getElementById('search-debug').innerHTML = JSON.stringify(searchResults, null, 2);
debugbar.querySelector('.show-results').addEventListener('click', () =>
document.getElementById('search-debug').classList.toggle('show'));
document.getElementById('product-debug').innerHTML = JSON.stringify(productInfo, null, 2);
debugbar.querySelector('.show-product').addEventListener('click', () =>
document.getElementById('product-debug').classList.toggle('show'));
debugbar.querySelector('.product-path').innerHTML = productPathUri;
debugbar.querySelector('.product-id').innerHTML = productIdFound;
debugbar.querySelector('.index-status').innerHTML = `total of indexed values [${indexValues.length}]`;
debugbar.querySelector('.active-route-name').innerHTML = productPathUri ? 'product' : 'search';
}
const fetchJson = async (path) => {
if (!path) return false;
return fetch(path)
.then((response) => {
if (!response.ok) {
console.error(response.status);
if (response.status === 404) {
showNotPageError(404, 'Produto não encontrado');
} else {
showNotPageError(500, 'Erro desconhecido');
}
throw new Error("HTTP error " + response.status);
}
return response.json();
});
}
const setPlaybackStatus = (type, status, turnOff) => {
if (turnOff === true) {
window.speechSynthesis.pause();
Object.keys(playbackStatus).forEach((t) => {
document.querySelectorAll(`.${t}LeafletHear i.play-state`).forEach((e) => e.classList.remove('playing'));
playbackStatus[t] = false
});
return;
}
playbackStatus[type] = status;
let iconSelector = document.querySelectorAll(`.${type}LeafletHear i.play-state`);
if (status) {
iconSelector.forEach(e => e.classList.add('playing'));
}
if (!status) {
iconSelector.forEach(e => e.classList.remove('playing'));
}
let other = Object.keys(playbackStatus).filter((t) => t !== type).join('');
iconSelector = document.querySelectorAll(`.${other}LeafletHear i.play-state`);
if (playbackStatus[other]) {
iconSelector.forEach(e => e.classList.remove('playing'));
}
}
const hearLeaflet = async (type) => {
if (!type) {
console.error('[RIEP] Hear leaflet no type', type);
return;
} else {
console.info('[RIEP] leaflet type: ', type);
}
if (playbackType === type && playbackStatus[type]) {
console.log('|| pause', type)
setPlaybackStatus(type, false);
if (window.innerWidth < 768) {
return window.speechSynthesis.cancel();
}
return window.speechSynthesis.pause();
}
if (playbackType === type && !playbackStatus[type]) {
console.log('|> resume', type)
setPlaybackStatus(type, true);
if (window.innerWidth > 768) {
return window.speechSynthesis.resume();
}
}
if (playbackType && playbackType !== type) {
console.log('[] cancel', type)
setPlaybackStatus(type, false);
window.speechSynthesis.cancel();
}
playbackType = type;
for (let i in synthesisLeafletTexts[type]) {
let utterance = new SpeechSynthesisUtterance();
utterance.lang = playbackLang;
utterance.pitch = 1;
utterance.rate = 1;
utterance.volume = 1;
utterance.text = synthesisLeafletTexts[type][i].trim();
window.speechSynthesis.speak(utterance);
if (i === synthesisLeafletTexts[type].length - 1) {
setPlaybackStatus(type, true);
}
}
if (window.speechSynthesis.pending) {
console.warn('pending browser readings, force resume...');
window.speechSynthesis.pause();
window.speechSynthesis.resume();
}
setPlaybackStatus(type, true);
console.log('[> play', type);
}
const setupSynthesis = async (callback) => {
console.log('[Synthesis] Setup Text-to-speech...');
document.querySelector("a.patientLeafletHear").classList.add("loading");
document.querySelector("a.healthcareLeafletHear").classList.add("loading");
synthesisActiveVoice = window.speechSynthesis.getVoices().find((voice) => voice.lang === "pt-BR");
if (!synthesisActiveVoice) {
console.warn("[Synthesis] cant find tts voice using default language pt-BR");
} else {
console.log("[Synthesis] Selected voice", {
name: synthesisActiveVoice.name,
lang: synthesisActiveVoice.lang,
uri: synthesisActiveVoice.voiceURI,
local: synthesisActiveVoice.localService,
default: synthesisActiveVoice.default,
});
}
let imageReference = location.href.indexOf('/preview') !== -1 ? '/' : '';
let imageReferenceLocal = location.href.indexOf('/preview') !== -1 ? '' : '.';
let fetchArray = [];
console.log('[Synthesis] Listing leaflet texts...');
const patientUrlToTxt = window.indexJsonPath.replace(`${imageReference}index.json`, `${imageReferenceLocal}/storage/leaflets/${productInfo.id}-patient.txt`);
fetchArray.push(fetch(patientUrlToTxt).then((c) => {
if (c.status !== 200) return '';
return c.text();
}));
const healthcareToTxt = window.indexJsonPath.replace(`${imageReference}index.json`, `${imageReferenceLocal}/storage/leaflets/${productInfo.id}-healthcare.txt`);
fetchArray.push(fetch(healthcareToTxt).then((c) => {
if (c.status !== 200) return '';
return c.text();
}));
if (fetchArray.length === 0) {
callback();
}
await Promise.all(fetchArray).then(([patientText, healthcareText]) => {
console.warn('[Synthesis] leaflet status - patient:', leafletStatus.patient, ' healthcare:', leafletStatus.healthcare);
console.warn('[Synthesis] Text Status - patient :', !!patientText, ' healthcare:', !!healthcareText);
synthesisLeafletTexts.patient = leafletStatus.patient && !!patientText;
synthesisLeafletTexts.healthcare = leafletStatus.healthcare && !!healthcareText;
let patientBtnDirectElement = document.querySelector(".btn.btn-ouvir-bula-paciente-direct-riep");
let patientButtons = document.querySelectorAll(".btn.patientLeafletHear");
if (synthesisLeafletTexts.patient && !synthesisLeafletTexts.healthcare) {
patientBtnDirectElement.classList.remove("hidden");
patientBtnDirectElement.classList.remove('loading');
}
if (!synthesisLeafletTexts.patient) {
patientButtons.forEach(el => el.remove())
} else {
patientButtons.forEach(el => el.addEventListener("click", (event) => hearLeaflet("patient", event)))
}
let healthcareBtnDirectElement = document.querySelector(".btn.btn-ouvir-bula-profissional-saude-direct-riep");
let healthcareButtons = document.querySelectorAll(".btn.healthcareLeafletHear");
if (!synthesisLeafletTexts.patient && synthesisLeafletTexts.healthcare) {
healthcareBtnDirectElement.classList.remove("hidden");
healthcareBtnDirectElement.classList.remove('loading');
}
if (!synthesisLeafletTexts.healthcare) {
healthcareButtons.forEach(el => el.remove())
} else {
healthcareButtons.forEach(el => el.addEventListener("click", (event) => hearLeaflet("healthcare", event)))
}
if (!synthesisLeafletTexts.patient && !synthesisLeafletTexts.healthcare) {
console.log('Both leaflets has text version, hiding both buttons');
document.querySelector(".btn-group .btn-ouvir-bula-profissional-saude-riep")?.remove();
document.querySelector(".btn-group .btn-ouvir-bula-paciente-riep")?.remove();
}
if (!synthesisLeafletTexts.patient || !synthesisLeafletTexts.healthcare) {
console.log('One of leaflets doesnt has text version, hiding modal button');
document.querySelector(".btn-group .btn-ouvir-bula-modal-riep")?.remove();
}
Object.keys(synthesisLeafletTexts).filter((type) => synthesisLeafletTexts[type]).forEach((type) => {
const content = type === 'patient' ? patientText : healthcareText
let text = content.replace(/<\/?[^>]+(>|$)/g, "");
synthesisLeafletTexts[type] = text.split(/\. |\n|, |:|!/).filter(line => line.trim().length > 0);
})
})
}
const setupRequirements = () => {
let urlParts = Object.values(location.search.substring(1).split('&')).find((param) => param.indexOf('path=') !== -1);
if (urlParts) {
productPathUri = urlParts.replace('path=', '');
}
let libScript = document.createElement('script');
libScript.onload = loadedElementsCheck;
libScript.src = window.lunrPath;
document.getElementsByTagName('body')[0].appendChild(libScript);
document.querySelector('.leaflet-modal-btn').addEventListener('click', () => {
document.querySelector('.modal.leaflet-modal').classList.add('show');
})
document.querySelector('.audio-modal-btn').addEventListener('click', () => {
document.querySelector('.modal.audio-modal').classList.add('show');
})
document.querySelector('.announcement-modal-btn').addEventListener('click', () => {
document.querySelector('.modal.announcement-modal').classList.add('show');
})
document.querySelectorAll('.modal .backdrop').forEach((modalElement) => {
modalElement.addEventListener('click', (event) => {
event.target.parentNode.classList.remove('show');
setPlaybackStatus(null, null, true);
})
})
document.querySelectorAll('.modal .close-btn').forEach((modalElement) => {
modalElement.addEventListener('click', (event) => {
event.target.parentNode.parentNode.parentNode.classList.remove('show');
setPlaybackStatus(null, null, true);
})
})
document.getElementById('search-form').addEventListener('submit', search);
document.querySelector('.nav-bar .back-btn').addEventListener('click', goBackToProduct);
Promise.all([
fetchJson(window.indexJsonPath)
.then(json => {
return json
}),
fetch(window.indexJsonPath.replace('index.json', 'contact.html'))
.then(content => {
return content.text();
})
]).then(([indexJson, contactHtml]) => {
contactPageBottomContent = contactHtml
indexValues = indexJson;
loadedElementsCheck();
})
.catch((res) => {
console.error(res);
})
}
window.addEventListener('DOMContentLoaded', () => setupRequirements())
if (document.getElementsByName('robots').length === 0) {
let noIndexElement = document.createElement('meta');
noIndexElement.name = "robots"
noIndexElement.content = "noindex";
document.head.appendChild(noIndexElement);
}