git ssb

10+

Matt McKegg / patchwork



Tree: 0df7b2e9903705c4b2201aa29a6a6c1560b102af

Files: 0df7b2e9903705c4b2201aa29a6a6c1560b102af / main-window.js

4942 bytesRaw
1var Modules = require('./modules')
2var h = require('./lib/h')
3var Value = require('@mmckegg/mutant/value')
4var when = require('@mmckegg/mutant/when')
5var computed = require('@mmckegg/mutant/computed')
6var toCollection = require('@mmckegg/mutant/dict-to-collection')
7var MutantDict = require('@mmckegg/mutant/dict')
8var MutantMap = require('@mmckegg/mutant/map')
9var watch = require('@mmckegg/mutant/watch')
10
11var plugs = require('patchbay/plugs')
12
13module.exports = function (config, ssbClient) {
14 var modules = Modules(config, ssbClient)
15
16 var screenView = plugs.first(modules.plugs.screen_view)
17
18 var searchTimer = null
19 var searchBox = h('input.search', {
20 type: 'search',
21 placeholder: 'word, @key, #channel'
22 })
23
24 searchBox.oninput = function () {
25 clearTimeout(searchTimer)
26 searchTimer = setTimeout(doSearch, 500)
27 }
28
29 searchBox.onfocus = function () {
30 if (searchBox.value) {
31 doSearch()
32 }
33 }
34
35 var forwardHistory = []
36 var backHistory = []
37
38 var views = MutantDict({
39 // preload tabs (and subscribe to update notifications)
40 '/public': screenView('/public'),
41 '/private': screenView('/private'),
42 [ssbClient.id]: screenView(ssbClient.id),
43 '/notifications': screenView('/notifications')
44 })
45
46 var lastViewed = {}
47
48 // delete cached view after 30 mins of last seeing
49 setInterval(() => {
50 views.keys().forEach((view) => {
51 if (lastViewed[view] !== true && Date.now() - lastViewed[view] > (30 * 60e3) && view !== currentView()) {
52 views.delete(view)
53 }
54 })
55 }, 60e3)
56
57 var canGoForward = Value(false)
58 var canGoBack = Value(false)
59 var currentView = Value('/public')
60
61 watch(currentView, (view) => {
62 window.location.hash = `#${view}`
63 })
64
65 window.onhashchange = function (ev) {
66 var path = window.location.hash.substring(1)
67 if (path) {
68 setView(path)
69 }
70 }
71
72 var mainElement = h('div.main', MutantMap(toCollection(views), (item) => {
73 return h('div.view', {
74 hidden: computed([item.key, currentView], (a, b) => a !== b)
75 }, [ item.value ])
76 }))
77
78 return h('MainWindow', {
79 classList: [ '-' + process.platform ]
80 }, [
81 h('div.top', [
82 h('span.history', [
83 h('a', {
84 'ev-click': goBack,
85 classList: [ when(canGoBack, '-active') ]
86 }, '<'),
87 h('a', {
88 'ev-click': goForward,
89 classList: [ when(canGoForward, '-active') ]
90 }, '>')
91 ]),
92 h('span.nav', [
93 tab('Public', '/public'),
94 tab('Private', '/private')
95 ]),
96 h('span.appTitle', ['Patchwork']),
97 h('span', [ searchBox ]),
98 h('span.nav', [
99 tab('Profile', ssbClient.id),
100 tab('Mentions', '/notifications')
101 ])
102 ]),
103 mainElement
104 ])
105
106 // scoped
107
108 function tab (name, view) {
109 var instance = views.get(view)
110 lastViewed[view] = true
111 return h('a', {
112 'ev-click': function (ev) {
113 if (instance.pendingUpdates && instance.pendingUpdates() && instance.reload) {
114 instance.reload()
115 }
116 },
117 href: `#${view}`,
118 classList: [
119 when(selected(view), '-selected')
120 ]
121 }, [
122 name,
123 when(instance.pendingUpdates, [
124 ' (', instance.pendingUpdates, ')'
125 ])
126 ])
127 }
128
129 function goBack () {
130 if (backHistory.length) {
131 canGoForward.set(true)
132 forwardHistory.push(currentView())
133 currentView.set(backHistory.pop())
134 canGoBack.set(backHistory.length > 0)
135 }
136 }
137
138 function goForward () {
139 if (forwardHistory.length) {
140 backHistory.push(currentView())
141 currentView.set(forwardHistory.pop())
142 canGoForward.set(forwardHistory.length > 0)
143 canGoBack.set(true)
144 }
145 }
146
147 function setView (view) {
148 if (!views.has(view)) {
149 views.put(view, screenView(view))
150 }
151
152 if (lastViewed[view] !== true) {
153 lastViewed[view] = Date.now()
154 }
155
156 if (currentView() && lastViewed[currentView()] !== true) {
157 lastViewed[currentView()] = Date.now()
158 }
159
160 if (view !== currentView()) {
161 canGoForward.set(false)
162 canGoBack.set(true)
163 forwardHistory.length = 0
164 backHistory.push(currentView())
165 currentView.set(view)
166 }
167 }
168
169 function doSearch () {
170 var value = searchBox.value.trim()
171 if (value.startsWith('/') || value.startsWith('?') || value.startsWith('@') || value.startsWith('#') || value.startsWith('%')) {
172 setView(value)
173 } else if (value.trim()) {
174 setView(`?${value.trim()}`)
175 } else {
176 setView('/public')
177 }
178 }
179
180 function selected (view) {
181 return computed([currentView, view], (currentView, view) => {
182 return currentView === view
183 })
184 }
185}
186
187function isSame (a, b) {
188 if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
189 for (var i = 0; i < a.length; i++) {
190 if (a[i] !== b[i]) {
191 return false
192 }
193 }
194 return true
195 } else if (a === b) {
196 return true
197 }
198}
199

Built with git-ssb-web