A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Split up playlists on WNFS

+81 -15
+77 -15
src/Javascript/Brain/user.js
··· 11 11 import { SECRET_KEY_LOCATION } from "./common" 12 12 import { decryptIfNeeded, encryptWithSecretKey } from "./common" 13 13 import { fromCache, isLocalHost, reportError } from "./common" 14 - import { sendJsonData, storageCallback, toCache } from "./common" 14 + import { sendData, sendJsonData, storageCallback, toCache } from "./common" 15 15 16 16 17 17 const ports = [] ··· 100 100 let wn 101 101 let wnfs 102 102 103 + const PLAYLISTS_PATH = "private/Audio/Music/Playlists/" 104 + 103 105 104 106 function fission() { 105 107 if (!wnfs) { ··· 150 152 ports.requestFission = app => event => { 151 153 fission() 152 154 .then(() => { 153 - return wnfs.exists(wnfs.appPath([ event.data.file ])) 155 + switch (event.data.file) { 156 + 157 + case "playlists.json": 158 + return wnfs.exists(PLAYLISTS_PATH) 159 + 160 + default: 161 + return wnfs.exists(wnfs.appPath([ event.data.file ])) 162 + 163 + } 154 164 }) 155 165 .then(exists => { 156 - if (exists) { 157 - return wnfs.read(wnfs.appPath([ event.data.file ])) 158 - } else { 159 - return null 166 + const sendJsonData_ = sendJsonData(app, event) 167 + if (!exists) return sendJsonData_(null) 168 + 169 + switch (event.data.file) { 170 + 171 + case "playlists.json": 172 + return wnfs.ls(PLAYLISTS_PATH).then(result => { 173 + return Object.values(result).map(r => { 174 + return wnfs 175 + .read(PLAYLISTS_PATH + r.name) 176 + .then(p => new TextDecoder().decode(p)) 177 + .then(j => JSON.parse(j)) 178 + }) 179 + }).then(promises => { 180 + return Promise.all(promises) 181 + }).then(playlists => { 182 + return sendData(app, event)(playlists) 183 + }) 184 + 185 + default: 186 + return wnfs 187 + .read(wnfs.appPath([ event.data.file ])) 188 + .then(a => a ? new TextDecoder().decode(a) : null) 189 + .then(sendJsonData_) 190 + 160 191 } 161 192 }) 162 - .then(a => a ? new TextDecoder().decode(a) : null) 163 - .then( sendJsonData(app, event) ) 164 193 .catch( reportError(app, event) ) 165 194 } 166 195 ··· 168 197 ports.toFission = app => event => { 169 198 fission() 170 199 .then(() => { 171 - return wnfs.write( 172 - wnfs.appPath([ event.data.file ]), 173 - new Blob( 174 - [ JSON.stringify(event.data.data) ], 175 - { type: "text/plain" } 176 - ) 177 - ) 200 + switch (event.data.file) { 201 + 202 + case "playlists.json": 203 + const playlistFilenames = event.data.data.map(playlist => 204 + `${playlist.name}.json` 205 + ) 206 + 207 + return wnfs.ls(PLAYLISTS_PATH).then(list => 208 + // delete playlists that are no longer in the catalog 209 + Object.values(list).map(l => l.name).filter(name => 210 + !playlistFilenames.includes(name) 211 + ) 212 + 213 + ).then(playlistsToRemove => 214 + Promise.all(playlistsToRemove.map(name => 215 + wnfs.rm(`${PLAYLISTS_PATH}/${name}`) 216 + )) 217 + 218 + ).then(() => 219 + // create/update playlists 220 + Promise.all(event.data.data.map(playlist => wnfs.write( 221 + `${PLAYLISTS_PATH}/${playlist.name}.json`, 222 + new Blob( 223 + [ JSON.stringify(playlist) ], 224 + { type: "text/plain" } 225 + ) 226 + ))) 227 + 228 + ) 229 + 230 + default: 231 + return wnfs.write( 232 + wnfs.appPath([ event.data.file ]), 233 + new Blob( 234 + [ JSON.stringify(event.data.data) ], 235 + { type: "text/plain" } 236 + ) 237 + ) 238 + 239 + } 178 240 }) 179 241 .then(() => wnfs.publish()) 180 242 .then( storageCallback(app, event) )
+4
src/Javascript/common.js
··· 7 7 app: { 8 8 name: "Diffuse", 9 9 creator: "icidasset" 10 + }, 11 + fs: { 12 + privatePaths: ["/Audio/Music/Playlists"], 13 + publicPaths: ["/Audio/Music/Playlists"] 10 14 } 11 15 } 12 16