Files: 286f58e95fb08e5233963b593bb28cd72bf2655a / main-window.js
6606 bytesRaw
1 | var h = require('./lib/h') |
2 | var Value = require('@mmckegg/mutant/value') |
3 | var computed = require('@mmckegg/mutant/computed') |
4 | var when = require('@mmckegg/mutant/when') |
5 | var send = require('@mmckegg/mutant/send') |
6 | var electron = require('electron') |
7 | var Player = require('./widgets/player') |
8 | var onceTrue = require('./lib/once-true') |
9 | var watch = require('@mmckegg/mutant/watch') |
10 | var MutantMap = require('@mmckegg/mutant/map') |
11 | var LatestUpdate = require('./lib/latest-update') |
12 | var sanitizeFileName = require('sanitize-filename') |
13 | |
14 | var views = { |
15 | discoveryFeed: require('./views/discovery-feed'), |
16 | followingFeed: require('./views/following-feed'), |
17 | profile: require('./views/profile'), |
18 | post: require('./views/audio-post') |
19 | } |
20 | |
21 | module.exports = function (client, config) { |
22 | var api = require('./api')(client, config) |
23 | var background = require('./models/background-remote')(config) |
24 | var currentView = Value(['discoveryFeed']) |
25 | |
26 | var backHistory = [] |
27 | var forwardHistory = [] |
28 | var canGoForward = Value(false) |
29 | var canGoBack = Value(false) |
30 | |
31 | var latestUpdate = LatestUpdate() |
32 | window.latestUpdate = latestUpdate |
33 | |
34 | var actions = { |
35 | openEditProfileWindow, |
36 | openJoinPubWindow, |
37 | editPost, |
38 | saveFile (item, cb) { |
39 | electron.remote.dialog.showSaveDialog(electron.remote.getCurrentWindow(), { |
40 | title: 'Export Audio File', |
41 | defaultPath: sanitizeFileName(`${item.author.displayName()} - ${item.title()}.mp3`), |
42 | filters: [ |
43 | {name: 'MP3', extensions: ['mp3']} |
44 | ] |
45 | }, function (path) { |
46 | if (path) { |
47 | background.exportFile(item.audioSrc(), path, cb) |
48 | } else { |
49 | cb && cb(false) |
50 | } |
51 | }) |
52 | }, |
53 | repost (item) { |
54 | |
55 | }, |
56 | viewProfile (id) { |
57 | actions.setView('profile', id) |
58 | }, |
59 | viewPost (id) { |
60 | actions.setView('post', id) |
61 | }, |
62 | setView: function (view, ...args) { |
63 | var newView = [view, ...args] |
64 | if (!isSame(newView, currentView())) { |
65 | canGoForward.set(false) |
66 | canGoBack.set(true) |
67 | forwardHistory.length = 0 |
68 | backHistory.push([currentView(), mainElement.scrollTop]) |
69 | currentView.set(newView) |
70 | mainElement.scrollTop = 0 |
71 | } |
72 | } |
73 | } |
74 | |
75 | background.stats(x => console.log(x)) |
76 | |
77 | var profile = api.getOwnProfile() |
78 | var discoveryFeed = api.getDiscoveryFeed() |
79 | var suggestedProfiles = api.getSuggestedProfiles(15) |
80 | var following = MutantMap(api.rankProfileIds(profile.following), id => api.getProfile(id)) |
81 | var followingFeed = api.getFollowingFeed() |
82 | |
83 | // hold these open |
84 | watch(suggestedProfiles) |
85 | watch(discoveryFeed) |
86 | watch(followingFeed) |
87 | |
88 | var context = { config, api, background, actions, discoveryFeed, followingFeed, suggestedProfiles, following, profile } |
89 | var player = context.player = Player(context) |
90 | |
91 | var rootElement = computed(currentView, (data) => { |
92 | if (Array.isArray(data) && views[data[0]]) { |
93 | return views[data[0]](context, ...data.slice(1)) |
94 | } |
95 | }) |
96 | |
97 | var mainElement = h('div.main', [ |
98 | rootElement |
99 | ]) |
100 | |
101 | onceTrue(api.profilesLoaded, (value) => { |
102 | // make sure we're connected to the pub that invited us |
103 | if (!profile.displayName()) { |
104 | // prompt use to set up profile the first time they open app |
105 | openEditProfileWindow() |
106 | } |
107 | }) |
108 | |
109 | electron.ipcRenderer.on('playPause', function () { |
110 | player.togglePlay() |
111 | }) |
112 | |
113 | electron.ipcRenderer.on('nextTrack', function () { |
114 | player.playNext() |
115 | }) |
116 | |
117 | electron.ipcRenderer.on('previousTrack', function () { |
118 | player.playPrevious() |
119 | }) |
120 | |
121 | return h('MainWindow', { |
122 | classList: [ '-' + process.platform ] |
123 | }, [ |
124 | h('div.top', [ |
125 | h('span.history', [ |
126 | h('a', { |
127 | 'ev-click': goBack, |
128 | classList: [ when(canGoBack, '-active') ] |
129 | }, '<'), |
130 | h('a', { |
131 | 'ev-click': goForward, |
132 | classList: [ when(canGoForward, '-active') ] |
133 | }, '>') |
134 | ]), |
135 | h('span.nav', [ |
136 | h('a', { |
137 | 'ev-click': send(actions.setView, 'discoveryFeed'), |
138 | classList: [ computed(currentView, (x) => x[0] === 'discoveryFeed' ? '-selected' : null) ] |
139 | }, 'Discovery'), |
140 | h('a', { |
141 | 'ev-click': send(actions.setView, 'followingFeed'), |
142 | classList: [ computed(currentView, (x) => x[0] === 'followingFeed' ? '-selected' : null) ] |
143 | }, 'Following') |
144 | ]), |
145 | h('span.appTitle', ['Ferment']), |
146 | h('span', [ |
147 | h('a', { |
148 | 'ev-click': send(actions.viewProfile, api.id), |
149 | title: 'Your Profile', |
150 | classList: [ computed(currentView, (x) => x[0] === 'profile' && x[1] === api.id ? '-selected' : null) ] |
151 | }, '๐'), |
152 | h('a -profile', {href: '#', 'ev-click': openEditProfileWindow}, ['Edit Profile']), |
153 | h('a -add', {href: '#', 'ev-click': openAddWindow}, ['+ Add Audio']) |
154 | ]) |
155 | ]), |
156 | when(latestUpdate, |
157 | h('div.info', [ |
158 | h('a.message -update', { href: 'https://github.com/mmckegg/ferment/releases' }, [ |
159 | h('strong', ['๐ Ferment ', latestUpdate, ' has been released.']), ' Click here for more info!' |
160 | ]) |
161 | ]) |
162 | ), |
163 | mainElement, |
164 | h('div.bottom', [ |
165 | player.audioElement |
166 | ]) |
167 | ]) |
168 | |
169 | // scoped |
170 | |
171 | function goBack () { |
172 | if (backHistory.length) { |
173 | canGoForward.set(true) |
174 | forwardHistory.push([currentView(), mainElement.scrollTop]) |
175 | var item = backHistory.pop() |
176 | currentView.set(item[0]) |
177 | setTimeout(() => { |
178 | mainElement.scrollTop = item[1] |
179 | }, 50) |
180 | canGoBack.set(backHistory.length > 0) |
181 | } |
182 | } |
183 | |
184 | function goForward () { |
185 | if (forwardHistory.length) { |
186 | backHistory.push([currentView(), mainElement.scrollTop]) |
187 | var item = forwardHistory.pop() |
188 | currentView.set(item[0]) |
189 | setTimeout(() => { |
190 | mainElement.scrollTop = item[1] |
191 | }, 50) |
192 | canGoForward.set(forwardHistory.length > 0) |
193 | canGoBack.set(true) |
194 | } |
195 | } |
196 | |
197 | function openEditProfileWindow () { |
198 | electron.ipcRenderer.send('open-edit-profile-window', { |
199 | profile: profile.byMe(), |
200 | id: api.id |
201 | }) |
202 | } |
203 | |
204 | function openJoinPubWindow () { |
205 | electron.ipcRenderer.send('open-join-pub-window') |
206 | } |
207 | } |
208 | |
209 | function editPost (opts) { |
210 | if (opts.id && opts.item.type === 'ferment/audio') { |
211 | electron.ipcRenderer.send('open-add-window', opts) |
212 | } |
213 | } |
214 | |
215 | function openAddWindow (opts) { |
216 | electron.ipcRenderer.send('open-add-window') |
217 | } |
218 | |
219 | function isSame (a, b) { |
220 | if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) { |
221 | for (var i = 0; i < a.length; i++) { |
222 | if (a[i] !== b[i]) { |
223 | return false |
224 | } |
225 | } |
226 | return true |
227 | } else if (a === b) { |
228 | return true |
229 | } |
230 | } |
231 |
Built with git-ssb-web