git ssb

1+

Daan Patchwork / patchwork



Tree: 06ded70b47c2b7b6dbd436a59f532f6caff0e67c

Files: 06ded70b47c2b7b6dbd436a59f532f6caff0e67c / lib / depject / app / html / progress-notifier.js

4445 bytesRaw
1const { computed, when, h, Value } = require('mutant')
2const nest = require('depnest')
3const sustained = require('../../../sustained')
4const pull = require('pull-stream')
5
6exports.gives = nest('app.html.progressNotifier')
7
8exports.needs = nest({
9 'sbot.pull.stream': 'first',
10 'progress.obs': {
11 indexes: 'first',
12 replicate: 'first',
13 migration: 'first'
14 },
15 'intl.sync.i18n': 'first'
16})
17
18exports.create = function (api) {
19 const i18n = api.intl.sync.i18n
20 return nest('app.html.progressNotifier', function () {
21 const replicateProgress = api.progress.obs.replicate()
22 const indexes = api.progress.obs.indexes()
23 const migration = api.progress.obs.migration()
24 const waiting = Waiting(replicateProgress)
25
26 const pending = computed(indexes, (progress) => progress.target - progress.current || 0)
27 const pendingMigration = computed(migration, (progress) => progress.target - progress.current || 0)
28
29 const indexProgress = computed(indexes, calcProgress)
30 const migrationProgress = computed(migration, calcProgress)
31
32 let incompleteFeedsFrom = 0
33
34 const downloadProgress = computed([replicateProgress.feeds, replicateProgress.incompleteFeeds], (feeds, incomplete) => {
35 if (incomplete > incompleteFeedsFrom) {
36 incompleteFeedsFrom = incomplete
37 } else if (incomplete === 0) {
38 incompleteFeedsFrom = 0
39 }
40 if (feeds && incomplete) {
41 return clamp((feeds - incomplete) / incompleteFeedsFrom)
42 } else {
43 return 1
44 }
45 })
46
47 const hidden = sustained(computed([waiting, downloadProgress, pending, pendingMigration], (waiting, downloadProgress, pending, pendingMigration) => {
48 return !waiting && downloadProgress === 1 && !pending && !pendingMigration
49 }), 500)
50
51 // HACK: css animations take up WAY TO MUCH cpu, remove from dom when inactive
52 const displaying = computed(sustained(hidden, 500, x => !x), hidden => !hidden)
53
54 // HACK: Resolves an issue where buttons are non-responsive while indexing.
55 //
56 // 1. Sets the *progress* cursor when Patchwork is focused.
57 // 2. Sets the *wait* cursor when a publish button is selected.
58 // 3. Sets the *not-allowed* cursor when a publish button is activated.
59 //
60 // If a user disregards all of the above then `modules/sbot.js` will return
61 // an error telling the user to wait until indexing is finished.
62 const readOnlyMode = `
63 body {
64 cursor: progress;
65 }
66
67 button:not(.-clear):not(.-cancel):not(.cancel), .like, .reply, .tag, .ToggleButton, .Picker {
68 cursor: wait;
69 opacity: 0.5;
70 }
71
72 button:not(.-clear):not(.-cancel):not(.cancel):active, .like:active, .reply:active, .tag:active, .ToggleButton:active, .Picker:active {
73 cursor: not-allowed;
74 }
75 `
76
77 return h('div.info', { hidden }, [
78 h('div.status', [
79 when(displaying, h('Loading -small', [
80 when(pendingMigration,
81 [h('span.info', i18n('Upgrading database')), h('progress', { style: { 'margin-left': '10px' }, min: 0, max: 1, value: migrationProgress })],
82 when(computed(downloadProgress, (v) => v < 1),
83 [h('span.info', i18n('Downloading new messages')), h('progress', { style: { 'margin-left': '10px' }, min: 0, max: 1, value: downloadProgress })],
84 when(pending, [
85 [
86 h('span.info', i18n('Indexing database')),
87 h('progress', { style: { 'margin-left': '10px' }, min: 0, max: 1, value: indexProgress }),
88 h('style', readOnlyMode)
89 ]
90 ], i18n('Scuttling...'))
91 )
92 )
93 ]))
94 ])
95 ])
96 })
97
98 // scoped
99
100 function Waiting (progress) {
101 const waiting = Value()
102 let lastTick = Date.now()
103
104 progress && progress(update)
105
106 pull(
107 api.sbot.pull.stream(sbot => sbot.patchwork.heartbeat()),
108 pull.drain(update)
109 )
110
111 setInterval(function () {
112 if (lastTick < Date.now() - 1000) {
113 waiting.set(true)
114 }
115 }, 1000)
116
117 return waiting
118
119 // scoped
120
121 function update () {
122 lastTick = Date.now()
123 waiting.set(false)
124 }
125 }
126}
127
128function clamp (value) {
129 return Math.min(1, Math.max(0, value)) || 0
130}
131
132function calcProgress (progress) {
133 const range = progress.target - progress.start
134 if (range) {
135 return (progress.current - progress.start) / range
136 } else {
137 return 1
138 }
139}
140

Built with git-ssb-web