/* 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 PlatformHelper = require('../../../lib/platform_helper.js');
const { waitUntilIdle } = require('../../helpers/ezra_helper.js');
const i18nController = require('../../controllers/i18n_controller.js');
const eventController = require('../../controllers/event_controller.js');
const referenceVerseController = require('../../controllers/reference_verse_controller.js');
const verseListController = require('../../controllers/verse_list_controller.js');
const dbSyncController = require('../../controllers/db_sync_controller.js');
const moduleUpdateController = require('../../controllers/module_update_controller.js');
/**
* The OptionsMenu component handles all event handling related to the options menu.
*
* To add a new option, perform the following steps:
* - Add the html element for the new option in `/html/display_options_menu.html`
* - Add the locales for the new option in /locales/en/translation.json and copy the string to all other languages
* - Add a function `showOrHide<Option>BasedOnOption()` that responds to changes
* - Add the initialization for the new option in the `init()` function
* - Add a call to `showOrHide<Option>BasedOnOption()` in `refreshViewBasedOnOptions()`
*
* @category Component
*/
class OptionsMenu {
constructor() {
this.menuIsOpened = false;
this.platformHelper = new PlatformHelper();
if (this.platformHelper.isCordova()) {
var CordovaPlatform = require('../../platform/cordova_platform.js');
this.cordovaPlatform = new CordovaPlatform();
}
}
async init() {
$('#show-translation-settings-button').bind('click', function() {
app_controller.openModuleSettingsAssistant('BIBLE');
});
$('#show-dict-settings-button').bind('click', function() {
app_controller.openModuleSettingsAssistant('DICT');
});
$('#show-commentary-settings-button').bind('click', function() {
app_controller.openModuleSettingsAssistant('COMMENTARY');
});
$('#show-module-update-button').bind('click', async () => {
this.hideDisplayMenu();
await moduleUpdateController.showModuleUpdateDialog();
});
$('#setup-db-sync-button').bind('click', async () => {
this.hideDisplayMenu();
await dbSyncController.showDbSyncConfigDialog();
});
$('#displayOptionsBackButton').bind('click', () => {
setTimeout(() => { this.hideDisplayMenu(); }, 100);
});
var openVerseListsInNewTabByDefault = false;
var showSearchResultsInPopupByDefault = false;
var bookChapterNavDefault = true;
var userDataIndicatorDefault = true;
if (this.platformHelper.isCordova() && !this.platformHelper.isMobile()) {
openVerseListsInNewTabByDefault = true;
}
if (this.platformHelper.isMobile()) {
showSearchResultsInPopupByDefault = true;
bookChapterNavDefault = false;
userDataIndicatorDefault = false;
}
this._bookIntroOption = this.initConfigOption('showBookIntroOption', () => { this.showOrHideBookIntroductionBasedOnOption(); });
this._sectionTitleOption = this.initConfigOption('showSectionTitleOption', () => { this.showOrHideSectionTitlesBasedOnOption(); });
this._xrefsOption = this.initConfigOption('showXrefsOption', () => { this.showOrHideXrefsBasedOnOption(); });
this._footnotesOption = this.initConfigOption('showFootnotesOption', () => { this.showOrHideFootnotesBasedOnOption(); });
this._paragraphsOption = this.initConfigOption('showParagraphsOption', () => { this.showOrHideParagraphsBasedOnOption(); });
this._redLetterOption = this.initConfigOption('redLetterOption', () => { this.renderRedLettersBasedOnOption(); });
this._bookChapterNavOption = this.initConfigOption('showBookChapterNavigationOption', () => { this.showOrHideBookChapterNavigationBasedOnOption(); }, bookChapterNavDefault);
this._headerNavOption = this.initConfigOption('showHeaderNavigationOption', () => { this.showOrHideHeaderNavigationBasedOnOption(); });
this._tabSearchOption = this.initConfigOption('showTabSearchOption', () => { this.showOrHideTabSearchFormBasedOnOption(undefined, true); });
this._verseListNewTabOption = this.initConfigOption('openVerseListsInNewTabOption', () => {}, openVerseListsInNewTabByDefault);
this._showSearchResultsInPopupOption = this.initConfigOption('showSearchResultsInPopupOption', () => {}, showSearchResultsInPopupByDefault);
this._userDataIndicatorOption = this.initConfigOption('showUserDataIndicatorOption', () => { this.showOrHideUserDataIndicatorsBasedOnOption(); }, userDataIndicatorDefault);
this._tagsOption = this.initConfigOption('showTagsOption', () => { this.showOrHideVerseTagsBasedOnOption(); });
this._tagGroupFilterOption = this.initConfigOption('useTagGroupFilterOption', () => { this.applyTagGroupFilterBasedOnOption(); });
this._tagsColumnOption = this.initConfigOption('useTagsColumnOption', () => { this.changeTagsLayoutBasedOnOption(); });
this._verseNotesOption = this.initConfigOption('showNotesOption', () => { this.showOrHideVerseNotesBasedOnOption(); });
this._verseNotesFixedHeightOption = this.initConfigOption('fixNotesHeightOption', () => { this.fixNotesHeightBasedOnOption(); });
this._keepScreenAwakeOption = this.initConfigOption('keepScreenAwakeOption', () => { this.keepScreenAwakeBasedOnOption(); });
this._textSizeAdjustTagsNotesOption = this.initConfigOption('adjustTagsNotesTextSizeOption', () => { app_controller.textSizeSettings.updateTagsNotes(this._textSizeAdjustTagsNotesOption.isChecked); }, true);
this._adjustSidePanelTextSizeOption = this.initConfigOption('adjustSidePanelTextSizeOption', () => { app_controller.textSizeSettings.updateSidePanel(this._adjustSidePanelTextSizeOption.isChecked); });
this._selectChapterBeforeLoadingOption = this.initConfigOption('selectChapterBeforeLoadingOption', () => {});
this._bookLoadingModeOption = this.initConfigOption('bookLoadingModeOption', async () => {});
this._checkNewReleasesOption = this.initConfigOption('checkNewReleasesOption', async() => {});
this._sendCrashReportsOption = this.initConfigOption('sendCrashReportsOption', async() => { this.toggleCrashReportsBasedOnOption(); });
this.initLocaleSwitchOption();
await this.initNightModeOption();
await this.adjustOptionsMenuForPlatform();
this.refreshViewBasedOnOptions();
eventController.subscribe('on-bible-text-loaded', async (tabIndex) => {
this.showOrHideSectionTitlesBasedOnOption(tabIndex);
});
eventController.subscribe('on-tab-selected', async (tabIndex) => {
await this.refreshViewBasedOnOptions(tabIndex);
});
eventController.subscribe('on-tab-added', async (tabIndex) => {
await this.refreshViewBasedOnOptions(tabIndex);
this.initCurrentOptionsMenu(tabIndex);
});
}
async initNightModeOption() {
this._nightModeOption = this.initConfigOption('useNightModeOption', async () => {
this.hideDisplayMenu();
uiHelper.showGlobalLoadingIndicator();
theme_controller.useNightModeBasedOnOption();
await waitUntilIdle();
uiHelper.hideGlobalLoadingIndicator();
});
this._nightModeOption.checked = await theme_controller.isNightModeUsed();
var isMojaveOrLater = await this.platformHelper.isMacOsMojaveOrLater();
if (isMojaveOrLater) {
// On macOS Mojave and later we do not give the user the option to switch night mode within the app, since it is controlled via system settings.
$(this._nightModeOption).hide();
}
}
initLocaleSwitchOption() {
this._localeSwitchOption = document.querySelector('#localeSwitchOption');
this._localeSwitchOption.addEventListener('localeChanged', async (e) => {
this.hideDisplayMenu();
await waitUntilIdle();
await i18nController.changeLocale(e.detail.locale);
});
this._localeSwitchOption.addEventListener('localeDetectClicked', async () => {
this.slowlyHideDisplayMenu();
await i18nController.detectLocale();
});
}
async adjustOptionsMenuForPlatform() {
if (!this.platformHelper.isCordova()) {
// On the desktop (Electron) we do not need the screen-awake option!
$(this._keepScreenAwakeOption).hide();
}
if (this.platformHelper.isCordova()) {
var bookLoadingModeOptionPersisted = await this._bookLoadingModeOption.persisted;
if (!bookLoadingModeOptionPersisted) {
this._bookLoadingModeOption.selectedValue = 'open-chapters-all-books';
}
}
}
initCurrentOptionsMenu(tabIndex=undefined) {
var currentVerseListMenu = app_controller.getCurrentVerseListMenu(tabIndex);
currentVerseListMenu.find('.display-options-button').unbind('click').bind('click', (event) => { this.handleMenuClick(event); });
}
initConfigOption(configOptionId, eventHandler, checkedByDefault=false) {
var option = document.getElementById(configOptionId);
option.checkedByDefault = checkedByDefault;
option.addEventListener("optionChanged", async () => {
await eventHandler();
this.slowlyHideDisplayMenu();
});
return option;
}
slowlyHideDisplayMenu() {
setTimeout(() => {
this.hideDisplayMenu();
}, 300);
}
hideDisplayMenu() {
if (this.menuIsOpened) {
document.getElementById('app-container').classList.remove('fullscreen-menu');
document.getElementById('display-options-menu').style.display = 'none';
document.getElementById('display-options-menu').classList.remove('visible');
this.menuIsOpened = false;
var display_button = $('#app-container').find('.display-options-button');
display_button.removeClass('ui-state-active');
}
}
handleMenuClick(event) {
if (this.menuIsOpened) {
app_controller.handleBodyClick();
} else {
app_controller.hideAllMenus();
var currentVerseListMenu = app_controller.getCurrentVerseListMenu();
var display_options_button = currentVerseListMenu.find('.display-options-button');
var menu = $('#app-container').find('#display-options-menu');
menu.addClass('visible');
document.getElementById('app-container').classList.add('fullscreen-menu');
uiHelper.showButtonMenu(display_options_button, menu);
this.menuIsOpened = true;
event.stopPropagation();
}
}
showOrHideBookIntroductionBasedOnOption(tabIndex=undefined) {
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
var bookIntro = currentVerseList.find('.book-intro');
var paragraphElements = bookIntro.find("div[type='paragraph']");
if (paragraphElements.length > 1) {
for (var i = 0; i < paragraphElements.length; i++) {
var currentParagraph = $(paragraphElements[i]);
if (!currentParagraph.hasClass('processed') && currentParagraph[0].hasAttribute('eid')) {
currentParagraph.addClass('processed');
currentParagraph.append('<br/>');
}
}
}
if (this._bookIntroOption.isChecked) {
bookIntro.show();
} else {
bookIntro.hide();
}
}
}
async showOrHideSectionTitlesBasedOnOption(tabIndex=undefined) {
var currentVerseList = verseListController.getCurrentVerseList(tabIndex)[0];
var tabId = app_controller.tab_controller.getSelectedTabId(tabIndex);
var all_section_titles = [];
if (currentVerseList != null && currentVerseList != undefined) {
// The following code moves the sword-section-title elements before the verse-boxes
all_section_titles = currentVerseList.querySelectorAll('.sword-section-title');
for (var i = 0; i < all_section_titles.length; i++) {
var currentSectionTitle = all_section_titles[i];
var currentParent = currentSectionTitle.parentNode;
var parentClassList = currentParent.classList;
// We verify that the section title is part of the verse text
// (and not part of a chapter introduction or something similar).
if (parentClassList.contains('verse-text')) {
// Generate anchor for section headers
var sectionHeaderAnchor = document.createElement('a');
var chapter = currentSectionTitle.getAttribute('chapter');
var sectionTitleContent = currentSectionTitle.textContent;
var unixSectionHeaderId = app_controller.navigation_pane.getUnixSectionHeaderId(tabId, chapter, sectionTitleContent);
sectionHeaderAnchor.setAttribute('name', unixSectionHeaderId);
var verseBox = currentSectionTitle.closest('.verse-box');
verseBox.before(sectionHeaderAnchor);
verseBox.before(currentSectionTitle);
}
}
if (this._sectionTitleOption.isChecked) {
currentVerseList.classList.add('verse-list-with-section-titles');
} else {
currentVerseList.classList.remove('verse-list-with-section-titles');
}
}
}
showOrHideXrefsBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
var tagBoxVerseList = $('#verse-list-popup-verse-list');
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._xrefsOption.isChecked) {
currentReferenceVerse.removeClass('verse-list-without-xrefs');
currentVerseList.removeClass('verse-list-without-xrefs');
tagBoxVerseList.removeClass('verse-list-without-xrefs');
} else {
currentReferenceVerse.addClass('verse-list-without-xrefs');
currentVerseList.addClass('verse-list-without-xrefs');
tagBoxVerseList.addClass('verse-list-without-xrefs');
}
}
}
showOrHideFootnotesBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
var tagBoxVerseList = $('#verse-list-popup-verse-list');
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._footnotesOption.isChecked) {
currentReferenceVerse.removeClass('verse-list-without-footnotes');
currentVerseList.removeClass('verse-list-without-footnotes');
tagBoxVerseList.removeClass('verse-list-without-footnotes');
} else {
currentReferenceVerse.addClass('verse-list-without-footnotes');
currentVerseList.addClass('verse-list-without-footnotes');
tagBoxVerseList.addClass('verse-list-without-footnotes');
}
}
}
showOrHideParagraphsBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
var tagBoxVerseList = $('#verse-list-popup-verse-list');
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._paragraphsOption.isChecked) {
currentReferenceVerse.addClass('verse-list-with-paragraphs');
currentVerseList.addClass('verse-list-with-paragraphs');
tagBoxVerseList.addClass('verse-list-with-paragraphs');
} else {
currentReferenceVerse.removeClass('verse-list-with-paragraphs');
currentVerseList.removeClass('verse-list-with-paragraphs');
tagBoxVerseList.removeClass('verse-list-with-paragraphs');
}
}
}
renderRedLettersBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
var tagBoxVerseList = $('#verse-list-popup-verse-list');
var comparePanel = $('#compare-panel');
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._redLetterOption.isChecked) {
currentReferenceVerse.addClass('verse-list-with-red-letters');
currentVerseList.addClass('verse-list-with-red-letters');
tagBoxVerseList.addClass('verse-list-with-red-letters');
comparePanel.addClass('verse-list-with-red-letters');
} else {
currentReferenceVerse.removeClass('verse-list-with-red-letters');
currentVerseList.removeClass('verse-list-with-red-letters');
tagBoxVerseList.removeClass('verse-list-with-red-letters');
comparePanel.removeClass('verse-list-with-red-letters');
}
}
}
showOrHideBookChapterNavigationBasedOnOption(tabIndex=undefined) {
if (this._bookChapterNavOption.isChecked) {
app_controller.navigation_pane.show(tabIndex);
} else {
app_controller.navigation_pane.hide(tabIndex);
}
}
showOrHideHeaderNavigationBasedOnOption(tabIndex=undefined) {
if (this._headerNavOption.isChecked &&
app_controller.translation_controller.hasCurrentTranslationHeaderElements(tabIndex)) {
app_controller.navigation_pane.enableHeaderNavigation(tabIndex);
} else {
app_controller.navigation_pane.disableHeaderNavigation();
}
}
showOrHideTabSearchFormBasedOnOption(tabIndex=undefined, focus=false) {
var currentTab = app_controller.tab_controller.getTab(tabIndex);
if (currentTab != null && currentTab.tab_search != null) {
if (this._tabSearchOption.isChecked) {
currentTab.tab_search.show();
if (focus) currentTab.tab_search.focus();
} else {
currentTab.tab_search.resetSearch();
}
}
}
showOrHideUserDataIndicatorsBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
var currentNavigationPane = app_controller.navigation_pane.getCurrentNavigationPane(tabIndex);
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._userDataIndicatorOption.isChecked) {
currentReferenceVerse.removeClass('verse-list-without-user-data-indicators');
currentVerseList.removeClass('verse-list-without-user-data-indicators');
currentNavigationPane.addClass('with-tag-indicators');
} else {
currentReferenceVerse.addClass('verse-list-without-user-data-indicators');
currentVerseList.addClass('verse-list-without-user-data-indicators');
currentNavigationPane.removeClass('with-tag-indicators');
}
}
}
showOrHideVerseTagsBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._tagsOption.isChecked) {
currentReferenceVerse.removeClass('verse-list-without-tags');
currentVerseList.removeClass('verse-list-without-tags');
} else {
currentReferenceVerse.addClass('verse-list-without-tags');
currentVerseList.addClass('verse-list-without-tags');
}
}
}
applyTagGroupFilterBasedOnOption() {
if (this._tagGroupFilterOption.isChecked) {
eventController.publishAsync('on-tag-group-filter-enabled');
} else {
eventController.publishAsync('on-tag-group-filter-disabled');
}
}
showOrHideVerseNotesBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._verseNotesOption.isChecked) {
currentReferenceVerse.addClass('verse-list-with-notes');
currentVerseList.addClass('verse-list-with-notes');
} else {
app_controller.notes_controller.restoreCurrentlyEditedNotes();
currentReferenceVerse.removeClass('verse-list-with-notes');
currentVerseList.removeClass('verse-list-with-notes');
}
}
}
fixNotesHeightBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._verseNotesFixedHeightOption.isChecked) {
currentReferenceVerse.addClass('verse-list-scroll-notes');
currentVerseList.addClass('verse-list-scroll-notes');
} else {
currentReferenceVerse.removeClass('verse-list-scroll-notes');
currentVerseList.removeClass('verse-list-scroll-notes');
}
}
}
keepScreenAwakeBasedOnOption() {
if (!this.platformHelper.isCordova()) {
return;
}
if (this._keepScreenAwakeOption.isChecked) {
this.cordovaPlatform.keepScreenAwake();
} else {
this.cordovaPlatform.allowScreenToSleep();
}
}
changeTagsLayoutBasedOnOption(tabIndex=undefined) {
var currentReferenceVerse = referenceVerseController.getCurrentReferenceVerse(tabIndex);
var currentVerseList = verseListController.getCurrentVerseList(tabIndex);
if (currentVerseList[0] != null && currentVerseList[0] != undefined) {
if (this._tagsColumnOption.isChecked) {
currentReferenceVerse.addClass('verse-list-tags-column');
currentVerseList.addClass('verse-list-tags-column');
} else {
currentReferenceVerse.removeClass('verse-list-tags-column');
currentVerseList.removeClass('verse-list-tags-column');
}
}
}
async toggleCrashReportsBasedOnOption() {
window.sendCrashReports = this._sendCrashReportsOption.isChecked;
await ipcGeneral.setSendCrashReports(window.sendCrashReports);
}
async refreshViewBasedOnOptions(tabIndex=undefined) {
this.showOrHideBookIntroductionBasedOnOption(tabIndex);
this.showOrHideSectionTitlesBasedOnOption(tabIndex);
this.showOrHideBookChapterNavigationBasedOnOption(tabIndex);
this.showOrHideTabSearchFormBasedOnOption(tabIndex);
this.showOrHideXrefsBasedOnOption(tabIndex);
this.showOrHideFootnotesBasedOnOption(tabIndex);
this.showOrHideParagraphsBasedOnOption(tabIndex);
this.renderRedLettersBasedOnOption(tabIndex);
this.showOrHideUserDataIndicatorsBasedOnOption(tabIndex);
this.showOrHideVerseTagsBasedOnOption(tabIndex);
this.applyTagGroupFilterBasedOnOption();
this.changeTagsLayoutBasedOnOption(tabIndex);
this.showOrHideVerseNotesBasedOnOption(tabIndex);
this.fixNotesHeightBasedOnOption(tabIndex);
this.showOrHideHeaderNavigationBasedOnOption(tabIndex);
this.keepScreenAwakeBasedOnOption();
theme_controller.useNightModeBasedOnOption();
}
}
module.exports = OptionsMenu;
Source