wip
This commit is contained in:
parent
7fbe2ddaf3
commit
aac2a58b5f
@ -20,6 +20,7 @@
|
||||
<script src="/bg/js/templates.js"></script>
|
||||
<script src="/bg/js/translator.js"></script>
|
||||
<script src="/bg/js/util.js"></script>
|
||||
<script src="/bg/js/util.js"></script>
|
||||
<script src="/mixed/js/audio.js"></script>
|
||||
<script src="/mixed/js/japanese.js"></script>
|
||||
<script src="/mixed/js/request.js"></script>
|
||||
|
@ -17,26 +17,26 @@
|
||||
*/
|
||||
|
||||
|
||||
window.displayWindow = new class extends Display {
|
||||
window.yomichan_window = new class extends Display {
|
||||
constructor() {
|
||||
super($('#spinner'), $('#content'));
|
||||
|
||||
this.search = $('#search').click(this.onSearch.bind(this));
|
||||
this.query = $('#query').on('input', this.inputSearch.bind(this));
|
||||
this.query = $('#query').on('input', this.onSearchInput.bind(this));
|
||||
this.intro = $('#intro');
|
||||
|
||||
window.wanakana.bind(this.query.get(0));
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
onError(error) {
|
||||
window.alert(`Error: ${error}`);
|
||||
}
|
||||
|
||||
clearSearch() {
|
||||
onSearchClear() {
|
||||
this.query.focus().select();
|
||||
}
|
||||
|
||||
inputSearch() {
|
||||
onSearchInput() {
|
||||
this.search.prop('disabled', this.query.val().length === 0);
|
||||
}
|
||||
|
||||
@ -46,9 +46,9 @@ window.displayWindow = new class extends Display {
|
||||
try {
|
||||
this.intro.slideUp();
|
||||
const {length, definitions} = await apiTermsFind(this.query.val());
|
||||
super.showTermDefs(definitions, await apiOptionsGet());
|
||||
super.termsShow(definitions, await apiOptionsGet());
|
||||
} catch (e) {
|
||||
this.handleError(e);
|
||||
this.onError(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -40,10 +40,10 @@
|
||||
<script src="/bg/js/dictionary.js"></script>
|
||||
<script src="/bg/js/handlebars.js"></script>
|
||||
<script src="/bg/js/templates.js"></script>
|
||||
<script src="/bg/js/util.js"></script>
|
||||
<script src="/mixed/js/audio.js"></script>
|
||||
<script src="/mixed/js/display.js"></script>
|
||||
<script src="/mixed/js/japanese.js"></script>
|
||||
<script src="/mixed/js/request.js"></script>
|
||||
|
||||
<script src="/bg/js/display-window.js"></script>
|
||||
</body>
|
||||
|
@ -18,9 +18,9 @@
|
||||
<img src="/mixed/img/spinner.gif">
|
||||
</div>
|
||||
|
||||
<div id="content"></div>
|
||||
<div id="definitions"></div>
|
||||
|
||||
<div id="orphan">
|
||||
<div id="error-orphaned">
|
||||
<div class="container-fluid">
|
||||
<h1>Yomichan Updated!</h1>
|
||||
<p>
|
||||
|
@ -17,65 +17,45 @@
|
||||
*/
|
||||
|
||||
|
||||
window.displayFrame = new class extends Display {
|
||||
window.yomichan_frame = new class extends Display {
|
||||
constructor() {
|
||||
super($('#spinner'), $('#content'));
|
||||
$(window).on('message', this.onMessage.bind(this));
|
||||
}
|
||||
|
||||
definitionAdd(definition, mode) {
|
||||
return apiDefinitionAdd(definition, mode);
|
||||
}
|
||||
|
||||
definitionsAddable(definitions, modes) {
|
||||
return apiDefinitionsAddable(definitions, modes);
|
||||
}
|
||||
|
||||
noteView(noteId) {
|
||||
return apiNoteView(noteId);
|
||||
}
|
||||
|
||||
templateRender(template, data) {
|
||||
return apiTemplateRender(template, data);
|
||||
}
|
||||
|
||||
kanjiFind(character) {
|
||||
return apiKanjiFind(character);
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
if (window.yomichanOrphaned) {
|
||||
this.showOrphaned();
|
||||
onError(error) {
|
||||
if (window.yomichan_orphaned) {
|
||||
this.onOrphaned();
|
||||
} else {
|
||||
window.alert(`Error: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
clearSearch() {
|
||||
onOrphaned() {
|
||||
$('#definitions').hide();
|
||||
$('#error-orphaned').show();
|
||||
}
|
||||
|
||||
onSearchClear() {
|
||||
window.parent.postMessage('popupClose', '*');
|
||||
}
|
||||
|
||||
selectionCopy() {
|
||||
onSelectionCopy() {
|
||||
window.parent.postMessage('selectionCopy', '*');
|
||||
}
|
||||
|
||||
showOrphaned() {
|
||||
$('#content').hide();
|
||||
$('#orphan').show();
|
||||
}
|
||||
|
||||
onMessage(e) {
|
||||
const handlers = {
|
||||
showTermDefs: ({definitions, options, context}) => {
|
||||
this.showTermDefs(definitions, options, context);
|
||||
termsShow: ({definitions, options, context}) => {
|
||||
this.termsShow(definitions, options, context);
|
||||
},
|
||||
|
||||
showKanjiDefs: ({definitions, options, context}) => {
|
||||
this.showKanjiDefs(definitions, options, context);
|
||||
kanjiShow: ({definitions, options, context}) => {
|
||||
this.kanjiShow(definitions, options, context);
|
||||
},
|
||||
|
||||
showOrphaned: () => {
|
||||
this.showOrphaned();
|
||||
orphaned: () => {
|
||||
this.onOrphaned();
|
||||
}
|
||||
};
|
||||
|
||||
@ -89,8 +69,8 @@ window.displayFrame = new class extends Display {
|
||||
onKeyDown(e) {
|
||||
const handlers = {
|
||||
67: /* c */ () => {
|
||||
if (e.ctrlKey && window.getSelection().toString() === '') {
|
||||
this.selectionCopy();
|
||||
if (e.ctrlKey && !window.getSelection().toString()) {
|
||||
this.onSelectionCopy();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
|
||||
window.yomichanFrontend = new class {
|
||||
window.yomichan_frontend = new class {
|
||||
constructor() {
|
||||
this.popup = new Popup();
|
||||
this.popupTimer = null;
|
||||
@ -27,17 +27,23 @@ window.yomichanFrontend = new class {
|
||||
this.lastTextSource = null;
|
||||
this.pendingLookup = false;
|
||||
this.options = null;
|
||||
}
|
||||
|
||||
apiOptionsGet().then(options => {
|
||||
this.options = options;
|
||||
window.addEventListener('mouseover', this.onMouseOver.bind(this));
|
||||
window.addEventListener('mousedown', this.onMouseDown.bind(this));
|
||||
window.addEventListener('mouseup', this.onMouseUp.bind(this));
|
||||
window.addEventListener('mousemove', this.onMouseMove.bind(this));
|
||||
window.addEventListener('resize', e => this.searchClear());
|
||||
window.addEventListener('message', this.onFrameMessage.bind(this));
|
||||
chrome.runtime.onMessage.addListener(this.onBgMessage.bind(this));
|
||||
}).catch(this.handleError.bind(this));
|
||||
async prepare() {
|
||||
try {
|
||||
this.options = await apiOptionsGet();
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
}
|
||||
|
||||
window.addEventListener('message', this.onFrameMessage.bind(this));
|
||||
window.addEventListener('mousedown', this.onMouseDown.bind(this));
|
||||
window.addEventListener('mousemove', this.onMouseMove.bind(this));
|
||||
window.addEventListener('mouseover', this.onMouseOver.bind(this));
|
||||
window.addEventListener('mouseup', this.onMouseUp.bind(this));
|
||||
window.addEventListener('resize', this.onResize.bind(this));
|
||||
|
||||
chrome.runtime.onMessage.addListener(this.onBgMessage.bind(this));
|
||||
}
|
||||
|
||||
popupTimerSet(callback) {
|
||||
@ -144,7 +150,11 @@ window.yomichanFrontend = new class {
|
||||
callback();
|
||||
}
|
||||
|
||||
searchAt(point) {
|
||||
onResize() {
|
||||
this.onSearchClear();
|
||||
}
|
||||
|
||||
async searchAt(point) {
|
||||
if (this.pendingLookup) {
|
||||
return;
|
||||
}
|
||||
@ -160,70 +170,69 @@ window.yomichanFrontend = new class {
|
||||
}
|
||||
|
||||
this.pendingLookup = true;
|
||||
this.searchTerms(textSource).then(found => {
|
||||
if (!found) {
|
||||
return this.searchKanji(textSource);
|
||||
|
||||
try {
|
||||
if (!await this.searchTerms(textSource)) {
|
||||
await this.searchKanji(textSource);
|
||||
}
|
||||
}).catch(error => {
|
||||
this.handleError(error, textSource);
|
||||
}).then(() => {
|
||||
docImposterDestroy();
|
||||
this.pendingLookup = false;
|
||||
});
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
}
|
||||
|
||||
docImposterDestroy();
|
||||
this.pendingLookup = false;
|
||||
}
|
||||
|
||||
searchTerms(textSource) {
|
||||
async searchTerms(textSource) {
|
||||
textSource.setEndOffset(this.options.scanning.length);
|
||||
|
||||
return apiTermsFind(textSource.text()).then(({definitions, length}) => {
|
||||
if (definitions.length === 0) {
|
||||
return false;
|
||||
} else {
|
||||
textSource.setEndOffset(length);
|
||||
const {definitions, length} = await apiTermsFind(textSource.text());
|
||||
if (definitions.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
|
||||
const url = window.location.href;
|
||||
this.popup.showTermDefs(
|
||||
textSource.getRect(),
|
||||
definitions,
|
||||
this.options,
|
||||
{sentence, url}
|
||||
);
|
||||
textSource.setEndOffset(length);
|
||||
|
||||
this.lastTextSource = textSource;
|
||||
if (this.options.scanning.selectText) {
|
||||
textSource.select();
|
||||
}
|
||||
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
|
||||
const url = window.location.href;
|
||||
this.popup.termsShow(
|
||||
textSource.getRect(),
|
||||
definitions,
|
||||
this.options,
|
||||
{sentence, url}
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
this.lastTextSource = textSource;
|
||||
if (this.options.scanning.selectText) {
|
||||
textSource.select();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
searchKanji(textSource) {
|
||||
async searchKanji(textSource) {
|
||||
textSource.setEndOffset(1);
|
||||
|
||||
return apiKanjiFind(textSource.text()).then(definitions => {
|
||||
if (definitions.length === 0) {
|
||||
return false;
|
||||
} else {
|
||||
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
|
||||
const url = window.location.href;
|
||||
this.popup.showKanjiDefs(
|
||||
textSource.getRect(),
|
||||
definitions,
|
||||
this.options,
|
||||
{sentence, url}
|
||||
);
|
||||
const definitions = await apiKanjiFind(textSource.text());
|
||||
if (definitions.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.lastTextSource = textSource;
|
||||
if (this.options.scanning.selectText) {
|
||||
textSource.select();
|
||||
}
|
||||
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
|
||||
const url = window.location.href;
|
||||
this.popup.showKanji(
|
||||
textSource.getRect(),
|
||||
definitions,
|
||||
this.options,
|
||||
{sentence, url}
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
this.lastTextSource = textSource;
|
||||
if (this.options.scanning.selectText) {
|
||||
textSource.select();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
searchClear() {
|
||||
@ -238,7 +247,7 @@ window.yomichanFrontend = new class {
|
||||
}
|
||||
|
||||
handleError(error, textSource) {
|
||||
if (window.yomichanOrphaned) {
|
||||
if (window.yomichan_orphaned) {
|
||||
if (textSource && this.options.scanning.modifier !== 'none') {
|
||||
this.popup.showOrphaned(textSource.getRect(), this.options);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ function utilInvoke(action, params={}) {
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
window.yomichanOrphaned = true;
|
||||
window.yomichan_orphaned = true;
|
||||
reject(e.message);
|
||||
}
|
||||
});
|
||||
|
@ -32,171 +32,57 @@ class Display {
|
||||
$(document).keydown(this.onKeyDown.bind(this));
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
onError(error) {
|
||||
throw 'override me';
|
||||
}
|
||||
|
||||
clearSearch() {
|
||||
onSearchClear() {
|
||||
throw 'override me';
|
||||
}
|
||||
|
||||
showTermDefs(definitions, options, context) {
|
||||
window.focus();
|
||||
|
||||
this.spinner.hide();
|
||||
this.definitions = definitions;
|
||||
this.options = options;
|
||||
this.context = context;
|
||||
|
||||
const sequence = ++this.sequence;
|
||||
const params = {
|
||||
definitions,
|
||||
addable: options.anki.enable,
|
||||
grouped: options.general.groupResults,
|
||||
playback: options.general.audioSource !== 'disabled',
|
||||
debug: options.general.debugInfo
|
||||
};
|
||||
|
||||
if (context) {
|
||||
for (const definition of definitions) {
|
||||
if (context.sentence) {
|
||||
definition.cloze = Display.clozeBuild(context.sentence, definition.source);
|
||||
}
|
||||
|
||||
definition.url = context.url;
|
||||
}
|
||||
}
|
||||
|
||||
apiTemplateRender('terms.html', params).then(content => {
|
||||
this.container.html(content);
|
||||
this.entryScroll(context && context.index || 0);
|
||||
|
||||
$('.action-add-note').click(this.onAddNote.bind(this));
|
||||
$('.action-view-note').click(this.onViewNote.bind(this));
|
||||
$('.action-play-audio').click(this.onPlayAudio.bind(this));
|
||||
$('.kanji-link').click(this.onKanjiLookup.bind(this));
|
||||
|
||||
return this.adderButtonsUpdate(['term-kanji', 'term-kana'], sequence);
|
||||
}).catch(this.handleError.bind(this));
|
||||
}
|
||||
|
||||
showKanjiDefs(definitions, options, context) {
|
||||
window.focus();
|
||||
|
||||
this.spinner.hide();
|
||||
this.definitions = definitions;
|
||||
this.options = options;
|
||||
this.context = context;
|
||||
|
||||
const sequence = ++this.sequence;
|
||||
const params = {
|
||||
definitions,
|
||||
source: context && context.source,
|
||||
addable: options.anki.enable,
|
||||
debug: options.general.debugInfo
|
||||
};
|
||||
|
||||
if (context) {
|
||||
for (const definition of definitions) {
|
||||
if (context.sentence) {
|
||||
definition.cloze = Display.clozeBuild(context.sentence);
|
||||
}
|
||||
|
||||
definition.url = context.url;
|
||||
}
|
||||
}
|
||||
|
||||
apiTemplateRender('kanji.html', params).then(content => {
|
||||
this.container.html(content);
|
||||
this.entryScroll(context && context.index || 0);
|
||||
|
||||
$('.action-add-note').click(this.onAddNote.bind(this));
|
||||
$('.source-term').click(this.onSourceTerm.bind(this));
|
||||
|
||||
return this.adderButtonsUpdate(['kanji'], sequence);
|
||||
}).catch(this.handleError.bind(this));
|
||||
}
|
||||
|
||||
adderButtonsUpdate(modes, sequence) {
|
||||
return apiDefinitionsAddable(this.definitions, modes).then(states => {
|
||||
if (!states || sequence !== this.sequence) {
|
||||
return;
|
||||
}
|
||||
|
||||
states.forEach((state, index) => {
|
||||
for (const mode in state) {
|
||||
const button = Display.adderButtonFind(index, mode);
|
||||
if (state[mode]) {
|
||||
button.removeClass('disabled');
|
||||
} else {
|
||||
button.addClass('disabled');
|
||||
}
|
||||
|
||||
button.removeClass('pending');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
entryScroll(index, smooth) {
|
||||
index = Math.min(index, this.definitions.length - 1);
|
||||
index = Math.max(index, 0);
|
||||
|
||||
$('.current').hide().eq(index).show();
|
||||
|
||||
const container = $('html,body').stop();
|
||||
const entry = $('.entry').eq(index);
|
||||
const target = index === 0 ? 0 : entry.offset().top;
|
||||
|
||||
if (smooth) {
|
||||
container.animate({scrollTop: target}, 200);
|
||||
} else {
|
||||
container.scrollTop(target);
|
||||
}
|
||||
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
onSourceTerm(e) {
|
||||
onSourceTermView(e) {
|
||||
e.preventDefault();
|
||||
this.sourceBack();
|
||||
}
|
||||
|
||||
onKanjiLookup(e) {
|
||||
e.preventDefault();
|
||||
async onKanjiLookup(e) {
|
||||
try {
|
||||
e.preventDefault();
|
||||
|
||||
const link = $(e.target);
|
||||
const context = {
|
||||
source: {
|
||||
definitions: this.definitions,
|
||||
index: Display.entryIndexFind(link)
|
||||
const link = $(e.target);
|
||||
const context = {
|
||||
source: {
|
||||
definitions: this.definitions,
|
||||
index: Display.entryIndexFind(link)
|
||||
}
|
||||
};
|
||||
|
||||
if (this.context) {
|
||||
context.sentence = this.context.sentence;
|
||||
context.url = this.context.url;
|
||||
}
|
||||
};
|
||||
|
||||
if (this.context) {
|
||||
context.sentence = this.context.sentence;
|
||||
context.url = this.context.url;
|
||||
const kanjiDefs = await apiKanjiFind(link.text());
|
||||
this.kanjiShow(kanjiDefs, this.options, context);
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
}
|
||||
|
||||
apiKanjiFind(link.text()).then(kanjiDefs => {
|
||||
this.showKanjiDefs(kanjiDefs, this.options, context);
|
||||
}).catch(this.handleError.bind(this));
|
||||
}
|
||||
|
||||
onPlayAudio(e) {
|
||||
onAudioPlay(e) {
|
||||
e.preventDefault();
|
||||
const index = Display.entryIndexFind($(e.currentTarget));
|
||||
this.audioPlay(this.definitions[index]);
|
||||
}
|
||||
|
||||
onAddNote(e) {
|
||||
onNoteAdd(e) {
|
||||
e.preventDefault();
|
||||
const link = $(e.currentTarget);
|
||||
const index = Display.entryIndexFind(link);
|
||||
this.noteAdd(this.definitions[index], link.data('mode'));
|
||||
}
|
||||
|
||||
onViewNote(e) {
|
||||
onNoteView(e) {
|
||||
e.preventDefault();
|
||||
const link = $(e.currentTarget);
|
||||
const index = Display.entryIndexFind(link);
|
||||
@ -220,48 +106,48 @@ class Display {
|
||||
|
||||
const handlers = {
|
||||
27: /* escape */ () => {
|
||||
this.clearSearch();
|
||||
this.onSearchClear();
|
||||
return true;
|
||||
},
|
||||
|
||||
33: /* page up */ () => {
|
||||
if (e.altKey) {
|
||||
this.entryScroll(this.index - 3, true);
|
||||
this.entryScrollIntoView(this.index - 3, true);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
34: /* page down */ () => {
|
||||
if (e.altKey) {
|
||||
this.entryScroll(this.index + 3, true);
|
||||
this.entryScrollIntoView(this.index + 3, true);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
35: /* end */ () => {
|
||||
if (e.altKey) {
|
||||
this.entryScroll(this.definitions.length - 1, true);
|
||||
this.entryScrollIntoView(this.definitions.length - 1, true);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
36: /* home */ () => {
|
||||
if (e.altKey) {
|
||||
this.entryScroll(0, true);
|
||||
this.entryScrollIntoView(0, true);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
38: /* up */ () => {
|
||||
if (e.altKey) {
|
||||
this.entryScroll(this.index - 1, true);
|
||||
this.entryScrollIntoView(this.index - 1, true);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
40: /* down */ () => {
|
||||
if (e.altKey) {
|
||||
this.entryScroll(this.index + 1, true);
|
||||
this.entryScrollIntoView(this.index + 1, true);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
@ -317,6 +203,135 @@ class Display {
|
||||
}
|
||||
}
|
||||
|
||||
async termsShow(definitions, options, context) {
|
||||
try {
|
||||
window.focus();
|
||||
|
||||
this.definitions = definitions;
|
||||
this.options = options;
|
||||
this.context = context;
|
||||
|
||||
const sequence = ++this.sequence;
|
||||
const params = {
|
||||
definitions,
|
||||
addable: options.anki.enable,
|
||||
grouped: options.general.groupResults,
|
||||
playback: options.general.audioSource !== 'disabled',
|
||||
debug: options.general.debugInfo
|
||||
};
|
||||
|
||||
if (context) {
|
||||
for (const definition of definitions) {
|
||||
if (context.sentence) {
|
||||
definition.cloze = Display.clozeBuild(context.sentence, definition.source);
|
||||
}
|
||||
|
||||
definition.url = context.url;
|
||||
}
|
||||
}
|
||||
|
||||
const content = await apiTemplateRender('terms.html', params);
|
||||
this.container.html(content);
|
||||
this.entryScrollIntoView(context && context.index || 0);
|
||||
|
||||
$('.action-add-note').click(this.onNoteAdd.bind(this));
|
||||
$('.action-view-note').click(this.onNoteView.bind(this));
|
||||
$('.action-play-audio').click(this.onAudioPlay.bind(this));
|
||||
$('.kanji-link').click(this.onKanjiLookup.bind(this));
|
||||
|
||||
await this.adderButtonUpdate(['term-kanji', 'term-kana'], sequence);
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
async kanjiShow(definitions, options, context) {
|
||||
try {
|
||||
window.focus();
|
||||
|
||||
this.definitions = definitions;
|
||||
this.options = options;
|
||||
this.context = context;
|
||||
|
||||
const sequence = ++this.sequence;
|
||||
const params = {
|
||||
definitions,
|
||||
source: context && context.source,
|
||||
addable: options.anki.enable,
|
||||
debug: options.general.debugInfo
|
||||
};
|
||||
|
||||
if (context) {
|
||||
for (const definition of definitions) {
|
||||
if (context.sentence) {
|
||||
definition.cloze = Display.clozeBuild(context.sentence);
|
||||
}
|
||||
|
||||
definition.url = context.url;
|
||||
}
|
||||
}
|
||||
|
||||
const content = await apiTemplateRender('kanji.html', params);
|
||||
this.container.html(content);
|
||||
this.entryScrollIntoView(context && context.index || 0);
|
||||
|
||||
$('.action-add-note').click(this.onNoteAdd.bind(this));
|
||||
$('.source-term').click(this.onSourceTermView.bind(this));
|
||||
|
||||
await this.adderButtonUpdate(['kanji'], sequence);
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
async adderButtonUpdate(modes, sequence) {
|
||||
try {
|
||||
this.spinner.show();
|
||||
|
||||
const states = apiDefinitionsAddable(this.definitions, modes);
|
||||
if (!states || sequence !== this.sequence) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < states.length; ++i) {
|
||||
const state = states[i];
|
||||
for (const mode in state) {
|
||||
const button = Display.adderButtonFind(i, mode);
|
||||
if (state[mode]) {
|
||||
button.removeClass('disabled');
|
||||
} else {
|
||||
button.addClass('disabled');
|
||||
}
|
||||
|
||||
button.removeClass('pending');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
} finally {
|
||||
this.spinner.hide();
|
||||
}
|
||||
}
|
||||
|
||||
entryScrollIntoView(index, smooth) {
|
||||
index = Math.min(index, this.definitions.length - 1);
|
||||
index = Math.max(index, 0);
|
||||
|
||||
$('.current').hide().eq(index).show();
|
||||
|
||||
const container = $('html,body').stop();
|
||||
const entry = $('.entry').eq(index);
|
||||
const target = index === 0 ? 0 : entry.offset().top;
|
||||
|
||||
if (smooth) {
|
||||
container.animate({scrollTop: target}, 200);
|
||||
} else {
|
||||
container.scrollTop(target);
|
||||
}
|
||||
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
sourceBack() {
|
||||
if (this.context && this.context.source) {
|
||||
const context = {
|
||||
@ -325,35 +340,42 @@ class Display {
|
||||
index: this.context.source.index
|
||||
};
|
||||
|
||||
this.showTermDefs(this.context.source.definitions, this.options, context);
|
||||
this.termsShow(this.context.source.definitions, this.options, context);
|
||||
}
|
||||
}
|
||||
|
||||
noteAdd(definition, mode) {
|
||||
this.spinner.show();
|
||||
return apiDefinitionAdd(definition, mode).then(noteId => {
|
||||
async noteAdd(definition, mode) {
|
||||
try {
|
||||
this.spinner.show();
|
||||
|
||||
const noteId = await apiDefinitionAdd(definition, mode);
|
||||
if (noteId) {
|
||||
const index = this.definitions.indexOf(definition);
|
||||
Display.adderButtonFind(index, mode).addClass('disabled');
|
||||
Display.viewerButtonFind(index).removeClass('pending disabled').data('noteId', noteId);
|
||||
} else {
|
||||
this.handleError('note could not be added');
|
||||
throw 'note could note be added';
|
||||
}
|
||||
}).catch(this.handleError.bind(this)).then(() => this.spinner.hide());
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
} finally {
|
||||
this.spinner.hide();
|
||||
}
|
||||
}
|
||||
|
||||
audioPlay(definition) {
|
||||
this.spinner.show();
|
||||
async audioPlay(definition) {
|
||||
try {
|
||||
this.spinner.show();
|
||||
|
||||
for (const key in this.audioCache) {
|
||||
this.audioCache[key].pause();
|
||||
}
|
||||
|
||||
audioBuildUrl(definition, this.options.general.audioSource, this.responseCache).then(url => {
|
||||
let url = await audioBuildUrl(definition, this.options.general.audioSource, this.responseCache);
|
||||
if (!url) {
|
||||
url = '/mixed/mp3/button.mp3';
|
||||
}
|
||||
|
||||
for (const key in this.audioCache) {
|
||||
this.audioCache[key].pause();
|
||||
}
|
||||
|
||||
let audio = this.audioCache[url];
|
||||
if (audio) {
|
||||
audio.currentTime = 0;
|
||||
@ -371,7 +393,11 @@ class Display {
|
||||
audio.play();
|
||||
};
|
||||
}
|
||||
}).catch(this.handleError.bind(this)).then(() => this.spinner.hide());
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
} finally {
|
||||
this.spinner.hide();
|
||||
}
|
||||
}
|
||||
|
||||
static clozeBuild(sentence, source) {
|
||||
|
Loading…
Reference in New Issue
Block a user