diff options
Diffstat (limited to 'ext/mixed/js')
| -rw-r--r-- | ext/mixed/js/display.js | 177 | 
1 files changed, 137 insertions, 40 deletions
| 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(); |