From 14b9e0621b34d34411c1e3eec8ff1d89b6717756 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 13 Dec 2020 12:32:43 -0500 Subject: [PATCH] Updated welcome page (#1107) * Make storage controller optional * Make more elements optional * Update styles * Create new welcome page * Update URL for welcome guide * Remove old guide * Fix unused global --- ext/bg/css/settings2.css | 14 +- ext/bg/guide.html | 40 -- ext/bg/js/backend.js | 2 +- ext/bg/js/settings/dictionary-controller.js | 35 +- .../settings/dictionary-import-controller.js | 7 +- .../settings2/settings-display-controller.js | 6 +- ext/bg/js/welcome-main.js | 84 ++++ ext/bg/settings2.html | 2 +- ext/bg/welcome.html | 372 ++++++++++++++++++ 9 files changed, 500 insertions(+), 62 deletions(-) delete mode 100644 ext/bg/guide.html create mode 100644 ext/bg/js/welcome-main.js create mode 100644 ext/bg/welcome.html diff --git a/ext/bg/css/settings2.css b/ext/bg/css/settings2.css index 9b5bea81..e15fa080 100644 --- a/ext/bg/css/settings2.css +++ b/ext/bg/css/settings2.css @@ -46,9 +46,10 @@ --settings-group-wrap: nowrap; --show-preview-label-height: 40px; - --font-size-default: 14px; + --font-size-default-no-units: 14; + --font-size-default: calc(1px * var(--font-size-default-no-units)); --font-size-small: 12px; - --line-height-default: calc(20 / 14); + --line-height-default: calc(20 / var(--font-size-default-no-units)); --outline-item-height: 40px; --outline-item-icon-size: 32px; --input-width: 100px; @@ -586,9 +587,16 @@ h3 { .settings-group.settings-group-top-margin { margin-top: 1.0125em; } +.settings-item:not([hidden]) { + display: block; +} .settings-item-button { cursor: pointer; } +a.settings-item-button { + color: var(--text-color-default); + text-decoration: none; +} .settings-item-outer { display: block; width: 100%; @@ -2335,7 +2343,7 @@ code.anki-field-marker { margin: 0; padding: 0; width: 100%; - height: calc(0.425em * 4 + 1em * (20 / 14) * 3); + height: calc(0.425em * 4 + 1em * var(--line-height-default) * 3); } diff --git a/ext/bg/guide.html b/ext/bg/guide.html deleted file mode 100644 index d75a9931..00000000 --- a/ext/bg/guide.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - Welcome to Yomichan! - - - - - - - - - - - -
- - -

- Read the steps below to get up and running with Yomichan. For complete documentation, - visit the official homepage. -

- -
    -
  1. Click on the icon in the browser toolbar to open the Yomichan actions dialog.
  2. -
  3. Click on the cog icon in the middle to open the options page.
  4. -
  5. Import the dictionaries you wish to use for term and Kanji searches.
  6. -
  7. Hold down Shift key or the middle mouse button as you move your mouse over text to display definitions.
  8. -
  9. Click on the icon to hear the term pronounced by a native speaker.
  10. -
  11. Click on individual Kanji in the term definition results to view additional information about those characters.
  12. -
- -

This startup notification can be turned off on the Yomichan options page.

-
- - diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index b2ea3cd6..3229e278 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -206,7 +206,7 @@ class Backend { const options = this.getOptions({current: true}); if (options.general.showGuide) { - chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')}); + chrome.tabs.create({url: chrome.runtime.getURL('/bg/welcome.html')}); } this._clipboardMonitor.on('change', this._onClipboardTextChange.bind(this)); diff --git a/ext/bg/js/settings/dictionary-controller.js b/ext/bg/js/settings/dictionary-controller.js index ba28ba1c..2592e6a2 100644 --- a/ext/bg/js/settings/dictionary-controller.js +++ b/ext/bg/js/settings/dictionary-controller.js @@ -58,22 +58,29 @@ class DictionaryEntry { const versionNode = node.querySelector('.dictionary-version'); const wildcardSupportedCheckbox = node.querySelector('.dictionary-prefix-wildcard-searches-supported'); - const hasDetails = this._setupDetails(detailsTable); + const hasDetails = (detailsTable !== null && this._setupDetails(detailsTable)); this._hasDetails = hasDetails; titleNode.textContent = title; versionNode.textContent = `rev.${revision}`; - wildcardSupportedCheckbox.checked = !!prefixWildcardsSupported; - - outdatedContainer.hidden = (version >= 3); - if (detailsToggleLink !== null) { detailsToggleLink.hidden = !hasDetails; } - - enabledCheckbox.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'enabled']); - priorityInput.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'priority']); + if (wildcardSupportedCheckbox !== null) { + wildcardSupportedCheckbox.checked = !!prefixWildcardsSupported; + } + if (outdatedContainer !== null) { + outdatedContainer.hidden = (version >= 3); + } + if (detailsToggleLink !== null) { + detailsToggleLink.hidden = !hasDetails; + } + if (enabledCheckbox !== null) { + enabledCheckbox.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'enabled']); + } + if (priorityInput !== null) { + priorityInput.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'priority']); + } if (allowSecondarySearchesCheckbox !== null) { allowSecondarySearchesCheckbox.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'allowSecondarySearches']); } - if (deleteButton !== null) { this._eventListeners.addEventListener(deleteButton, 'click', this._onDeleteButtonClicked.bind(this), false); } @@ -84,7 +91,9 @@ class DictionaryEntry { if (detailsToggleLink !== null && this._detailsContainer !== null) { this._eventListeners.addEventListener(detailsToggleLink, 'click', this._onDetailsToggleLinkClicked.bind(this), false); } - this._eventListeners.addEventListener(priorityInput, 'settingChanged', this._onPriorityChanged.bind(this), false); + if (priorityInput !== null) { + this._eventListeners.addEventListener(priorityInput, 'settingChanged', this._onPriorityChanged.bind(this), false); + } } cleanup() { @@ -213,7 +222,9 @@ class DictionaryController { yomichan.on('databaseUpdated', this._onDatabaseUpdated.bind(this)); document.querySelector('#dictionary-confirm-delete-button').addEventListener('click', this._onDictionaryConfirmDelete.bind(this), false); - this._checkIntegrityButton.addEventListener('click', this._onCheckIntegrityButtonClick.bind(this), false); + if (this._checkIntegrityButton !== null) { + this._checkIntegrityButton.addEventListener('click', this._onCheckIntegrityButtonClick.bind(this), false); + } await this._onDatabaseUpdated(); } @@ -433,8 +444,8 @@ class DictionaryController { for (const progress of progressContainers) { progress.hidden = true; } if (statusFooter !== null) { statusFooter.setTaskActive(progressSelector, false); } this._setButtonsEnabled(true); - storageController.updateStats(); this._isDeleting = false; + if (storageController !== null) { storageController.updateStats(); } } } diff --git a/ext/bg/js/settings/dictionary-import-controller.js b/ext/bg/js/settings/dictionary-import-controller.js index 15632d62..4945d54c 100644 --- a/ext/bg/js/settings/dictionary-import-controller.js +++ b/ext/bg/js/settings/dictionary-import-controller.js @@ -93,7 +93,7 @@ class DictionaryImportController { if (this._modifying) { return; } const purgeNotification = this._purgeNotification; - + const storageController = this._storageController; const prevention = this._preventPageExit(); try { @@ -114,8 +114,8 @@ class DictionaryImportController { prevention.end(); if (purgeNotification !== null) { purgeNotification.hidden = true; } this._setSpinnerVisible(false); - this._storageController.updateStats(); this._setModifying(false); + if (storageController !== null) { storageController.updateStats(); } } } @@ -157,7 +157,7 @@ class DictionaryImportController { const statusString = `${percent.toFixed(0)}%`; for (const progressBar of progressBars) { progressBar.style.width = cssString; } for (const label of statusLabels) { label.textContent = statusString; } - storageController.updateStats(); + if (storageController !== null) { storageController.updateStats(); } }; const fileCount = files.length; @@ -187,6 +187,7 @@ class DictionaryImportController { } this._setSpinnerVisible(false); this._setModifying(false); + if (storageController !== null) { storageController.updateStats(); } } } diff --git a/ext/bg/js/settings2/settings-display-controller.js b/ext/bg/js/settings2/settings-display-controller.js index 2be7bf92..d0fcffd9 100644 --- a/ext/bg/js/settings2/settings-display-controller.js +++ b/ext/bg/js/settings2/settings-display-controller.js @@ -73,8 +73,10 @@ class SettingsDisplayController { }); menuSelectorObserver.observe(document.documentElement, false); - this._contentNode.addEventListener('scroll', this._onScroll.bind(this), {passive: true}); - this._topLink.addEventListener('click', this._onTopLinkClick.bind(this), false); + if (this._topLink !== null) { + this._contentNode.addEventListener('scroll', this._onScroll.bind(this), {passive: true}); + this._topLink.addEventListener('click', this._onTopLinkClick.bind(this), false); + } window.addEventListener('keydown', this._onKeyDown.bind(this), false); window.addEventListener('popstate', this._onPopState.bind(this), false); diff --git a/ext/bg/js/welcome-main.js b/ext/bg/js/welcome-main.js new file mode 100644 index 00000000..504bd88b --- /dev/null +++ b/ext/bg/js/welcome-main.js @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019-2020 Yomichan 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 . + */ + +/* global + * DictionaryController + * DictionaryImportController + * GenericSettingController + * ModalController + * ScanInputsSimpleController + * SettingsController + * SettingsDisplayController + * StatusFooter + * api + */ + +async function setupEnvironmentInfo() { + const {browser, platform} = await api.getEnvironmentInfo(); + document.documentElement.dataset.browser = browser; + document.documentElement.dataset.os = platform.os; +} + +async function setupGenericSettingsController(genericSettingController) { + await genericSettingController.prepare(); + await genericSettingController.refresh(); +} + +(async () => { + try { + document.querySelector('#content-scroll-focus').focus(); + + const statusFooter = new StatusFooter(document.querySelector('.status-footer-container')); + statusFooter.prepare(); + + api.forwardLogsToBackend(); + await yomichan.prepare(); + + setupEnvironmentInfo(); + + const optionsFull = await api.optionsGetFull(); + + const preparePromises = []; + + const modalController = new ModalController(); + modalController.prepare(); + + const settingsController = new SettingsController(optionsFull.profileCurrent); + settingsController.prepare(); + + const dictionaryController = new DictionaryController(settingsController, modalController, null, statusFooter); + dictionaryController.prepare(); + + const dictionaryImportController = new DictionaryImportController(settingsController, modalController, null, statusFooter); + dictionaryImportController.prepare(); + + const genericSettingController = new GenericSettingController(settingsController); + preparePromises.push(setupGenericSettingsController(genericSettingController)); + + const simpleScanningInputController = new ScanInputsSimpleController(settingsController); + simpleScanningInputController.prepare(); + + await Promise.all(preparePromises); + + document.documentElement.dataset.loaded = 'true'; + + const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); + settingsDisplayController.prepare(); + } catch (e) { + yomichan.logError(e); + } +})(); diff --git a/ext/bg/settings2.html b/ext/bg/settings2.html index 1cf25934..7e2e2e35 100644 --- a/ext/bg/settings2.html +++ b/ext/bg/settings2.html @@ -186,7 +186,7 @@
-
Show the welcome guide on browser startup
+
Show the welcome guide on browser startup
diff --git a/ext/bg/welcome.html b/ext/bg/welcome.html new file mode 100644 index 00000000..91b58bc9 --- /dev/null +++ b/ext/bg/welcome.html @@ -0,0 +1,372 @@ + + + + + + Welcome to Yomichan! + + + + + + + + + + + + + +
+
+ + + +

Welcome to Yomichan!

+ +

Here are some basics to get started

+
+
+
+ Clicking the Yomichan icon in the browser bar will open the quick-actions popup. +
+
+
+ The cog button will open the settings page. +
+
+ The magnifying glass button will open a search page, + enabling text and terms to be looked up using the installed dictionaries. + This can even be used in offline mode! +
+
+ The question mark button will open a page + with some general information about Yomichan. +
+
+
+
+
+ Yomichan requires one or more dictionaries to be installed in order to look up terms, kanji, and other information. + Several downloadable dictionaries can be found on the Yomichan homepage, + allowing you to choose the dictionaries most relevant for you. + Dictionaries can be configured using the button below, + or later from the the Settings page. +
+
+
+
+
Install or remove dictionaries
+
+
+ +
+
+
+
+
+
+ After dictionaries have been installed, webpage text can be scanned by moving the cursor while holding the scanning modifier key. + The default key is Shift, which can be configured below. +
+
+
+ Clicking the speaker icon of an entry in the popup search results + will play an audio clip of a term's pronunciation using an online dictionary, if available. +
+
+ Clicking on a kanji character in a term's definition will show additional information about that character. + (Requires a kanji dictionary to be installed.) +
+
+
+
+
+ This startup notification can be turned off using the options below, or later from the Settings page. +
+
+
+ +

Basic customization

+
+
+
+
Show this welcome guide on browser startup
+
+
+ +
+
+
+
+
+
Scan modifier key
+
Hold a key while moving the cursor to scan text.
+
+
+ +
+
+
+
+
+
Scan using middle mouse button
+
Hold the middle mouse button while moving the cursor to scan text.
+
+
+ +
+
+
+
+
+
Auto-hide search popup
+
When no key or button is required for scanning, the popup will hide automatically.
+
+
+ +
+
+ +
+
+
+
Scan delay (in milliseconds)
+
When no key or button is required for scanning, the delay before scanning occurs.
+
+
+ +
+
+
+
+
Theme
+
Adjust the style of the popup.
+
+
+
+
+
Body
+ +
+
+
Shadow
+ +
+
+
+
+
+
+
View more settings on the Settings page
+
+
+ +
+
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +