Files: 6791a012f6f25d8aeb64cae36c5f8ff3b21e9132 / app / page / settings.js
2342 bytesRaw
1 | const nest = require('depnest') |
2 | const { h, Value, computed } = require('mutant') |
3 | |
4 | exports.gives = nest({ |
5 | 'app.html.menuItem': true, |
6 | 'app.page.settings': true |
7 | }) |
8 | |
9 | exports.needs = nest({ |
10 | 'app.html.settings': 'map', |
11 | 'app.html.scroller': 'first', |
12 | 'app.sync.goTo': 'first' |
13 | }) |
14 | |
15 | exports.create = function (api) { |
16 | return nest({ |
17 | 'app.html.menuItem': menuItem, |
18 | 'app.page.settings': settingsPage |
19 | }) |
20 | |
21 | function menuItem () { |
22 | return h('a', { |
23 | 'ev-click': () => api.app.sync.goTo({ page: 'settings' }) |
24 | }, '/settings') |
25 | } |
26 | |
27 | function settingsPage (location) { |
28 | const state = { |
29 | groups: groupSettings(api.app.html.settings()), |
30 | activeGroup: Value(0) |
31 | } |
32 | |
33 | var page = h('SettingsPage', { title: '/settings' }, [ |
34 | h('div.container', computed(state.activeGroup, activeGroup => { |
35 | return [ |
36 | h('section.groups', state.groups.map((group, i) => { |
37 | return h('div.group', |
38 | { |
39 | 'className': i === activeGroup ? '-active' : '', |
40 | 'ev-click': () => state.activeGroup.set(i) |
41 | }, |
42 | group.name |
43 | ) |
44 | })), |
45 | h('section.group-settings', state.groups[activeGroup].subgroups.map(Setting)) |
46 | ] |
47 | })) |
48 | ]) |
49 | |
50 | function Setting (setting) { |
51 | return h('div.setting', [ |
52 | h('h2', setting.title), |
53 | setting.body |
54 | ]) |
55 | } |
56 | |
57 | var { container } = api.app.html.scroller({ prepend: page }) |
58 | container.title = '/settings' |
59 | container.keyboardScroll = function (n) { |
60 | if (isNaN(n)) return |
61 | |
62 | state.activeGroup.set((state.activeGroup() + n) % state.groups.length) |
63 | } |
64 | return container |
65 | } |
66 | } |
67 | |
68 | function groupSettings (settings) { |
69 | const groupedByGroup = settings |
70 | .reduce((acc, setting) => { |
71 | if (!setting.title || !setting.body) throw new Error('setting sections require title, body') |
72 | |
73 | const group = (setting.group || setting.title).toLowerCase() |
74 | if (acc[group]) acc[group].push(setting) |
75 | else acc[group] = [setting] |
76 | |
77 | return acc |
78 | }, {}) |
79 | |
80 | return Object.keys(groupedByGroup) |
81 | .map(name => { |
82 | return { |
83 | name, |
84 | subgroups: groupedByGroup[name] |
85 | } |
86 | }) |
87 | .sort((a, b) => { |
88 | if (a === 'general') return -1 |
89 | else if (b === 'general') return 1 |
90 | else return a < b ? -1 : +1 |
91 | }) |
92 | } |
93 |
Built with git-ssb-web