diff options
Diffstat (limited to 'ext/mixed')
-rw-r--r-- | ext/mixed/css/frame.css | 3 | ||||
-rw-r--r-- | ext/mixed/img/entry-current.png | bin | 0 -> 743 bytes | |||
-rw-r--r-- | ext/mixed/js/display.js | 177 |
3 files changed, 139 insertions, 41 deletions
diff --git a/ext/mixed/css/frame.css b/ext/mixed/css/frame.css index af689cbe..a425aca8 100644 --- a/ext/mixed/css/frame.css +++ b/ext/mixed/css/frame.css @@ -52,7 +52,8 @@ hr { */ .entry { - padding: 15px 0px 15px 0px; + padding-top: 10px; + padding-bottom: 10px; } .tag-default { diff --git a/ext/mixed/img/entry-current.png b/ext/mixed/img/entry-current.png Binary files differnew file mode 100644 index 00000000..bab7cc9b --- /dev/null +++ b/ext/mixed/img/entry-current.png diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 63620dc6..45c1e08c 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -25,6 +25,9 @@ class Display { this.audioCache = {}; this.responseCache = {}; this.sequence = 0; + this.index = 0; + + $(document).keydown(this.onKeyDown.bind(this)); } definitionAdd(definition, mode) { @@ -48,8 +51,12 @@ class Display { } showTermDefs(definitions, options, context) { + window.focus(); + this.spinner.hide(); this.definitions = definitions; + this.context = context; + this.options = options; const sequence = ++this.sequence; const params = { @@ -69,42 +76,24 @@ class Display { this.templateRender('terms.html', params).then(content => { this.container.html(content); - let offset = 0; - if (context && context.hasOwnProperty('index') && context.index < definitions.length) { - const entry = $('.entry').eq(context.index); - offset = entry.offset().top; - } + const index = context && context.hasOwnProperty('index') ? context.index : 0; + this.entryScroll(index); - window.scrollTo(0, offset); - - $('.action-add-note').click(this.onActionAddNote.bind(this)); - $('.action-play-audio').click(e => { - e.preventDefault(); - const index = Display.entryIndexFind($(e.currentTarget)); - this.audioPlay(this.definitions[index]); - }); - $('.kanji-link').click(e => { - e.preventDefault(); - - const link = $(e.target); - context = context || {}; - context.source = { - definitions, - index: Display.entryIndexFind(link) - }; - - this.kanjiFind(link.text()).then(kanjiDefs => { - this.showKanjiDefs(kanjiDefs, options, context); - }).catch(this.handleError.bind(this)); - }); + $('.action-add-note').click(this.onAddNote.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.context = context; + this.options = options; const sequence = ++this.sequence; const params = { @@ -122,17 +111,12 @@ class Display { this.templateRender('kanji.html', params).then(content => { this.container.html(content); - window.scrollTo(0, 0); - $('.action-add-note').click(this.onActionAddNote.bind(this)); - $('.source-term').click(e => { - e.preventDefault(); + const index = context && context.hasOwnProperty('index') ? context.index : 0; + this.entryScroll(index); - if (context && context.source) { - context.index = context.source.index; - this.showTermDefs(context.source.definitions, options, context); - } - }); + $('.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)); @@ -159,13 +143,125 @@ class Display { }); } - onActionAddNote(e) { + entryScroll(index, smooth) { + if (index < 0 || index >= this.definitions.length) { + return; + } + + $('.current').hide().eq(index).show(); + + const body = $('body').stop(); + const entry = $('.entry').eq(index); + const target = index === 0 ? 0 : entry.offset().top; + + if (smooth) { + body.animate({scrollTop: target}, 200); + } else { + body.scrollTop(target); + } + + this.index = index; + } + + onSourceTerm(e) { + e.preventDefault(); + + if (this.context && this.context.source) { + const context = { + url: this.context.source.url, + sentence: this.context.source.sentence, + index: this.context.source.index + }; + + this.showTermDefs(this.context.source.definitions, this.options, context); + } + } + + onKanjiLookup(e) { + e.preventDefault(); + + const link = $(e.target); + const context = { + source: { + definitions, + index: Display.entryIndexFind(link) + } + }; + + if (this.context) { + context.sentence = this.context.sentence || ''; + context.url = this.context.url || ''; + } + + this.kanjiFind(link.text()).then(kanjiDefs => { + this.showKanjiDefs(kanjiDefs, options, context); + }).catch(this.handleError.bind(this)); + } + + onPlayAudio(e) { + e.preventDefault(); + + const index = Display.entryIndexFind($(e.currentTarget)); + this.audioPlay(this.definitions[index]); + } + + onAddNote(e) { e.preventDefault(); - this.spinner.show(); const link = $(e.currentTarget); - const mode = link.data('mode'); const index = Display.entryIndexFind(link); + this.noteAdd(index, link.data('mode')); + } + + onKeyDown(e) { + const handlers = { + 36: /* home */ () => { + this.entryScroll(0, true); + }, + + 35: /* end */ () => { + this.entryScroll(this.definitions.length - 1, true); + }, + + 38: /* up */ () => { + this.entryScroll(this.index - 1, true); + }, + + 40: /* down */ () => { + this.entryScroll(this.index + 1, true); + }, + + 209: /* [ */ () => { + + }, + + 221: /* ] */ () => { + + }, + + 220: /* \ */ () => { + this.audioPlay(this.definitions[this.index]); + }, + + 8: /* backspace */ () => { + + } + }; + + const handler = handlers[e.keyCode]; + if (handler) { + e.preventDefault(); + handler(); + } + } + + sourceTerm(index) { + + + } + + noteAdd(index, mode) { + this.spinner.show(); const definition = this.definitions[index]; let promise = Promise.resolve(); @@ -187,8 +283,9 @@ class Display { }).catch(this.handleError.bind(this)).then(() => this.spinner.hide()); } - audioPlay(definition) { + audioPlay(index) { this.spinner.show(); + const definition = this.definitions[index]; for (const key in this.audioCache) { this.audioCache[key].pause(); |