diff options
Diffstat (limited to 'src/view/books.ts')
-rw-r--r-- | src/view/books.ts | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/src/view/books.ts b/src/view/books.ts deleted file mode 100644 index 5ec019a..0000000 --- a/src/view/books.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { h, withVar, mount, Html, Rx } from 'lib/rx' -import * as Book from 'book' -import * as Modal from 'view/components/modal' - -export function view(books: Rx<Array<Book.Book>>): Html { - return h('div', - { className: 'g-Books' }, - withVar<Book.Book | undefined>(undefined, (focusBook, updateFocusBook) => [ - books.map(bs => [ - focusBook.map(book => { - if (book !== undefined) { - let onKeyup = keyupHandler({ - books: bs, - book, - onUpdate: (book: Book.Book) => updateFocusBook(_ => book) - }) - - return bookDetailModal({ - book, - onClose: () => updateFocusBook(_ => undefined), - onmount: () => addEventListener('keyup', onKeyup), - onunmount: () => removeEventListener('keyup', onKeyup) - }) - } - }), - bs.map(book => viewBook({ - book, - onSelect: (book) => updateFocusBook(_ => book) - })) - ]) - ]) - ) -} - -interface KeyupHandlerParams { - books: Array<Book.Book> - book: Book.Book - onUpdate: (book: Book.Book) => void -} - -function keyupHandler({ books, book, onUpdate }: KeyupHandlerParams): ((e: KeyboardEvent) => void) { - return (e: KeyboardEvent) => { - if (e.key === 'ArrowLeft') { - const indexedBooks = books.map((b, i) => ({ b, i })) - const focus = indexedBooks.find(({ b }) => b == book) - if (focus !== undefined && focus.i > 0) { - onUpdate(books[focus.i - 1]) - } - } else if (e.key === 'ArrowRight') { - const indexedBooks = books.map((b, i) => ({ b, i })) - const focus = indexedBooks.find(({ b }) => b == book) - if (focus !== undefined && focus.i < books.length - 1) { - onUpdate(books[focus.i + 1]) - } - } - } -} - -interface ViewBookParams { - book: Book.Book - onSelect: (book: Book.Book) => void -} - -function viewBook({ book, onSelect }: ViewBookParams): Html { - return h('button', - { className: 'g-Book' }, - h('img', - { src: book.cover, - className: 'g-Book__Image', - onclick: () => onSelect(book) - } - ) - ) -} - -interface BookDetailModalParams { - book: Book.Book - onClose: () => void - onmount: () => void - onunmount: () => void -} - -function bookDetailModal({ book, onClose, onmount, onunmount }: BookDetailModalParams): Html { - return Modal.view({ - header: h('div', - h('div', { className: 'g-BookDetail__Title' }, `${book.title}, ${book.date}`), - book.subtitle && h('div', { className: 'g-BookDetail__Subtitle' }, book.subtitle) - ), - body: h('div', - { className: 'g-BookDetail' }, - h('img', { src: book.cover }), - h('div', - h('dl', - metadata('Auteur', book.authors), - metadata('Genre', book.genres) - ), - book.summary && book.summary - .split('\n') - .map(str => str.trim()) - .filter(str => str != '') - .map(str => h('p', str)) - ) - ), - onClose, - onmount, - onunmount - }) -} - -function metadata(term: string, descriptions: Array<string>): Html { - return h('div', - h('dt', term, descriptions.length > 1 && 's', ' :'), - h('dd', ' ', descriptions.join(', ')) - ) -} |