Files: d1627bb325d9d1acbb1ba98a75ceb37a6b537c85 / lib / depject / page / html / render / settings.js
7390 bytesRaw
1 | const { computed, h, map, Value, watch } = require('mutant') |
2 | const nest = require('depnest') |
3 | const packageInfo = require('../../../../../package.json') |
4 | const ExpanderHook = require('../../../../expander-hook') |
5 | |
6 | const themeNames = Object.keys(require('../../../../../styles')) |
7 | const electron = require('electron') |
8 | |
9 | exports.needs = nest({ |
10 | 'app.navigate': 'first', |
11 | 'settings.obs.get': 'first', |
12 | 'intl.sync.locales': 'first', |
13 | 'intl.sync.i18n': 'first', |
14 | 'intl.sync.localeNames': 'first' |
15 | }) |
16 | |
17 | exports.gives = nest('page.html.render') |
18 | |
19 | let availableDictionaries = Value([]) |
20 | |
21 | electron.ipcRenderer.on('setAvailableDictionaries', (ev, langs) => { |
22 | availableDictionaries.set(langs) |
23 | }) |
24 | |
25 | exports.create = function (api) { |
26 | return nest('page.html.render', function channel (path) { |
27 | if (path !== '/settings') return |
28 | const i18n = api.intl.sync.i18n |
29 | |
30 | const locales = api.intl.sync.locales() |
31 | const localeNameLookup = api.intl.sync.localeNames() |
32 | const fontSizes = ['8px', '10px', '12px', '14px', '16px', '18px', '20px'] |
33 | const fontFamilies = [ |
34 | 'serif', |
35 | 'sans-serif', |
36 | 'cursive', |
37 | 'fantasy', |
38 | 'monospace' |
39 | ] |
40 | |
41 | const theme = api.settings.obs.get('patchwork.theme', 'light') |
42 | const lang = api.settings.obs.get('patchwork.lang', '') |
43 | const spellcheckLangs = api.settings.obs.get('patchwork.spellcheckLangs', ['en-GB']) |
44 | const enableSpellCheck = api.settings.obs.get('patchwork.enableSpellCheck', true) |
45 | const spellcheckParams = computed([spellcheckLangs, enableSpellCheck], (langs, enabled) => ({ langs, enabled })) |
46 | watch(spellcheckParams, (params) => { |
47 | electron.ipcRenderer.invoke('setSpellcheckLangs', params) |
48 | }) |
49 | const fontSize = api.settings.obs.get('patchwork.fontSize', '') |
50 | const fontFamily = api.settings.obs.get('patchwork.fontFamily', '') |
51 | const includeParticipating = api.settings.obs.get('patchwork.includeParticipating', false) |
52 | const autoDeleteBlocked = api.settings.obs.get('patchwork.autoDeleteBlocked', false) |
53 | |
54 | // const filterFollowing = api.settings.obs.get('filters.following') |
55 | // const filterSubscriptions = api.settings.obs.get('filters.subscriptions') |
56 | // const onlySubscribed = api.settings.obs.get('filters.onlySubscribed') |
57 | // const filterChannelViewSubscriptions = api.settings.obs.get('filters.channelView.subscriptions') |
58 | |
59 | const prepend = [ |
60 | h('PageHeading', [ |
61 | h('h1', [ |
62 | h('strong', i18n('Settings')) |
63 | ]) |
64 | ]) |
65 | ] |
66 | |
67 | return h('Scroller', { style: { overflow: 'auto' } }, [ |
68 | h('div.wrapper', [ |
69 | h('section.prepend', prepend), |
70 | h('section.content', [ |
71 | |
72 | h('section', [ |
73 | h('h2', i18n('Theme')), |
74 | h('select', { |
75 | style: { 'font-size': '120%' }, |
76 | value: theme, |
77 | 'ev-change': (ev) => theme.set(ev.target.value) |
78 | }, [ |
79 | themeNames.map(name => h('option', { value: name }, [name])) |
80 | ]) |
81 | ]), |
82 | |
83 | h('section', [ |
84 | h('h2', i18n('Interface Language')), |
85 | h('select', { |
86 | style: { 'font-size': '120%' }, |
87 | value: lang, |
88 | 'ev-change': (ev) => lang.set(ev.target.value) |
89 | }, [ |
90 | h('option', { value: '' }, i18n('Default')), |
91 | locales.map(code => h('option', { value: code }, [ |
92 | '[', code, '] ', getLocaleName(code) |
93 | ])) |
94 | ]) |
95 | ]), |
96 | |
97 | h('section', [ |
98 | h('h2', i18n('Spellchecking')), |
99 | h('div', [ |
100 | checkbox(enableSpellCheck, { |
101 | label: i18n('Enable Spellchecking') |
102 | }) |
103 | ]), |
104 | h('h3', i18n('Languages to check for (select multiple)')), |
105 | h('select', { |
106 | disabled: computed(enableSpellCheck, (b) => !b), |
107 | multiple: true, |
108 | size: 10, |
109 | style: { 'font-size': '120%' }, |
110 | hooks: [SpellcheckChangeHook(spellcheckLangs)] |
111 | }, [ |
112 | map(availableDictionaries, (code) => h('option', { |
113 | value: code, |
114 | selected: spellcheckLangs().indexOf(code) !== -1, |
115 | }, [ |
116 | '[', code, '] ', getLocaleName(code) |
117 | ])) |
118 | ]) |
119 | ]), |
120 | |
121 | h('section', [ |
122 | h('h2', i18n('Font Size')), |
123 | h('select', { |
124 | style: { 'font-size': '120%' }, |
125 | value: fontSize, |
126 | 'ev-change': (ev) => fontSize.set(ev.target.value) |
127 | }, [ |
128 | h('option', { value: '' }, i18n('Default')), |
129 | fontSizes.map(size => h('option', { value: size }, size)) |
130 | ]) |
131 | ]), |
132 | |
133 | h('section', [ |
134 | h('h2', i18n('Font Family')), |
135 | h('select', { |
136 | style: { 'font-size': '120%' }, |
137 | value: fontFamily, |
138 | 'ev-change': (ev) => fontFamily.set(ev.target.value) |
139 | }, [ |
140 | h('option', { value: '' }, i18n('Default')), |
141 | fontFamilies.map(family => h('option', { value: family, }, family)) |
142 | ]) |
143 | ]), |
144 | h('h2', i18n('Notification Options')), |
145 | |
146 | h('div', [ |
147 | checkbox(includeParticipating, { |
148 | label: i18n('Include "Participating" tab in navigation bar') |
149 | }) |
150 | ]), |
151 | |
152 | h('h2', i18n('Blocking')), |
153 | |
154 | h('div', [ |
155 | checkbox(autoDeleteBlocked, { |
156 | label: i18n('Automatically delete messages from blocked authors. This is irreversible and will cause problems with clients that share the database but do not support deleted messages. Enable at your own risk!') |
157 | }) |
158 | ]) |
159 | ]), |
160 | |
161 | // h('section', [ |
162 | // h('h2', i18n('Channel Feed Options')), |
163 | |
164 | // h('div', [ |
165 | // checkbox(filterChannelViewSubscriptions, { |
166 | // label: i18n('Hide channel subscription messages') |
167 | // }) |
168 | // ]) |
169 | // ]), |
170 | |
171 | h('section', [ |
172 | h('h2', i18n('Key export')), |
173 | |
174 | h('p', [ |
175 | i18n('Click'), ' ', |
176 | h('a', { |
177 | href: '#', |
178 | 'ev-click': function () { |
179 | api.app.navigate('/mnemonic', {}) |
180 | } |
181 | }, i18n('here')), ' ', |
182 | i18n('to export your secret as a mnemonic.'), |
183 | ' (', 'English only, sorry.',')', |
184 | ]) |
185 | ]), |
186 | |
187 | h('section', [ |
188 | h('h2', i18n('Information')), |
189 | |
190 | h('p', `${packageInfo.productName} ${packageInfo.version}`) |
191 | ]) |
192 | ]) |
193 | ]) |
194 | |
195 | function getLocaleName (code) { |
196 | const translated = i18n(code) |
197 | const name = localeNameLookup[code] |
198 | |
199 | if (name !== translated && code !== translated) { |
200 | return `${name} (${translated})` |
201 | } else { |
202 | return name |
203 | } |
204 | } |
205 | }) |
206 | } |
207 | |
208 | function checkbox (param, { label }) { |
209 | return h('label', [ |
210 | h('input', { |
211 | type: 'checkbox', |
212 | checked: param, |
213 | 'ev-change': (ev) => param.set(ev.target.checked) |
214 | }), ' ', label |
215 | ]) |
216 | } |
217 | |
218 | function SpellcheckChangeHook (spellcheckLangs) { |
219 | return function (element) { |
220 | element.addEventListener('change', (ev) => { |
221 | const newLangs = [] |
222 | for (const c of ev.target.children) { |
223 | if (c.selected) { |
224 | newLangs.push(c.value) |
225 | } |
226 | } |
227 | spellcheckLangs.set(newLangs) |
228 | }) |
229 | } |
230 | } |
231 |
Built with git-ssb-web