app/page/calendar.jsView |
---|
1 | 1 … | const nest = require('depnest') |
2 | | -const { h, Value, computed } = require('mutant') |
| 2 … | +const { h, Value, computed, Dict, throttle, dictToCollection } = require('mutant') |
| 3 … | +const pull = require('pull-stream') |
| 4 … | +const { isMsg } = require('ssb-ref') |
3 | 5 … | |
4 | 6 … | exports.gives = nest('app.page.calendar') |
5 | 7 … | |
6 | 8 … | exports.needs = nest({ |
| 9 … | + 'sbot.pull.stream': 'first' |
7 | 10 … | }) |
8 | 11 … | |
9 | 12 … | exports.create = (api) => { |
10 | 13 … | return nest('app.page.calendar', calendarPage) |
11 | 14 … | |
|
12 | 15 … | function calendarPage (location) { |
13 | | - const cal = Cal() |
| 16 … | + const store = Dict({}) |
| 17 … | + pull( |
| 18 … | + pullGatherings(2018), |
| 19 … | + pull.drain( |
| 20 … | + ({ key, date }) => store.put(key, date), |
| 21 … | + (err) => { |
| 22 … | + if (err) console.error(err) |
| 23 … | + else console.log('DONE') |
| 24 … | + } |
| 25 … | + ) |
| 26 … | + ) |
14 | 27 … | |
15 | | - return h('CalendarPage', { title: '/calendar' }, cal) |
| 28 … | + return h('CalendarPage', { title: '/calendar' }, [ |
| 29 … | + computed(throttle(dictToCollection(store), 150), collection => { |
| 30 … | + const events = collection.map(item => { |
| 31 … | + return { |
| 32 … | + date: item.value, |
| 33 … | + data: { key: item.key } |
| 34 … | + } |
| 35 … | + }) |
| 36 … | + |
| 37 … | + return Calendar(events) |
| 38 … | + }) |
| 39 … | + ]) |
16 | 40 … | } |
| 41 … | + |
| 42 … | + function pullGatherings (year) { |
| 43 … | + const query = [{ |
| 44 … | + $filter: { |
| 45 … | + value: { |
| 46 … | + timestamp: {$gt: Number(new Date(year, 0, 1))}, |
| 47 … | + content: { |
| 48 … | + type: 'about', |
| 49 … | + startDateTime: { |
| 50 … | + epoch: {$gt: 0} |
| 51 … | + } |
| 52 … | + } |
| 53 … | + } |
| 54 … | + } |
| 55 … | + }, { |
| 56 … | + $map: { |
| 57 … | + key: ['value', 'content', 'about'], |
| 58 … | + date: ['value', 'content', 'startDateTime', 'epoch'] |
| 59 … | + } |
| 60 … | + }] |
| 61 … | + |
| 62 … | + const opts = { |
| 63 … | + reverse: false, |
| 64 … | + query |
| 65 … | + } |
| 66 … | + |
| 67 … | + return pull( |
| 68 … | + api.sbot.pull.stream(server => server.query.read(opts)), |
| 69 … | + pull.filter(r => isMsg(r.key) && Number.isInteger(r.date)), |
| 70 … | + pull.map(r => { |
| 71 … | + return { key: r.key, date: new Date(r.date) } |
| 72 … | + }) |
| 73 … | + ) |
| 74 … | + } |
17 | 75 … | } |
18 | 76 … | |
| 77 … | + |
| 78 … | + |
| 79 … | + |
| 80 … | + |
| 81 … | + |
19 | 82 … | const MONTHS = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] |
20 | 83 … | const DAYS = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ] |
21 | 84 … | |
22 | | -function Cal () { |
| 85 … | +function Calendar (events) { |
| 86 … | + |
| 87 … | + |
| 88 … | + |
23 | 89 … | const year = Value(new Date().getFullYear()) |
24 | 90 … | const today = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()) |
25 | 91 … | |
26 | 92 … | |
27 | 93 … | const root = h('Calendar', [ |
28 | 94 … | Header(year), |
29 | 95 … | h('div.months', computed(year, year => { |
30 | | - return MONTHS.map((month, monthIndex) => Month({ month, monthIndex, year, today })) |
| 96 … | + return MONTHS.map((month, monthIndex) => Month({ month, monthIndex, year, today, events })) |
31 | 97 … | })) |
32 | 98 … | ]) |
33 | 99 … | |
34 | 100 … | return root |
44 | 110 … | |
45 | 111 … | ]) |
46 | 112 … | } |
47 | 113 … | |
48 | | -function Month ({ month, monthIndex, year, today }) { |
| 114 … | +function Month ({ month, monthIndex, year, today, events }) { |
49 | 115 … | const monthLength = new Date(year, monthIndex + 1, 0).getDate() |
50 | 116 … | |
51 | 117 … | |
52 | 118 … | const days = Array(monthLength).fill().map((_, i) => i + 1) |
53 | 119 … | |
54 | 120 … | var date |
| 121 … | + var dateEnd |
55 | 122 … | var weekday |
56 | 123 … | var week |
57 | 124 … | var offset = getDay(new Date(year, monthIndex, 1)) - 1 |
58 | 125 … | |
65 | 132 … | ]) |
66 | 133 … | |
67 | 134 … | function Day (day) { |
68 | 135 … | date = new Date(year, monthIndex, day) |
| 136 … | + dateEnd = new Date(year, monthIndex, day + 1) |
69 | 137 … | weekday = getDay(date) |
70 | 138 … | week = Math.ceil((day + offset) / 7) |
71 | 139 … | |
| 140 … | + const eventsOnDay = events.filter(e => { |
| 141 … | + return e.date >= date && e.date < dateEnd |
| 142 … | + }) |
| 143 … | + |
72 | 144 … | return h('CalendarDay', { |
73 | 145 … | attributes: { 'data-date': `${year}-${monthIndex + 1}-${day}` }, |
74 | 146 … | style: { |
75 | 147 … | 'grid-row': `${weekday} / ${weekday + 1}`, |
76 | 148 … | 'grid-column': `${week + 1} / ${week + 2}` |
77 | 149 … | |
78 | 150 … | }, |
79 | 151 … | classList: [ |
80 | | - date < today ? '-past' : '-future' |
| 152 … | + date < today ? '-past' : '-future', |
| 153 … | + eventsOnDay.length ? '-events' : '' |
81 | 154 … | ] |
82 | 155 … | }) |
83 | 156 … | } |
84 | 157 … | } |
98 | 171 … | |
99 | 172 … | |
100 | 173 … | |
101 | 174 … | } |
| 175 … | + |