git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: 8397cee5bd7b17b9f2ebf584813ed0c0a035023d

Files: 8397cee5bd7b17b9f2ebf584813ed0c0a035023d / modules / app.js

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

Built with git-ssb-web