573 lines
15 KiB
JavaScript
573 lines
15 KiB
JavaScript
/*----------------------------------------------------------------------------------| io.vdm.dev |----/
|
|
Vast Development Method
|
|
/-------------------------------------------------------------------------------------------------------/
|
|
|
|
@package getBible.net
|
|
|
|
@created 3rd December, 2015
|
|
@author Llewellyn van der Merwe <https://getbible.net>
|
|
@git Get Bible <https://git.vdm.dev/getBible>
|
|
@github Get Bible <https://github.com/getBible>
|
|
@support Get Bible <https://git.vdm.dev/getBible/support>
|
|
@copyright Copyright (C) 2015. All Rights Reserved
|
|
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
|
|
|
/------------------------------------------------------------------------------------------------------*/
|
|
|
|
/* JS Document */
|
|
|
|
const memoryAppMemory = [];
|
|
const setLocalMemory = (key, values, merge = false) => {
|
|
if (merge) {
|
|
values = mergeLocalMemory(key, values);
|
|
} else {
|
|
values = JSON.stringify(values);
|
|
}
|
|
|
|
if (typeof Storage !== "undefined") {
|
|
localStorage.setItem(key, values);
|
|
} else {
|
|
memoryAppMemory[key] = values;
|
|
}
|
|
}
|
|
const mergeLocalMemory = (key, values) => {
|
|
const oldValues = getLocalMemory(key);
|
|
|
|
if (oldValues) {
|
|
values = { ...oldValues, ...values };
|
|
}
|
|
|
|
return JSON.stringify(values);
|
|
}
|
|
const getLocalMemory = (key, defaultValue = null, setDefault = false) => {
|
|
|
|
let returnValue = null;
|
|
|
|
if (typeof Storage !== "undefined") {
|
|
const localValue = localStorage.getItem(key);
|
|
|
|
if (isJsonString(localValue)) {
|
|
returnValue = JSON.parse(localValue);
|
|
}
|
|
} else if (typeof memoryAppMemory[key] !== "undefined") {
|
|
const localValue = memoryAppMemory[key];
|
|
|
|
if (isJsonString(localValue)) {
|
|
returnValue = JSON.parse(localValue);
|
|
}
|
|
}
|
|
|
|
if (returnValue) {
|
|
return returnValue;
|
|
} else if (setDefault) {
|
|
setLocalMemory(key, defaultValue, false);
|
|
}
|
|
|
|
return defaultValue;
|
|
}
|
|
const clearLocalMemory = (key) => {
|
|
if (typeof Storage !== "undefined") {
|
|
localStorage.removeItem(key);
|
|
} else if (typeof memoryAppMemory[key] !== "undefined") {
|
|
delete memoryAppMemory[key];
|
|
}
|
|
}
|
|
const isJsonString = (str) => {
|
|
try {
|
|
JSON.parse(str);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
class ScrollMemory {
|
|
constructor(divId) {
|
|
this.div = document.getElementById(divId);
|
|
this.localStorageKey = `${divId}ScrollPosition`;
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.restoreScrollPosition();
|
|
this.observeDivChanges();
|
|
this.addScrollEventListener();
|
|
}
|
|
|
|
restoreScrollPosition() {
|
|
const scrollPosition = localStorage.getItem(this.localStorageKey);
|
|
if (scrollPosition) {
|
|
this.div.scrollTop = scrollPosition;
|
|
}
|
|
}
|
|
|
|
saveScrollPosition() {
|
|
localStorage.setItem(this.localStorageKey, this.div.scrollTop);
|
|
}
|
|
|
|
observeDivChanges() {
|
|
const observer = new MutationObserver(() => this.restoreScrollPosition());
|
|
const config = { childList: true };
|
|
observer.observe(this.div, config);
|
|
}
|
|
|
|
addScrollEventListener() {
|
|
this.div.addEventListener('scroll', () => this.saveScrollPosition());
|
|
}
|
|
}
|
|
/**
|
|
* JS Function to set Share His Word url
|
|
*/
|
|
const setShareHisWordUrl = async (linker, translation, book, chapter) => {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getShareHisWordUrl(linker, translation, book, chapter));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
if (data.url || data.error) {
|
|
return data; // return the data object on success
|
|
} else {
|
|
throw new Error(data); // throw an error if the request was not successful
|
|
}
|
|
};
|
|
/**
|
|
* JS Function to check if we have a valid linker key
|
|
*/
|
|
const checkValidLinker = async (linker, oldLinker) => {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getCheckValidLinkerUrl(linker, oldLinker));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
if (data.success || data.error) {
|
|
return data; // return the data object on success
|
|
} else {
|
|
throw new Error(data); // throw an error if the request was not successful
|
|
}
|
|
};
|
|
/**
|
|
* JS Function to set the search url
|
|
*/
|
|
const setSearchUrl = async (search, translation) => {
|
|
// always reset the url value
|
|
document.getElementById('getbible-search-word').href = '#';
|
|
try {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getSearchURL(search, translation));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.url) {
|
|
document.getElementById('getbible-search-word').href = data.url;
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
/**
|
|
* JS Function to set open AI url
|
|
*/
|
|
const setOpenaiUrl = async (ids, guid, words, verse, chapter, book, translation) => {
|
|
// always reset the url value
|
|
ids.forEach(id => updateUrl(id, '#'));
|
|
try {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getOpenaiURL(guid, words, verse, chapter, book, translation));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.url) {
|
|
ids.forEach(id => updateUrl(id, data.url));
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to update the url
|
|
*/
|
|
const updateUrl = (id, url) => {
|
|
let button = document.getElementById(id);
|
|
if (button) {
|
|
button.href = url;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* JS Function to set the linker session value
|
|
*/
|
|
const setLinker = async (linker) => {
|
|
try {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getSetLinkerURL(linker));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.success) {
|
|
console.log(linker, data.success);
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to set the linker pass value
|
|
*/
|
|
const setLinkerAccess = async (linker, pass, oldPass = '') => {
|
|
// build form
|
|
const formData = new FormData();
|
|
|
|
// add the form data
|
|
formData.set('linker', linker);
|
|
formData.set('pass', pass);
|
|
formData.set('old', oldPass);
|
|
|
|
let options = {
|
|
method: 'POST',
|
|
body: formData
|
|
}
|
|
|
|
const response = await fetch(getSetLinkerAccessURL(), options);
|
|
const data = await response.json();
|
|
|
|
if (data.success || data.error) {
|
|
return data; // return the data object on success
|
|
} else {
|
|
throw new Error(data); // throw an error if the request was not successful
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to set the active linker on the page
|
|
*/
|
|
const setActiveLinkerOnPage = async (guid) => {
|
|
// Get all elements with the class name 'getbible-linker-guid-value'
|
|
let values = document.getElementsByClassName('getbible-linker-guid-value');
|
|
let inputs = document.getElementsByClassName('getbible-linker-guid-input');
|
|
// Update the 'textContent' of each value display
|
|
for (let i = 0; i < values.length; i++) {
|
|
values[i].textContent = guid;
|
|
}
|
|
// Update the 'value' of each input area
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
inputs[i].value = guid;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* JS Function to set a note
|
|
*/
|
|
const setNote = async (book, chapter, verse, note) => {
|
|
try {
|
|
// build form
|
|
const formData = new FormData();
|
|
|
|
// add the form data
|
|
formData.set('book', book);
|
|
formData.set('chapter', chapter);
|
|
formData.set('verse', verse);
|
|
formData.set('note', note);
|
|
|
|
let options = {
|
|
method: 'POST',
|
|
body: formData
|
|
}
|
|
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getSetNoteURL(), options);
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.success) {
|
|
// Show success message
|
|
UIkit.notification({
|
|
message: data.success,
|
|
status: 'success',
|
|
timeout: 5000
|
|
});
|
|
// update the local and the html in the verses
|
|
setActiveNoteVerse(verse, data.note);
|
|
setActiveNoteTextarea(verse);
|
|
setTimeout(function() {
|
|
UIkit.modal('#getbible-app-notes').hide();
|
|
}, 2000);
|
|
} else if (data.access_required && data.error) {
|
|
setupGetBibleAccess(
|
|
'getbible-app-notes',
|
|
data.error,
|
|
setNote,
|
|
[book, chapter, verse, note]
|
|
);
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to set a tag
|
|
*/
|
|
const setTag = async (name) => {
|
|
try {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getSetTagURL(name));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.success) {
|
|
// Show success message
|
|
UIkit.notification({
|
|
message: data.success,
|
|
status: 'success',
|
|
timeout: 5000
|
|
});
|
|
} else if (data.access_required && data.error) {
|
|
setupGetBibleAccess(
|
|
'getbible-app-tags',
|
|
data.error,
|
|
setTag,
|
|
[name]
|
|
);
|
|
} else if (data.error) {
|
|
// Show danger message
|
|
UIkit.notification({
|
|
message: data.error,
|
|
status: 'danger',
|
|
timeout: 3000
|
|
});
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to set a tag to a verse
|
|
*/
|
|
const tagVerse = async (translation, book, chapter, verse, tag) => {
|
|
try {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getTagVerseURL(translation, book, chapter, verse, tag));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.success) {
|
|
// So success message
|
|
UIkit.notification({
|
|
message: data.success,
|
|
status: 'success',
|
|
timeout: 3000
|
|
});
|
|
// update the local and the html in the verses
|
|
setActiveTaggedVerse(data);
|
|
} else if (data.access_required && data.error) {
|
|
setupGetBibleAccess(
|
|
'getbible-app-tags',
|
|
data.error,
|
|
tagVerse,
|
|
[translation, book, chapter, verse, tag]
|
|
);
|
|
} else if (data.error) {
|
|
// Show danger message
|
|
UIkit.notification({
|
|
message: data.error,
|
|
status: 'danger',
|
|
timeout: 3000
|
|
});
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to remove a tag from a verse
|
|
*/
|
|
const removeTagFromVerse = async (tag, verse) => {
|
|
try {
|
|
// Make a request to your endpoint
|
|
const response = await fetch(getRemoveTagFromVerseURL(tag));
|
|
|
|
// Wait for the server to return the response, then parse it as JSON.
|
|
const data = await response.json();
|
|
|
|
// Call another function after the response has been received
|
|
if (data.success) {
|
|
// Show success message
|
|
UIkit.notification({
|
|
message: data.success,
|
|
status: 'success',
|
|
timeout: 3000
|
|
});
|
|
// update the local and the html in the verses
|
|
setInactiveTaggedVerse(tag, verse);
|
|
} else if (data.access_required && data.error) {
|
|
setupGetBibleAccess(
|
|
'getbible-app-tags',
|
|
data.error,
|
|
removeTagFromVerse,
|
|
[tag, verse]
|
|
);
|
|
} else if (data.error || data.notice) {
|
|
if (data.notice) {
|
|
// Show primary message as notice
|
|
UIkit.notification({
|
|
message: data.notice,
|
|
status: 'primary',
|
|
timeout: 8000
|
|
});
|
|
} else {
|
|
// Show danger message
|
|
UIkit.notification({
|
|
message: data.error,
|
|
status: 'danger',
|
|
timeout: 3000
|
|
});
|
|
}
|
|
updateActiveGetBibleTaggedItems(verse);
|
|
updateAllGetBibleTaggedItems(verse);
|
|
} else {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", data);
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to set get Bible access
|
|
*/
|
|
const setupGetBibleAccess = async (active_modal, error_message, callback, args) => {
|
|
// close the active modal
|
|
UIkit.modal('#' + active_modal).hide();
|
|
try {
|
|
let modal = UIkit.modal('#getbible_favourite_verse_selector');
|
|
modal.show();
|
|
// get linker
|
|
let linker_old = getLocalMemory('getbible_active_linker_guid');
|
|
// Wait for the modal to be closed
|
|
await new Promise(resolve => {
|
|
// The 'hidden' event is triggered when the modal is closed
|
|
UIkit.util.on(modal.$el, 'hidden', function() {
|
|
resolve();
|
|
});
|
|
});
|
|
// get linker
|
|
let linker = getLocalMemory('getbible_active_linker_guid');
|
|
let pass = getLocalMemory(linker);
|
|
// check if access was set
|
|
if (pass) {
|
|
UIkit.modal('#' + active_modal).show();
|
|
// we should reload the page if a new linker was set
|
|
if (linker_old !== linker) {
|
|
triggerGetBibleReload = true;
|
|
}
|
|
callback(...args);
|
|
} else {
|
|
// Show message
|
|
UIkit.notification({
|
|
message: error_message,
|
|
status: 'warning',
|
|
timeout: 5000
|
|
});
|
|
}
|
|
} catch (error) {
|
|
// Handle any errors
|
|
console.error("Error occurred: ", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* JS Function to create an tag div item
|
|
*/
|
|
const createGetbileTagDivItem = (id, verse, name, url, tagged = null, ) => {
|
|
let itemElement = document.createElement('div');
|
|
itemElement.id = 'getbible-tag-' + id;
|
|
itemElement.dataset.tag = id;
|
|
itemElement.dataset.verse = verse;
|
|
if (tagged !== null) {
|
|
itemElement.dataset.tagged = tagged;
|
|
}
|
|
|
|
let marginDiv = document.createElement('div');
|
|
marginDiv.className = 'uk-margin';
|
|
|
|
let cardDiv = document.createElement('div');
|
|
cardDiv.className = 'uk-card uk-card-default uk-card-body uk-card-small';
|
|
|
|
// Create handle span
|
|
let handleSpan = document.createElement('span');
|
|
handleSpan.className = 'uk-sortable-handle uk-margin-small-right uk-text-center';
|
|
handleSpan.setAttribute('uk-icon', 'move');
|
|
handleSpan.insertAdjacentText('beforeend', name + ' ');
|
|
|
|
// Create view icon
|
|
let viewIcon = document.createElement('a');
|
|
viewIcon.href = url;
|
|
viewIcon.className = 'uk-icon-button';
|
|
viewIcon.setAttribute('uk-icon', 'tag');
|
|
viewIcon.setAttribute('uk-tooltip', 'title: ' + Joomla.JText._('COM_GETBIBLE_VIEW_ALL_VERSES_TAGGED'));
|
|
viewIcon.onclick = (event) => {
|
|
event.stopPropagation();
|
|
};
|
|
|
|
// Append view icon and name to cardDiv
|
|
cardDiv.appendChild(handleSpan);
|
|
cardDiv.appendChild(viewIcon);
|
|
|
|
marginDiv.appendChild(cardDiv);
|
|
itemElement.appendChild(marginDiv);
|
|
|
|
return itemElement;
|
|
};
|
|
|
|
/**
|
|
* JS Function to clear content from its parent div
|
|
*/
|
|
const removeChildrenElements = (parentId) => {
|
|
let list = document.querySelector('#' + parentId);
|
|
list.innerHTML = '';
|
|
}; |