Threaded dictionary delete (#1895)

* Generalize dictionary worker

* Add deleteDictionary functionality

* Update DictionaryController to use DictionaryDatabaseModifier

* Fix incorrect result handling
This commit is contained in:
toasted-nutbread 2021-08-14 12:41:58 -04:00 committed by GitHub
parent 3e350bd563
commit 4839503d54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 32 deletions

View File

@ -25,12 +25,22 @@ class DictionaryDatabaseModifier {
} }
importDictionary(archiveContent, details, onProgress) { importDictionary(archiveContent, details, onProgress) {
return this._invoke('importDictionary', {details, archiveContent}, [archiveContent], onProgress); return this._invoke(
'importDictionary',
{details, archiveContent},
[archiveContent],
onProgress,
this._formatimportDictionaryResult.bind(this)
);
}
deleteDictionary(dictionaryTitle, onProgress) {
return this._invoke('deleteDictionary', {dictionaryTitle}, [], onProgress);
} }
// Private // Private
_invoke(action, params, transfer, onProgress) { _invoke(action, params, transfer, onProgress, formatResult) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const worker = new Worker('/js/language/dictionary-worker-main.js', {}); const worker = new Worker('/js/language/dictionary-worker-main.js', {});
const details = { const details = {
@ -39,7 +49,8 @@ class DictionaryDatabaseModifier {
resolve, resolve,
reject, reject,
onMessage: null, onMessage: null,
onProgress onProgress,
formatResult
}; };
const onMessage = this._onMessage.bind(this, details); const onMessage = this._onMessage.bind(this, details);
details.onMessage = onMessage; details.onMessage = onMessage;
@ -54,15 +65,17 @@ class DictionaryDatabaseModifier {
switch (action) { switch (action) {
case 'complete': case 'complete':
{ {
const {worker, resolve, reject, onMessage} = details; const {worker, resolve, reject, onMessage, formatResult} = details;
details.complete = true; details.complete = true;
details.worker = null; details.worker = null;
details.resolve = null; details.resolve = null;
details.reject = null; details.reject = null;
details.onMessage = null; details.onMessage = null;
details.onProgress = null;
details.formatResult = null;
worker.removeEventListener('message', onMessage); worker.removeEventListener('message', onMessage);
worker.terminate(); worker.terminate();
this._onMessageComplete(params, resolve, reject); this._onMessageComplete(params, resolve, reject, formatResult);
} }
break; break;
case 'progress': case 'progress':
@ -74,12 +87,21 @@ class DictionaryDatabaseModifier {
} }
} }
_onMessageComplete(params, resolve, reject) { _onMessageComplete(params, resolve, reject, formatResult) {
const {error} = params; const {error} = params;
if (typeof error !== 'undefined') { if (typeof error !== 'undefined') {
reject(deserializeError(error)); reject(deserializeError(error));
} else { } else {
resolve(this._formatResult(params.result)); let {result} = params;
try {
if (typeof formatResult === 'function') {
result = formatResult(result);
}
} catch (e) {
reject(e);
return;
}
resolve(result);
} }
} }
@ -101,9 +123,8 @@ class DictionaryDatabaseModifier {
worker.postMessage({action: 'getImageResolution.response', params: response}); worker.postMessage({action: 'getImageResolution.response', params: response});
} }
_formatResult(data) { _formatimportDictionaryResult(result) {
const {result, errors} = data; result.errors = result.errors.map((error) => deserializeError(error));
const errors2 = errors.map((error) => deserializeError(error)); return result;
return {result, errors: errors2};
} }
} }

View File

@ -36,7 +36,10 @@ class DictionaryWorker {
const {action, params} = e.data; const {action, params} = e.data;
switch (action) { switch (action) {
case 'importDictionary': case 'importDictionary':
this._onImportDictionary(params); this._onMessageWithProgress(params, this._importDictionary.bind(this));
break;
case 'deleteDictionary':
this._onMessageWithProgress(params, this._deleteDictionary.bind(this));
break; break;
case 'getImageResolution.response': case 'getImageResolution.response':
this._mediaLoader.handleMessage(params); this._mediaLoader.handleMessage(params);
@ -44,7 +47,7 @@ class DictionaryWorker {
} }
} }
async _onImportDictionary({details, archiveContent}) { async _onMessageWithProgress(params, handler) {
const onProgress = (...args) => { const onProgress = (...args) => {
self.postMessage({ self.postMessage({
action: 'progress', action: 'progress',
@ -53,7 +56,7 @@ class DictionaryWorker {
}; };
let response; let response;
try { try {
const result = await this._importDictionary(archiveContent, details, onProgress); const result = await handler(params, onProgress);
response = {result}; response = {result};
} catch (e) { } catch (e) {
response = {error: serializeError(e)}; response = {error: serializeError(e)};
@ -61,11 +64,11 @@ class DictionaryWorker {
self.postMessage({action: 'complete', params: response}); self.postMessage({action: 'complete', params: response});
} }
async _importDictionary(archiveContent, importDetails, onProgress) { async _importDictionary({details, archiveContent}, onProgress) {
const dictionaryDatabase = await this._getPreparedDictionaryDatabase(); const dictionaryDatabase = await this._getPreparedDictionaryDatabase();
try { try {
const dictionaryImporter = new DictionaryImporter(this._mediaLoader, onProgress); const dictionaryImporter = new DictionaryImporter(this._mediaLoader, onProgress);
const {result, errors} = await dictionaryImporter.importDictionary(dictionaryDatabase, archiveContent, importDetails); const {result, errors} = await dictionaryImporter.importDictionary(dictionaryDatabase, archiveContent, details);
return { return {
result, result,
errors: errors.map((error) => serializeError(error)) errors: errors.map((error) => serializeError(error))
@ -75,6 +78,15 @@ class DictionaryWorker {
} }
} }
async _deleteDictionary({dictionaryTitle}, onProgress) {
const dictionaryDatabase = await this._getPreparedDictionaryDatabase();
try {
return await dictionaryDatabase.deleteDictionary(dictionaryTitle, {rate: 1000}, onProgress);
} finally {
dictionaryDatabase.close();
}
}
async _getPreparedDictionaryDatabase() { async _getPreparedDictionaryDatabase() {
const dictionaryDatabase = new DictionaryDatabase(); const dictionaryDatabase = new DictionaryDatabase();
await dictionaryDatabase.prepare(); await dictionaryDatabase.prepare();

View File

@ -16,7 +16,7 @@
*/ */
/* global /* global
* DictionaryDatabase * DictionaryDatabaseModifier
*/ */
class DictionaryEntry { class DictionaryEntry {
@ -679,19 +679,9 @@ class DictionaryController {
} }
async _deleteDictionaryInternal(dictionaryTitle, onProgress) { async _deleteDictionaryInternal(dictionaryTitle, onProgress) {
const dictionaryDatabase = await this._getPreparedDictionaryDatabase(); const dictionaryDatabaseModifier = new DictionaryDatabaseModifier();
try { await dictionaryDatabaseModifier.deleteDictionary(dictionaryTitle, onProgress);
await dictionaryDatabase.deleteDictionary(dictionaryTitle, {rate: 1000}, onProgress); yomichan.api.triggerDatabaseUpdated('dictionary', 'delete');
yomichan.api.triggerDatabaseUpdated('dictionary', 'delete');
} finally {
dictionaryDatabase.close();
}
}
async _getPreparedDictionaryDatabase() {
const dictionaryDatabase = new DictionaryDatabase();
await dictionaryDatabase.prepare();
return dictionaryDatabase;
} }
async _deleteDictionarySettings(dictionaryTitle) { async _deleteDictionarySettings(dictionaryTitle) {

View File

@ -3483,7 +3483,6 @@
<script src="/js/general/object-property-accessor.js"></script> <script src="/js/general/object-property-accessor.js"></script>
<script src="/js/general/task-accumulator.js"></script> <script src="/js/general/task-accumulator.js"></script>
<script src="/js/input/hotkey-util.js"></script> <script src="/js/input/hotkey-util.js"></script>
<script src="/js/language/dictionary-database.js"></script>
<script src="/js/language/dictionary-database-modifier.js"></script> <script src="/js/language/dictionary-database-modifier.js"></script>
<script src="/js/language/dictionary-importer-media-loader.js"></script> <script src="/js/language/dictionary-importer-media-loader.js"></script>
<script src="/js/language/sandbox/dictionary-data-util.js"></script> <script src="/js/language/sandbox/dictionary-data-util.js"></script>

View File

@ -405,7 +405,6 @@
<script src="/js/general/object-property-accessor.js"></script> <script src="/js/general/object-property-accessor.js"></script>
<script src="/js/general/task-accumulator.js"></script> <script src="/js/general/task-accumulator.js"></script>
<script src="/js/input/hotkey-util.js"></script> <script src="/js/input/hotkey-util.js"></script>
<script src="/js/language/dictionary-database.js"></script>
<script src="/js/language/dictionary-database-modifier.js"></script> <script src="/js/language/dictionary-database-modifier.js"></script>
<script src="/js/language/dictionary-importer-media-loader.js"></script> <script src="/js/language/dictionary-importer-media-loader.js"></script>
<script src="/js/media/media-util.js"></script> <script src="/js/media/media-util.js"></script>