Merge pull request #448 from toasted-nutbread/badge-improvements

Badge improvements
This commit is contained in:
toasted-nutbread 2020-04-18 21:16:25 -04:00 committed by GitHub
commit 3b2663ba09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 126 additions and 54 deletions

View File

@ -28,7 +28,6 @@
* Mecab * Mecab
* Translator * Translator
* conditionsTestValue * conditionsTestValue
* dictConfigured
* dictTermsSort * dictTermsSort
* handlebarsRenderDynamic * handlebarsRenderDynamic
* jp * jp
@ -67,8 +66,6 @@ class Backend {
url: window.location.href url: window.location.href
}; };
this.isPrepared = false;
this.clipboardPasteTarget = document.querySelector('#clipboard-paste-target'); this.clipboardPasteTarget = document.querySelector('#clipboard-paste-target');
this.popupWindow = null; this.popupWindow = null;
@ -77,6 +74,11 @@ class Backend {
this.messageToken = yomichan.generateId(16); this.messageToken = yomichan.generateId(16);
this._defaultBrowserActionTitle = null;
this._isPrepared = false;
this._prepareError = false;
this._badgePrepareDelayTimer = null;
this._messageHandlers = new Map([ this._messageHandlers = new Map([
['yomichanCoreReady', {handler: this._onApiYomichanCoreReady.bind(this), async: false}], ['yomichanCoreReady', {handler: this._onApiYomichanCoreReady.bind(this), async: false}],
['optionsSchemaGet', {handler: this._onApiOptionsSchemaGet.bind(this), async: false}], ['optionsSchemaGet', {handler: this._onApiOptionsSchemaGet.bind(this), async: false}],
@ -121,18 +123,21 @@ class Backend {
} }
async prepare() { async prepare() {
try {
this._defaultBrowserActionTitle = await this._getBrowserIconTitle();
this._badgePrepareDelayTimer = setTimeout(() => {
this._badgePrepareDelayTimer = null;
this._updateBadge();
}, 1000);
this._updateBadge();
await this.database.prepare(); await this.database.prepare();
await this.translator.prepare(); await this.translator.prepare();
this.optionsSchema = await requestJson(chrome.runtime.getURL('/bg/data/options-schema.json'), 'GET'); this.optionsSchema = await requestJson(chrome.runtime.getURL('/bg/data/options-schema.json'), 'GET');
this.defaultAnkiFieldTemplates = await requestText(chrome.runtime.getURL('/bg/data/default-anki-field-templates.handlebars'), 'GET'); this.defaultAnkiFieldTemplates = await requestText(chrome.runtime.getURL('/bg/data/default-anki-field-templates.handlebars'), 'GET');
this.options = await optionsLoad(); this.options = await optionsLoad();
try {
this.options = JsonSchema.getValidValueOrDefault(this.optionsSchema, this.options); this.options = JsonSchema.getValidValueOrDefault(this.optionsSchema, this.options);
} catch (e) {
// This shouldn't happen, but catch errors just in case of bugs
logError(e);
}
this.onOptionsUpdated('background'); this.onOptionsUpdated('background');
@ -144,8 +149,6 @@ class Backend {
} }
chrome.runtime.onMessage.addListener(this.onMessage.bind(this)); chrome.runtime.onMessage.addListener(this.onMessage.bind(this));
this.isPrepared = true;
const options = this.getOptions(this.optionsContext); const options = this.getOptions(this.optionsContext);
if (options.general.showGuide) { if (options.general.showGuide) {
chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')}); chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')});
@ -156,6 +159,24 @@ class Backend {
this._sendMessageAllTabs('backendPrepared'); this._sendMessageAllTabs('backendPrepared');
const callback = () => this.checkLastError(chrome.runtime.lastError); const callback = () => this.checkLastError(chrome.runtime.lastError);
chrome.runtime.sendMessage({action: 'backendPrepared'}, callback); chrome.runtime.sendMessage({action: 'backendPrepared'}, callback);
this._isPrepared = true;
} catch (e) {
this._prepareError = true;
logError(e);
throw e;
} finally {
if (this._badgePrepareDelayTimer !== null) {
clearTimeout(this._badgePrepareDelayTimer);
this._badgePrepareDelayTimer = null;
}
this._updateBadge();
}
}
isPrepared() {
return this._isPrepared;
} }
_sendMessageAllTabs(action, params={}) { _sendMessageAllTabs(action, params={}) {
@ -207,15 +228,7 @@ class Backend {
applyOptions() { applyOptions() {
const options = this.getOptions(this.optionsContext); const options = this.getOptions(this.optionsContext);
if (!options.general.enable) { this._updateBadge();
this.setExtensionBadgeBackgroundColor('#555555');
this.setExtensionBadgeText('off');
} else if (!dictConfigured(options)) {
this.setExtensionBadgeBackgroundColor('#f0ad4e');
this.setExtensionBadgeText('!');
} else {
this.setExtensionBadgeText('');
}
this.anki.setServer(options.anki.server); this.anki.setServer(options.anki.server);
this.anki.setEnabled(options.anki.enable); this.anki.setEnabled(options.anki.enable);
@ -295,18 +308,6 @@ class Backend {
return true; return true;
} }
setExtensionBadgeBackgroundColor(color) {
if (typeof chrome.browserAction.setBadgeBackgroundColor === 'function') {
chrome.browserAction.setBadgeBackgroundColor({color});
}
}
setExtensionBadgeText(text) {
if (typeof chrome.browserAction.setBadgeText === 'function') {
chrome.browserAction.setBadgeText({text});
}
}
checkLastError() { checkLastError() {
// NOP // NOP
} }
@ -864,6 +865,77 @@ class Backend {
} }
} }
_getBrowserIconTitle() {
return (
isObject(chrome.browserAction) &&
typeof chrome.browserAction.getTitle === 'function' ?
new Promise((resolve) => chrome.browserAction.getTitle({}, resolve)) :
Promise.resolve('')
);
}
_updateBadge() {
let title = this._defaultBrowserActionTitle;
if (title === null || !isObject(chrome.browserAction)) {
// Not ready or invalid
return;
}
let text = '';
let color = null;
let status = null;
if (!this._isPrepared) {
if (this._prepareError) {
text = '!!';
color = '#f04e4e';
status = 'Error';
} else if (this._badgePrepareDelayTimer === null) {
text = '...';
color = '#f0ad4e';
status = 'Loading';
}
} else if (!this._anyOptionsMatches((options) => options.general.enable)) {
text = 'off';
color = '#555555';
status = 'Disabled';
} else if (!this._anyOptionsMatches((options) => this._isAnyDictionaryEnabled(options))) {
text = '!';
color = '#f0ad4e';
status = 'No dictionaries installed';
}
if (color !== null && typeof chrome.browserAction.setBadgeBackgroundColor === 'function') {
chrome.browserAction.setBadgeBackgroundColor({color});
}
if (text !== null && typeof chrome.browserAction.setBadgeText === 'function') {
chrome.browserAction.setBadgeText({text});
}
if (typeof chrome.browserAction.setTitle === 'function') {
if (status !== null) {
title = `${title} - ${status}`;
}
chrome.browserAction.setTitle({title});
}
}
_isAnyDictionaryEnabled(options) {
for (const {enabled} of Object.values(options.dictionaries)) {
if (enabled) {
return true;
}
}
return false;
}
_anyOptionsMatches(predicate) {
for (const {options} of this.options.profiles) {
const value = predicate(options);
if (value) { return value; }
}
return false;
}
async _renderTemplate(template, data) { async _renderTemplate(template, data) {
return handlebarsRenderDynamic(template, data); return handlebarsRenderDynamic(template, data);
} }

View File

@ -60,7 +60,7 @@ function utilBackgroundFunctionIsolate(func) {
function utilBackend() { function utilBackend() {
const backend = chrome.extension.getBackgroundPage().yomichanBackend; const backend = chrome.extension.getBackgroundPage().yomichanBackend;
if (!backend.isPrepared) { if (!backend.isPrepared()) {
throw new Error('Backend not ready yet'); throw new Error('Backend not ready yet');
} }
return backend; return backend;