aboutsummaryrefslogtreecommitdiff
path: root/src/view/filters.ts
blob: efe4115698e9bbe6a24090afc6ee7b3eb1037023 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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']
  }
}