From 83606d0571a2e5cb590d33a0b0a30c6effb22fec Mon Sep 17 00:00:00 2001 From: jamesmaa Date: Thu, 19 Sep 2024 18:05:48 -0400 Subject: [PATCH] --wip-- [skip ci] --- ext/css/settings.css | 6 ++ ext/data/default-options-overrides.json | 12 --- ext/data/recommended-settings.json | 30 +++++++ ....json => recommended-settings-schema.json} | 0 ext/js/pages/settings/languages-controller.js | 33 +------ .../recommended-settings-controller.js | 90 +++++++++++++++++++ ext/js/pages/settings/settings-controller.js | 16 ++-- ext/js/pages/settings/settings-main.js | 3 + ext/settings.html | 26 ++++++ ext/templates-settings.html | 21 ++++- test/data/json.json | 6 +- types/ext/settings-controller.d.ts | 8 +- 12 files changed, 192 insertions(+), 59 deletions(-) delete mode 100644 ext/data/default-options-overrides.json create mode 100644 ext/data/recommended-settings.json rename ext/data/schemas/{default-options-overrides-schema.json => recommended-settings-schema.json} (100%) create mode 100644 ext/js/pages/settings/recommended-settings-controller.js diff --git a/ext/css/settings.css b/ext/css/settings.css index 7e6c4bc158..c70e8f9b74 100644 --- a/ext/css/settings.css +++ b/ext/css/settings.css @@ -754,6 +754,12 @@ select.short-height { color: #8b0000; } +/* Recommended settings modal */ +/* #recommended-settings-body { + display: grid; + grid-template-columns: auto 1fr; +} */ + /* Advanced settings */ .settings-group.advanced-only>.settings-item::after, diff --git a/ext/data/default-options-overrides.json b/ext/data/default-options-overrides.json deleted file mode 100644 index 23e5d9a9b7..0000000000 --- a/ext/data/default-options-overrides.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "es": [ - { - "path": "scanning.scanResolution", - "value": "word" - }, - { - "path": "foo.bar", - "value": "baz" - } - ] -} diff --git a/ext/data/recommended-settings.json b/ext/data/recommended-settings.json new file mode 100644 index 0000000000..d3610364af --- /dev/null +++ b/ext/data/recommended-settings.json @@ -0,0 +1,30 @@ +{ + "en": [ + { + "action": "set", + "path": "scanning.scanResolution", + "value": "word", + "description": "English uses spaces to separate words so scanning by word (instead of character) is recommended." + }, + { + "action": "set", + "path": "translation.searchResolution", + "value": "word", + "description": "English uses spaces to separate words so looking up whole words in the dictionary is recommended." + } + ], + "es": [ + { + "action": "set", + "path": "scanning.scanResolution", + "value": "word", + "description": "Spanish uses spaces to separate words so scanning by word (instead of character) is recommended." + }, + { + "action": "set", + "path": "translation.searchResolution", + "value": "word", + "description": "Spanish uses spaces to separate words so looking up whole words in the dictionary is recommended." + } + ] +} diff --git a/ext/data/schemas/default-options-overrides-schema.json b/ext/data/schemas/recommended-settings-schema.json similarity index 100% rename from ext/data/schemas/default-options-overrides-schema.json rename to ext/data/schemas/recommended-settings-schema.json diff --git a/ext/js/pages/settings/languages-controller.js b/ext/js/pages/settings/languages-controller.js index ee80c74986..aa917737b9 100755 --- a/ext/js/pages/settings/languages-controller.js +++ b/ext/js/pages/settings/languages-controller.js @@ -35,17 +35,11 @@ export class LanguagesController { async prepare() { this._languages = await this._settingsController.application.api.getLanguageSummaries(); this._languages.sort((a, b) => a.name.localeCompare(b.name, 'en')); - const languageSelect = this._fillSelect(this._languages); - languageSelect.addEventListener( - /** @type {string} */ ('settingChanged'), - /** @type {EventListener} */ (this._onLanguageSelectChanged.bind(this)), - false, - ); + this._fillSelect(this._languages); } /** * @param {import('language').LanguageSummary[]} languages - * @returns {Element} */ _fillSelect(languages) { const selectElement = querySelectorNotNull(document, '#language-select'); @@ -55,30 +49,5 @@ export class LanguagesController { option.text = `${name} (${iso})`; selectElement.appendChild(option); } - return selectElement; - } - - /** - * @param {import('dom-data-binder').SettingChangedEvent} settingChangedEvent - */ - _onLanguageSelectChanged(settingChangedEvent) { - // Check if there are language setting overrides and ask the user if they want to apply them - const setLanguage = settingChangedEvent.detail.value; - if (typeof setLanguage !== 'string') { return; } - - const languageSettingOverrides = this._settingsController.getLanguageSettingOverrides(setLanguage); - if (this._lastSelectedLanguage !== '' && this._lastSelectedLanguage !== setLanguage && typeof languageSettingOverrides !== 'undefined') { - const userFriendlyLanguageName = this._languages.find((language) => language.iso === setLanguage)?.name; - // eslint-disable-next-line no-alert - const yes = confirm( - 'We found default settings that work best for ' + userFriendlyLanguageName + ':\n\n' + - languageSettingOverrides.map(({path, value}) => `${path} = "${value}"`).join('\n') + '\n\n' + - 'Apply the default settings?', - ); - if (yes) { - void this._settingsController.applyLanguageSettingOverrides(setLanguage); - } - } - this._lastSelectedLanguage = setLanguage; } } diff --git a/ext/js/pages/settings/recommended-settings-controller.js b/ext/js/pages/settings/recommended-settings-controller.js new file mode 100644 index 0000000000..d28ddd37bd --- /dev/null +++ b/ext/js/pages/settings/recommended-settings-controller.js @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024 Yomitan Authors + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +import {querySelectorNotNull} from '../../dom/query-selector.js'; + +export class RecommendedSettingsController { + /** + * @param {import('./settings-controller.js').SettingsController} settingsController + */ + constructor(settingsController) { + /** @type {import('./settings-controller.js').SettingsController} */ + this._settingsController = settingsController; + /** @type {HTMLElement} */ + this._recommendedSettingsModal = querySelectorNotNull(document, '#recommended-settings-modal'); + /** @type {HTMLInputElement} */ + this._languageSelect = querySelectorNotNull(document, '#language-select'); + /** @type {HTMLInputElement} */ + this._applyButton = querySelectorNotNull(document, '#recommended-settings-apply-button'); + /** @type {} */ + } + + /** */ + async prepare() { + this._languageSelect.addEventListener('change', this._onLanguageSelectChanged.bind(this), false); + this._applyButton.addEventListener('click', this._onApplyButtonClicked.bind(this), false); + } + + /** + * @param {Event} _e + */ + _onLanguageSelectChanged(_e) { + const setLanguage = this._languageSelect.value; + if (typeof setLanguage !== 'string') { return; } + + const recommendedSettings = this._settingsController.getRecommendedSettings(setLanguage); + if (typeof recommendedSettings !== 'undefined') { + const settingsList = querySelectorNotNull(document, '#recommended-settings-list'); + settingsList.innerHTML = ''; + for (const {path, value, description} of recommendedSettings) { + const template = this._settingsController.instantiateTemplate('recommended-settings-list-item'); + + // Render checkbox + const label = querySelectorNotNull(template, '.settings-item-label'); + label.innerHTML = `${path} -> ${value}`; + + // Render description + const descriptionElement = querySelectorNotNull(template, '.settings-item-description'); + if (description !== 'undefined') { + descriptionElement.textContent = description; + } + + // Render checkbox + const checkbox /** @type {HTMLInputElement} */ = querySelectorNotNull(template, 'input[type="checkbox"]'); + checkbox.value = path; + + settingsList.append(template); + } + this._recommendedSettingsModal.hidden = false; + } + } + + /** + * @param {MouseEvent} e + */ + _onApplyButtonClicked(e) { + e.preventDefault(); + const enabledCheckboxes = querySelectorNotNull(document, '#recommended-settings-list').querySelectorAll('input[type="checkbox"]:checked'); + if (enabledCheckboxes.length > 0) { + const recommendedSettings = this._settingsController.getRecommendedSettings(this._languageSelect.value); + for (const checkbox of enabledCheckboxes) { + this._settingsController.setSetting(path, value); + } + } + this._recommendedSettingsModal.hidden = true; + } +} diff --git a/ext/js/pages/settings/settings-controller.js b/ext/js/pages/settings/settings-controller.js index 4762f41b0a..c54e899212 100644 --- a/ext/js/pages/settings/settings-controller.js +++ b/ext/js/pages/settings/settings-controller.js @@ -46,8 +46,8 @@ export class SettingsController extends EventDispatcher { this._pageExitPreventionEventListeners = new EventListenerCollection(); /** @type {HtmlTemplateCollection} */ this._templates = new HtmlTemplateCollection(); - /** @type {import('settings-controller').LanguageSettingOverrides} */ - this._languageSettingOverrides = {}; + /** @type {import('settings-controller').RecommendedSettingsByLanguage} */ + this._recommendedSettingsByLanguage = {}; } /** @type {import('../../application.js').Application} */ @@ -78,7 +78,7 @@ export class SettingsController extends EventDispatcher { /** */ async prepare() { await this._templates.loadFromFiles(['/templates-settings.html']); - this._languageSettingOverrides = await fetchJson('/data/default-options-overrides.json'); + this._recommendedSettingsByLanguage = await fetchJson('/data/recommended-settings.json'); this._application.on('optionsUpdated', this._onOptionsUpdated.bind(this)); if (this._canObservePermissionsChanges()) { chrome.permissions.onAdded.addListener(this._onPermissionsChanged.bind(this)); @@ -190,8 +190,8 @@ export class SettingsController extends EventDispatcher { * @param {string} language */ async applyLanguageSettingOverrides(language) { - /** @type {import('settings-controller').SettingOverride[]} */ - const settingOverrides = this._languageSettingOverrides[language]; + /** @type {import('settings-controller').RecommendedSetting[]} */ + const settingOverrides = this._recommendedSettingsByLanguage[language]; if (typeof settingOverrides === 'undefined') { return; } /** @type {import('settings-modifications').Modification[]} */ const modifications = settingOverrides.map(({path, value}) => ({action: 'set', path, value})); @@ -201,10 +201,10 @@ export class SettingsController extends EventDispatcher { /** * @param {string} language - * @returns {import('settings-controller').SettingOverride[]} + * @returns {import('settings-controller').RecommendedSetting[]} */ - getLanguageSettingOverrides(language) { - return this._languageSettingOverrides[language]; + getRecommendedSettings(language) { + return this._recommendedSettingsByLanguage[language]; } /** diff --git a/ext/js/pages/settings/settings-main.js b/ext/js/pages/settings/settings-main.js index ebb51276c3..5e1146eb53 100644 --- a/ext/js/pages/settings/settings-main.js +++ b/ext/js/pages/settings/settings-main.js @@ -40,6 +40,7 @@ import {PersistentStorageController} from './persistent-storage-controller.js'; import {PopupPreviewController} from './popup-preview-controller.js'; import {PopupWindowController} from './popup-window-controller.js'; import {ProfileController} from './profile-controller.js'; +import {RecommendedSettingsController} from './recommended-settings-controller.js'; import {ScanInputsController} from './scan-inputs-controller.js'; import {ScanInputsSimpleController} from './scan-inputs-simple-controller.js'; import {SecondarySearchDictionaryController} from './secondary-search-dictionary-controller.js'; @@ -174,6 +175,8 @@ await Application.main(true, async (application) => { const sortFrequencyDictionaryController = new SortFrequencyDictionaryController(settingsController); preparePromises.push(sortFrequencyDictionaryController.prepare()); + const recommendedSettingsController = new RecommendedSettingsController(settingsController); + preparePromises.push(recommendedSettingsController.prepare()); await Promise.all(preparePromises); diff --git a/ext/settings.html b/ext/settings.html index 168fefac38..1053a272c9 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -3851,5 +3851,31 @@

Pronunciation Dictionaries

+ + + diff --git a/ext/templates-settings.html b/ext/templates-settings.html index 23c014f15e..93df11c2c1 100644 --- a/ext/templates-settings.html +++ b/ext/templates-settings.html @@ -126,7 +126,7 @@
- +
@@ -473,4 +473,23 @@ + + + diff --git a/test/data/json.json b/test/data/json.json index ee6079d23f..e4e98d1219 100644 --- a/test/data/json.json +++ b/test/data/json.json @@ -99,7 +99,7 @@ "type": "AjvSchema" }, { - "path": "ext/data/schemas/default-options-overrides-schema.json", + "path": "ext/data/schemas/recommended-settings-schema.json", "typeFile": "types/test/json.d.ts", "type": "AjvSchema" }, @@ -199,10 +199,10 @@ "schema": "ext/data/schemas/recommended-dictionaries-schema.json" }, { - "path": "ext/data/default-options-overrides.json", + "path": "ext/data/recommended-settings.json", "typeFile": "types/ext/settings-controller.d.ts", "type": "LanguageSettingOverrides", - "schema": "ext/data/schemas/default-options-overrides-schema.json" + "schema": "ext/data/schemas/recommended-settings-schema.json" } ] } diff --git a/types/ext/settings-controller.d.ts b/types/ext/settings-controller.d.ts index 4a4296ba88..f445efabb5 100644 --- a/types/ext/settings-controller.d.ts +++ b/types/ext/settings-controller.d.ts @@ -58,11 +58,13 @@ export type SettingsExtraFields = THasScope extends t export type ModifyResult = Core.Response; -export type LanguageSettingOverrides = { - [key: string]: SettingOverride[]; +export type RecommendedSettingsByLanguage = { + [key: string]: RecommendedSetting[]; }; -export type SettingOverride = { +export type RecommendedSetting = { + action: string; path: string; value: string; + description: string; };