/* This file is part of Ezra Bible App.
Copyright (C) 2019 - 2023 Ezra Bible App Development Team <contact@ezrabibleapp.net>
Ezra Bible App is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Ezra Bible App is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Ezra Bible App. See the file LICENSE.
If not, see <http://www.gnu.org/licenses/>. */
const eventController = require('../controllers/event_controller.js');
const { sleep } = require('../helpers/ezra_helper.js');
const verseListController = require('../controllers/verse_list_controller.js');
const moduleSelectHelper = require('../helpers/module_select_helper.js');
const swordModuleHelper = require('../helpers/sword_module_helper.js');
const INSTANT_LOADING_CHAPTER_LIMIT = 15;
/**
* The TranslationController is used to handle the bible translation menu and to
* access and generate various information about installed bible translations.
*
* Like all other controllers it is only initialized once. It is accessible at the
* global object `app_controller.translation_controller`.
*
* @category Controller
*/
class TranslationController {
constructor() {
this.translationCount = null;
this.initBibleSyncBoxDone = false;
eventController.subscribe('on-bible-text-loaded', async (tabIndex) => {
if (app_controller.isStartupCompleted()) {
await this.toggleTranslationsBasedOnCurrentBook(tabIndex);
}
});
eventController.subscribe('on-tab-selected', async (tabIndex) => {
await this.initTranslationsMenu(-1, tabIndex);
});
eventController.subscribe('on-translation-added', async () => {
await this.initTranslationsMenu();
});
eventController.subscribe('on-translation-removed', async () => {
$("select#bible-select").empty();
await this.initTranslationsMenu();
});
}
getTranslationCount() {
return this.translationCount;
}
initBibleSyncBox() {
if (this.initBibleSyncBoxDone) {
return;
}
this.initBibleSyncBoxDone = true;
$('#bible-sync-box').dialog({
width: 600,
height: 300,
autoOpen: false,
modal: true,
title: i18n.t("module-sync.module-sync-header"),
dialogClass: 'bible-sync-dialog'
});
}
getBibleSelect(tabIndex) {
var currentVerseListMenu = app_controller.getCurrentVerseListMenu(tabIndex);
if (currentVerseListMenu != null) {
var bibleSelect = currentVerseListMenu.find('select.bible-select');
return bibleSelect;
} else {
return null;
}
}
getBibleSelectBlock(tabIndex) {
var currentVerseListMenu = app_controller.getCurrentVerseListMenu(tabIndex);
if (currentVerseListMenu != null) {
var bibleSelectBlock = currentVerseListMenu.find('.bible-select-block');
return bibleSelectBlock;
} else {
return null;
}
}
updateUiBasedOnNumberOfTranslations(tabIndex, count) {
var bibleSelect = this.getBibleSelect(tabIndex);
var bibleSelectBlock = this.getBibleSelectBlock(tabIndex);
if (bibleSelect == null || bibleSelectBlock == null) {
return;
}
if (count == 0) {
if (platformHelper.isMobile()) {
bibleSelectBlock.addClass('hidden');
} else {
bibleSelect.attr('disabled','disabled');
}
$('.book-select-button').addClass('ui-state-disabled');
$('.tag-select-button').addClass('ui-state-disabled');
$('.module-search-button').addClass('ui-state-disabled');
let currentVerseList = verseListController.getCurrentVerseList(tabIndex);
// FIXME: This needs to be adjusted based on the new menu
currentVerseList.find('.help-text').html(i18n.t("help.help-text-no-translations", { interpolation: {escapeValue: false} }));
} else {
if (platformHelper.isMobile()) {
bibleSelectBlock.removeClass('hidden');
} else {
$('.bible-select').removeAttr('disabled');
}
$('.book-select-button').removeClass('ui-state-disabled');
$('.module-search-button').removeClass('ui-state-disabled');
var currentBook = null;
var currentTagIdList = "";
var currentSearchTerm = null;
var currentTab = app_controller.tab_controller.getTab(tabIndex);
if (currentTab != null) {
currentBook = currentTab.getBook();
currentTagIdList = currentTab.getTagIdList();
currentSearchTerm = currentTab.getSearchTerm();
}
if (currentBook == null && currentTagIdList == "" && currentSearchTerm == null) {
let currentVerseList = verseListController.getCurrentVerseList(tabIndex);
currentVerseList.find('.help-text').text(i18n.t("help.help-text-translation-available"));
}
}
}
async initTranslationsMenu(previousTabIndex=-1, tabIndex=undefined) {
if (tabIndex === undefined) {
tabIndex = app_controller.tab_controller.getSelectedTabIndex();
}
//console.log("initTranslationsMenu " + tabIndex);
var previousVerseListMenu = null;
if (previousTabIndex != -1) {
previousVerseListMenu = app_controller.getCurrentVerseListMenu(previousTabIndex);
}
var currentVerseListMenu = app_controller.getCurrentVerseListMenu(tabIndex);
var bibleSelect = null;
if (previousVerseListMenu != null && previousVerseListMenu.length > 0) {
var previousBibleSelect = previousVerseListMenu.find('select.bible-select').clone();
var currentBibleSelect = currentVerseListMenu.find('select.bible-select');
currentBibleSelect.replaceWith(previousBibleSelect);
bibleSelect = currentVerseListMenu.find('select.bible-select');
} else {
bibleSelect = currentVerseListMenu.find('select.bible-select');
bibleSelect.empty();
var modules = await ipcNsi.getAllLocalModules('BIBLE');
modules.sort(swordModuleHelper.sortModules);
await moduleSelectHelper.addLanguageGroupsToModuleSelectMenu(bibleSelect, modules);
if (modules == null) modules = [];
this.previousTranslationCount = this.translationCount;
this.translationCount = modules.length;
if (this.translationCount != this.previousTranslationCount) {
this.updateUiBasedOnNumberOfTranslations(tabIndex, modules.length);
}
moduleSelectHelper.addModulesToModuleSelectMenu(tabIndex, bibleSelect[0], modules);
eventController.subscribe('on-locale-changed', locale => moduleSelectHelper.updateModuleSelectLanguages(locale, bibleSelect));
}
bibleSelect.selectmenu({
width: platformHelper.isMobile() ? 110 : undefined,
change: () => {
if (!app_controller.tab_controller.isCurrentTabEmpty() && app_controller.tab_controller.getTab().getTextType() != 'search_results') {
uiHelper.showTextLoadingIndicator();
}
var currentVerseListMenu = app_controller.getCurrentVerseListMenu();
var bibleSelect = currentVerseListMenu.find('select.bible-select');
var oldBibleTranslationId = app_controller.tab_controller.getTab().getBibleTranslationId();
var newBibleTranslationId = bibleSelect[0].value;
ipcSettings.set('bibleTranslation', newBibleTranslationId);
setTimeout(() => {
eventController.publish('on-translation-changed', {from: oldBibleTranslationId, to: newBibleTranslationId});
}, 50);
}
});
this.toggleTranslationsBasedOnCurrentBook(tabIndex);
$('.bible-select-block').find('.ui-selectmenu').bind('click', () => {
app_controller.hideAllMenus();
});
}
hasCurrentTranslationHeaderElements(tabIndex=undefined) {
var currentVerseList = verseListController.getCurrentVerseList(tabIndex)[0];
var query = '.sword-section-title:not([type="chapter"]):not([type="psalm"]):not([type="scope"]):not([type="acrostic"])';
var allSectionTitles = currentVerseList.querySelectorAll(query);
return allSectionTitles.length > 0;
}
async installStrongs(htmlElementForMessages) {
var message = "<span>" + i18n.t("general.installing-strongs") + " ...</span>";
htmlElementForMessages.append(message);
try {
await ipcNsi.installModule("StrongsHebrew");
await ipcNsi.installModule("StrongsGreek");
app_controller.dictionary_controller.runAvailabilityCheck();
var doneMessage = "<span> " + i18n.t("general.done") + ".</span><br/>";
htmlElementForMessages.append(doneMessage);
} catch(e) {
var errorMessage = "<span> " + i18n.t("general.module-install-failed") + ".</span><br/>";
htmlElementForMessages.append(errorMessage);
}
}
// Currently not used!! (see startup.js)
async installStrongsIfNeeded() {
//console.time("get sync infos");
var strongsAvailable = await ipcNsi.strongsAvailable();
var strongsInstallNeeded = await swordModuleHelper.isStrongsTranslationAvailable() && !strongsAvailable;
//console.timeEnd("get sync infos");
if (strongsInstallNeeded) {
var currentVerseList = verseListController.getCurrentVerseList();
var verse_list_position = currentVerseList.offset();
this.initBibleSyncBox();
$('#bible-sync-box').dialog({
position: [verse_list_position.left + 50, verse_list_position.top + 30]
});
$('#bible-sync-box').dialog("open");
await sleep(100);
}
if (strongsInstallNeeded) {
await this.installStrongs($('#bible-sync-box'));
}
if (strongsInstallNeeded) {
await sleep(2000);
}
$('#bible-sync-box').dialog("close");
}
async getInstalledModules(moduleType='BIBLE') {
var translations = [];
var localModules = await ipcNsi.getAllLocalModules(moduleType);
if (localModules != null) {
localModules.sort(swordModuleHelper.sortModules);
for (var i = 0; i < localModules.length; i++) {
translations.push(localModules[i].name);
}
}
return translations;
}
async toggleTranslationsBasedOnCurrentBook(tabIndex=undefined) {
const bibleSelect = this.getBibleSelect(tabIndex);
const currentTab = app_controller.tab_controller.getTab(tabIndex);
if (currentTab != null) {
let currentBook = currentTab.getBook();
let previousBook = currentTab.getPreviousBook();
if (currentBook == null || currentBook == previousBook) {
return;
}
let moduleBookStatus = {};
if (currentBook != null) {
moduleBookStatus = await ipcNsi.getModuleBookStatus(currentBook);
}
let selectOptions = bibleSelect[0].querySelectorAll('option');
for (let i = 0; i < selectOptions.length; i++) {
let currentOption = selectOptions[i];
let currentTextType = currentTab.getTextType();
if (currentTextType == 'book' &&
moduleBookStatus != null &&
currentOption.value in moduleBookStatus &&
!moduleBookStatus[currentOption.value]) {
currentOption.disabled = true;
} else {
currentOption.disabled = false;
}
}
// Refresh the selectmenu widget
bibleSelect.selectmenu();
}
}
async isInstantLoadingBook(bibleTranslationId, bookCode) {
if (bibleTranslationId == null || bookCode == null) {
return false;
}
var instantLoad = false;
const bookChapterCount = await ipcNsi.getBookChapterCount(bibleTranslationId, bookCode);
const bookLoadingModeOption = app_controller.optionsMenu._bookLoadingModeOption;
switch (bookLoadingModeOption.value) {
case 'open-complete-book':
instantLoad = true;
break;
case 'open-chapters-large-books':
if (bookChapterCount <= INSTANT_LOADING_CHAPTER_LIMIT) {
instantLoad = true;
}
break;
}
return instantLoad;
}
}
module.exports = TranslationController;
Source