Add info page (#1102)
* Add api.getAnkiConnectVersion * Enable basic functionality when certain features/elements aren't present * Add info page * Update information links * Update info link on the settings v2 page
This commit is contained in:
parent
92cfd31c0f
commit
5948229176
@ -32,7 +32,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<a class="nav-button action-open-options" data-icon="cog" title="Options (Middle click to open in new tab)"></a>
|
<a class="nav-button action-open-options" data-icon="cog" title="Options (Middle click to open in new tab)"></a>
|
||||||
<a class="nav-button action-open-search" data-icon="magnifying-glass" title="Search (Alt + Insert) (Middle click to open in new tab)"></a>
|
<a class="nav-button action-open-search" data-icon="magnifying-glass" title="Search (Alt + Insert) (Middle click to open in new tab)"></a>
|
||||||
<a class="nav-button action-open-help" data-icon="question-mark" title="Help"></a>
|
<a class="nav-button action-open-help" data-icon="question-mark" title="Information"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
71
ext/bg/info.html
Normal file
71
ext/bg/info.html
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>Yomichan Info</title>
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon16.png" sizes="16x16">
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon19.png" sizes="19x19">
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon32.png" sizes="32x32">
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon38.png" sizes="38x38">
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon48.png" sizes="48x48">
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon64.png" sizes="64x64">
|
||||||
|
<link rel="icon" type="image/png" href="/mixed/img/icon128.png" sizes="128x128">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/bg/css/settings2.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<div class="content-outer"><div class="content">
|
||||||
|
<div class="content-center">
|
||||||
|
|
||||||
|
<span tabindex="-1" id="content-scroll-focus"></span>
|
||||||
|
|
||||||
|
<h1>Yomichan Info</h1>
|
||||||
|
|
||||||
|
<h2 id="general">General</h2>
|
||||||
|
<div class="settings-group">
|
||||||
|
<div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label">
|
||||||
|
<ul>
|
||||||
|
<li>Extension version: <span id="version"></span></li>
|
||||||
|
<li>Platform: <span id="platform"></span></li>
|
||||||
|
<li>Browser: <span id="browser"></span></li>
|
||||||
|
<li>User agent: <span id="user-agent"></span></li>
|
||||||
|
<li>AnkiConnect version: <span id="anki-connect-version-container"><span id="anki-connect-version">...</span><em class="light" id="anki-connect-version-unknown-message" hidden> (Anki not running or connected)</em></span></li>
|
||||||
|
<li>Installed dictionaries: <span id="installed-dictionaries">...</span><em id="installed-dictionaries-none" hidden>None installed</em></li>
|
||||||
|
<li><a id="settings-export-button">Export settings</a></li>
|
||||||
|
</ul>
|
||||||
|
</div></div></div></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 id="links">Links</h2>
|
||||||
|
<div class="settings-group">
|
||||||
|
<div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label">
|
||||||
|
<ul>
|
||||||
|
<li>Information and downloadable dictionaries: <a href="https://foosoft.net/projects/yomichan/" rel="noreferrer noopener">Homepage</a></li>
|
||||||
|
<li>Source code, bug reporting, and feedback: <a href="https://github.com/FooSoft/yomichan" rel="noreferrer noopener">Github</a></li>
|
||||||
|
<li>Release notes: <a href="https://github.com/FooSoft/yomichan/releases" rel="noreferrer noopener" data-href-format="https://github.com/FooSoft/yomichan/releases/tag/{version}" id="release-notes-this-version-link">This version</a> | <a href="https://github.com/FooSoft/yomichan/releases" rel="noreferrer noopener">All versions</a></li>
|
||||||
|
<li>More extension information: <a href="/bg/permissions.html">Permissions</a> | <a href="/bg/legal.html">Licenses</a></li>
|
||||||
|
</ul>
|
||||||
|
</div></div></div></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-padding"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<!-- Scripts -->
|
||||||
|
<script src="/mixed/js/core.js"></script>
|
||||||
|
<script src="/mixed/js/yomichan.js"></script>
|
||||||
|
<script src="/mixed/js/comm.js"></script>
|
||||||
|
<script src="/mixed/js/api.js"></script>
|
||||||
|
|
||||||
|
<script src="/mixed/js/html-template-collection.js"></script>
|
||||||
|
<script src="/bg/js/settings/settings-controller.js"></script>
|
||||||
|
<script src="/bg/js/settings/backup-controller.js"></script>
|
||||||
|
|
||||||
|
<script src="/bg/js/info-main.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -49,6 +49,12 @@ class AnkiConnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getVersion() {
|
||||||
|
if (!this._enabled) { return null; }
|
||||||
|
await this._checkVersion();
|
||||||
|
return await this._invoke('version', {});
|
||||||
|
}
|
||||||
|
|
||||||
async addNote(note) {
|
async addNote(note) {
|
||||||
if (!this._enabled) { return null; }
|
if (!this._enabled) { return null; }
|
||||||
await this._checkVersion();
|
await this._checkVersion();
|
||||||
|
@ -90,6 +90,7 @@ class Backend {
|
|||||||
['kanjiFind', {async: true, contentScript: true, handler: this._onApiKanjiFind.bind(this)}],
|
['kanjiFind', {async: true, contentScript: true, handler: this._onApiKanjiFind.bind(this)}],
|
||||||
['termsFind', {async: true, contentScript: true, handler: this._onApiTermsFind.bind(this)}],
|
['termsFind', {async: true, contentScript: true, handler: this._onApiTermsFind.bind(this)}],
|
||||||
['textParse', {async: true, contentScript: true, handler: this._onApiTextParse.bind(this)}],
|
['textParse', {async: true, contentScript: true, handler: this._onApiTextParse.bind(this)}],
|
||||||
|
['getAnkiConnectVersion', {async: true, contentScript: true, handler: this._onApGetAnkiConnectVersion.bind(this)}],
|
||||||
['isAnkiConnected', {async: true, contentScript: true, handler: this._onApiIsAnkiConnected.bind(this)}],
|
['isAnkiConnected', {async: true, contentScript: true, handler: this._onApiIsAnkiConnected.bind(this)}],
|
||||||
['addAnkiNote', {async: true, contentScript: true, handler: this._onApiAddAnkiNote.bind(this)}],
|
['addAnkiNote', {async: true, contentScript: true, handler: this._onApiAddAnkiNote.bind(this)}],
|
||||||
['getAnkiNoteInfo', {async: true, contentScript: true, handler: this._onApiGetAnkiNoteInfo.bind(this)}],
|
['getAnkiNoteInfo', {async: true, contentScript: true, handler: this._onApiGetAnkiNoteInfo.bind(this)}],
|
||||||
@ -428,6 +429,10 @@ class Backend {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onApGetAnkiConnectVersion() {
|
||||||
|
return await this._anki.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
async _onApiIsAnkiConnected() {
|
async _onApiIsAnkiConnected() {
|
||||||
return await this._anki.isConnected();
|
return await this._anki.isConnected();
|
||||||
}
|
}
|
||||||
@ -786,7 +791,8 @@ class Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onCommandHelp() {
|
_onCommandHelp() {
|
||||||
chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'});
|
const url = chrome.runtime.getURL('/bg/info.html');
|
||||||
|
chrome.tabs.create({url});
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCommandOptions(params) {
|
_onCommandOptions(params) {
|
||||||
|
@ -30,7 +30,7 @@ class DisplayController {
|
|||||||
this._showExtensionInfo(manifest);
|
this._showExtensionInfo(manifest);
|
||||||
this._setupEnvironment();
|
this._setupEnvironment();
|
||||||
this._setupButtonEvents('.action-open-search', 'search', chrome.runtime.getURL('/bg/search.html'));
|
this._setupButtonEvents('.action-open-search', 'search', chrome.runtime.getURL('/bg/search.html'));
|
||||||
this._setupButtonEvents('.action-open-help', 'help', 'https://foosoft.net/projects/yomichan/');
|
this._setupButtonEvents('.action-open-help', 'help', chrome.runtime.getURL('/bg/info.html'));
|
||||||
|
|
||||||
const optionsFull = await api.optionsGetFull();
|
const optionsFull = await api.optionsGetFull();
|
||||||
this._optionsFull = optionsFull;
|
this._optionsFull = optionsFull;
|
||||||
|
123
ext/bg/js/info-main.js
Normal file
123
ext/bg/js/info-main.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global
|
||||||
|
* BackupController
|
||||||
|
* SettingsController
|
||||||
|
* api
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getBrowserDisplayName(browser) {
|
||||||
|
switch (browser) {
|
||||||
|
case 'chrome': return 'Chrome';
|
||||||
|
case 'firefox': return 'Firefox';
|
||||||
|
case 'firefox-mobile': return 'Firefox for Android';
|
||||||
|
case 'edge': return 'Edge';
|
||||||
|
case 'edge-legacy': return 'Edge Legacy';
|
||||||
|
default: return `${browser}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOperatingSystemDisplayName(os) {
|
||||||
|
switch (os) {
|
||||||
|
case 'mac': return 'Mac OS';
|
||||||
|
case 'win': return 'Windows';
|
||||||
|
case 'android': return 'Android';
|
||||||
|
case 'cros': return 'Chrome OS';
|
||||||
|
case 'linux': return 'Linux';
|
||||||
|
case 'openbsd': return 'Open BSD';
|
||||||
|
case 'unknown': return 'Unknown';
|
||||||
|
default: return `${os}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
document.querySelector('#content-scroll-focus').focus();
|
||||||
|
|
||||||
|
const manifest = chrome.runtime.getManifest();
|
||||||
|
|
||||||
|
api.forwardLogsToBackend();
|
||||||
|
await yomichan.prepare();
|
||||||
|
|
||||||
|
const {userAgent} = navigator;
|
||||||
|
const {version} = manifest;
|
||||||
|
const {browser, platform: {os}} = await api.getEnvironmentInfo();
|
||||||
|
|
||||||
|
const thisVersionLink = document.querySelector('#release-notes-this-version-link');
|
||||||
|
thisVersionLink.href = thisVersionLink.dataset.hrefFormat.replace(/\{version\}/g, version);
|
||||||
|
|
||||||
|
document.querySelector('#version').textContent = `${version}`;
|
||||||
|
document.querySelector('#browser').textContent = getBrowserDisplayName(browser);
|
||||||
|
document.querySelector('#platform').textContent = getOperatingSystemDisplayName(os);
|
||||||
|
document.querySelector('#user-agent').textContent = userAgent;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let ankiConnectVersion = null;
|
||||||
|
try {
|
||||||
|
ankiConnectVersion = await api.getAnkiConnectVersion();
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector('#anki-connect-version').textContent = (ankiConnectVersion !== null ? `${ankiConnectVersion}` : 'Unknown');
|
||||||
|
document.querySelector('#anki-connect-version-container').hasError = `${ankiConnectVersion === null}`;
|
||||||
|
document.querySelector('#anki-connect-version-unknown-message').hidden = (ankiConnectVersion !== null);
|
||||||
|
})();
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let dictionaryInfos;
|
||||||
|
try {
|
||||||
|
dictionaryInfos = await api.getDictionaryInfo();
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
let first = true;
|
||||||
|
for (const {title} of dictionaryInfos) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
fragment.appendChild(document.createTextNode(', '));
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = document.createElement('span');
|
||||||
|
node.className = 'installed-dictionary';
|
||||||
|
node.textContent = title;
|
||||||
|
fragment.appendChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector('#installed-dictionaries-none').hidden = (dictionaryInfos.length !== 0);
|
||||||
|
const container = document.querySelector('#installed-dictionaries');
|
||||||
|
container.textContent = '';
|
||||||
|
container.appendChild(fragment);
|
||||||
|
})();
|
||||||
|
|
||||||
|
const settingsController = new SettingsController();
|
||||||
|
settingsController.prepare();
|
||||||
|
|
||||||
|
const backupController = new BackupController(settingsController, null);
|
||||||
|
await backupController.prepare();
|
||||||
|
|
||||||
|
await promiseTimeout(100);
|
||||||
|
|
||||||
|
document.documentElement.dataset.loaded = 'true';
|
||||||
|
} catch (e) {
|
||||||
|
yomichan.logError(e);
|
||||||
|
}
|
||||||
|
})();
|
@ -31,25 +31,41 @@ class BackupController {
|
|||||||
this._settingsResetModal = null;
|
this._settingsResetModal = null;
|
||||||
this._settingsImportErrorModal = null;
|
this._settingsImportErrorModal = null;
|
||||||
this._settingsImportWarningModal = null;
|
this._settingsImportWarningModal = null;
|
||||||
this._optionsUtil = new OptionsUtil();
|
this._optionsUtil = null;
|
||||||
|
try {
|
||||||
|
this._optionsUtil = new OptionsUtil();
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
await this._optionsUtil.prepare();
|
if (this._optionsUtil !== null) {
|
||||||
|
await this._optionsUtil.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
this._settingsResetModal = this._modalController.getModal('settings-reset');
|
if (this._modalController !== null) {
|
||||||
this._settingsImportErrorModal = this._modalController.getModal('settings-import-error');
|
this._settingsResetModal = this._modalController.getModal('settings-reset');
|
||||||
this._settingsImportWarningModal = this._modalController.getModal('settings-import-warning');
|
this._settingsImportErrorModal = this._modalController.getModal('settings-import-error');
|
||||||
|
this._settingsImportWarningModal = this._modalController.getModal('settings-import-warning');
|
||||||
|
}
|
||||||
|
|
||||||
document.querySelector('#settings-export-button').addEventListener('click', this._onSettingsExportClick.bind(this), false);
|
this._addNodeEventListener('#settings-export-button', 'click', this._onSettingsExportClick.bind(this), false);
|
||||||
document.querySelector('#settings-import-button').addEventListener('click', this._onSettingsImportClick.bind(this), false);
|
this._addNodeEventListener('#settings-import-button', 'click', this._onSettingsImportClick.bind(this), false);
|
||||||
document.querySelector('#settings-import-file').addEventListener('change', this._onSettingsImportFileChange.bind(this), false);
|
this._addNodeEventListener('#settings-import-file', 'change', this._onSettingsImportFileChange.bind(this), false);
|
||||||
document.querySelector('#settings-reset-button').addEventListener('click', this._onSettingsResetClick.bind(this), false);
|
this._addNodeEventListener('#settings-reset-button', 'click', this._onSettingsResetClick.bind(this), false);
|
||||||
document.querySelector('#settings-reset-confirm-button').addEventListener('click', this._onSettingsResetConfirmClick.bind(this), false);
|
this._addNodeEventListener('#settings-reset-confirm-button', 'click', this._onSettingsResetConfirmClick.bind(this), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
|
_addNodeEventListener(selector, ...args) {
|
||||||
|
const node = document.querySelector(selector);
|
||||||
|
if (node === null) { return; }
|
||||||
|
|
||||||
|
node.addEventListener(...args);
|
||||||
|
}
|
||||||
|
|
||||||
_getSettingsExportDateString(date, dateSeparator, dateTimeSeparator, timeSeparator, resolution) {
|
_getSettingsExportDateString(date, dateSeparator, dateTimeSeparator, timeSeparator, resolution) {
|
||||||
const values = [
|
const values = [
|
||||||
date.getUTCFullYear().toString(),
|
date.getUTCFullYear().toString(),
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<label class="outline-item"><span class="outline-item-inner"><span class="outline-item-left">
|
<label class="outline-item"><span class="outline-item-inner"><span class="outline-item-left">
|
||||||
<label class="toggle"><input id="advanced-checkbox" type="checkbox" data-setting="general.showAdvanced" data-transform="setDocumentAttribute" data-document-attribute="data-advanced"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
<label class="toggle"><input id="advanced-checkbox" type="checkbox" data-setting="general.showAdvanced" data-transform="setDocumentAttribute" data-document-attribute="data-advanced"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
||||||
</span><span class="outline-item-label">Advanced</span></span></label>
|
</span><span class="outline-item-label">Advanced</span></span></label>
|
||||||
<a class="outline-item"><span class="outline-item-inner"><span class="outline-item-left outline-item-icon" data-icon="about"></span><span class="outline-item-label">About Yomichan</span></span></a>
|
<a href="/bg/info.html" class="outline-item"><span class="outline-item-inner"><span class="outline-item-left outline-item-icon" data-icon="about"></span><span class="outline-item-label">About Yomichan</span></span></a>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,6 +73,10 @@ const api = (() => {
|
|||||||
return this._invoke('isAnkiConnected');
|
return this._invoke('isAnkiConnected');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAnkiConnectVersion() {
|
||||||
|
return this._invoke('getAnkiConnectVersion');
|
||||||
|
}
|
||||||
|
|
||||||
addAnkiNote(note) {
|
addAnkiNote(note) {
|
||||||
return this._invoke('addAnkiNote', {note});
|
return this._invoke('addAnkiNote', {note});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user