aboutsummaryrefslogtreecommitdiff
path: root/library/client/view/filters.ts
diff options
context:
space:
mode:
Diffstat (limited to 'library/client/view/filters.ts')
-rw-r--r--library/client/view/filters.ts90
1 files changed, 90 insertions, 0 deletions
diff --git a/library/client/view/filters.ts b/library/client/view/filters.ts
new file mode 100644
index 0000000..efe4115
--- /dev/null
+++ b/library/client/view/filters.ts
@@ -0,0 +1,90 @@
+import { h, Rx, Html } from 'lib/rx'
+import * as Book from 'book'
+import * as I18n from 'lib/i18n'
+
+// Model
+
+export interface Model {
+ read?: Book.ReadStatus
+}
+
+const init: Model = {}
+
+// View
+
+interface ViewFiltersParams {
+ filteredBooks: Rx<Array<Book.Book>>
+ filters: Rx<Model>
+ updateFilters: (f: (filters: Model) => Model) => void
+}
+
+export function view({ filteredBooks, filters, updateFilters }: ViewFiltersParams): Html {
+ return h('ul',
+ h('li', [
+ h('div', { className: 'g-FilterTitle' }, 'Lecture'),
+ readFilter({
+ filteredBooks,
+ readStatus: filters.map(fs => fs.read),
+ update: (status?: Book.ReadStatus) => updateFilters(fs => {
+ fs.read = status
+ return fs
+ })
+ })
+ ])
+ )
+}
+
+interface ReadFilterParams {
+ filteredBooks: Rx<Array<Book.Book>>
+ readStatus: Rx<Book.ReadStatus | undefined>
+ update: (status?: Book.ReadStatus) => void
+}
+
+function readFilter({ filteredBooks, readStatus, update }: ReadFilterParams): Html {
+ return h('ul',
+ { className: 'g-Filters' },
+ readStatus.map(currentStatus => {
+ if (currentStatus !== undefined) {
+ return h('li',
+ { className: 'g-Filter g-Filter--Selected' },
+ h('button',
+ { onclick: () => update(undefined) },
+ filteredBooks.map(xs => unit(xs.length, readStatusLabels(currentStatus)))
+ )
+ )
+ } else {
+ return Book.readStatuses.map(status =>
+ filteredBooks.map(xs => {
+ const count = xs.filter(b => b.read === status).length
+
+ return count !== 0
+ ? h('li',
+ { className: 'g-Filter g-Filter--Unselected' },
+ h('button',
+ { onclick: () => update(status) },
+ unit(count, readStatusLabels(status))
+ )
+ )
+ : undefined
+ })
+ )
+ }
+ })
+ )
+}
+
+function unit(n: number, labels: Array<string>): string {
+ return I18n.unit(n, labels[0], labels[1], (n, str) => `${str} (${n})`)
+}
+
+function readStatusLabels(status: Book.ReadStatus): Array<string> {
+ if (status === 'Read') {
+ return ['lu', 'lus']
+ } else if (status === 'Unread') {
+ return ['non lu', 'non lus']
+ } else if (status === 'Reading') {
+ return ['en cours', 'en cours']
+ } else {
+ return ['arrêté', 'arrêtés']
+ }
+}