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.

Closes #209 - Remove Blockstack & Textile support

+19 -635
-2
.eslintrc.yaml
··· 11 11 sourceType: module 12 12 13 13 globals: 14 - blockstack: readonly 15 14 Elm: readonly 16 15 MediaMetadata: readonly 17 16 RemoteStorage: readonly 18 - Textile: readonly 19 17 tocca: readonly 20 18 21 19 rules:
+5
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 + ## 3.0.0 4 + 5 + - **Adds album-covers view** (switch to and from list view with icon in nav bar) 6 + - Removes support for Blockstack & Textile 7 + 3 8 ## 2.5.3 4 9 5 10 - Deprecate Blockstack & Textile
+8 -10
README.md
··· 12 12 13 13 ### Integrations 14 14 15 - User layer for user-data storage. 16 15 Music layer for music storage. 17 - 18 - #### User layer 19 - 20 - - [Blockstack](https://blockstack.org/) 21 - - [Dropbox](https://www.dropbox.com/) 22 - - [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) <small>(browser)</small> 23 - - [IPFS](https://ipfs.io/) 24 - - [RemoteStorage](https://remotestorage.io/) 25 - - [Textile](https://github.com/textileio/go-textile) 16 + User layer for user-data storage. 26 17 27 18 #### Music layer 28 19 ··· 33 24 - [Google Drive](https://drive.google.com/) 34 25 - [IPFS](https://ipfs.io/) 35 26 - [WebDAV](https://en.wikipedia.org/wiki/WebDAV) 27 + 28 + #### User layer 29 + 30 + - [Dropbox](https://www.dropbox.com/) 31 + - [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) <small>(Browser)</small> 32 + - [IPFS](https://ipfs.io/) <small>(using MFS)</small> 33 + - [RemoteStorage](https://remotestorage.io/) 36 34 37 35 38 36
-15
src/Applications/Brain.elm
··· 140 140 ----------------------------------------- 141 141 -- 📭 Other 142 142 ----------------------------------------- 143 - RedirectToBlockstackSignIn -> 144 - Other.redirectToBlockstackSignIn 145 - 146 143 SetCurrentTime a -> 147 144 Other.setCurrentTime a 148 145 ··· 191 188 Alien.AuthAnonymous -> 192 189 UserMsg (User.HypaethralDataRetrieved data) 193 190 194 - Alien.AuthBlockstack -> 195 - UserMsg (User.HypaethralDataRetrieved data) 196 - 197 191 Alien.AuthDropbox -> 198 192 UserMsg (User.HypaethralDataRetrieved data) 199 193 ··· 209 203 Alien.AuthRemoteStorage -> 210 204 UserMsg (User.HypaethralDataRetrieved data) 211 205 212 - Alien.AuthTextile -> 213 - UserMsg (User.HypaethralDataRetrieved data) 214 - 215 206 Alien.FabricateSecretKey -> 216 207 UserMsg User.SecretKeyFabricated 217 208 ··· 229 220 230 221 Alien.ProcessSources -> 231 222 ProcessingMsg (Processing.Process data) 232 - 233 - Alien.RedirectToBlockstackSignIn -> 234 - RedirectToBlockstackSignIn 235 223 236 224 Alien.RemoveEncryptionKey -> 237 225 UserMsg User.RemoveEncryptionKey ··· 299 287 300 288 Alien.AuthRemoteStorage -> 301 289 reportAuthError Alien.AuthRemoteStorage err "I found some encrypted data, but I couldn't decrypt it. Maybe you used the wrong passphrase?" 302 - 303 - Alien.AuthTextile -> 304 - reportAuthError Alien.AuthTextile err "Something went wrong regarding Textile. Maybe Textile isn't running?" 305 290 306 291 _ -> 307 292 case err of
-5
src/Applications/Brain/Other/State.elm
··· 14 14 -- 🔱 15 15 16 16 17 - redirectToBlockstackSignIn : Manager 18 - redirectToBlockstackSignIn = 19 - Return.communicate (Ports.redirectToBlockstackSignIn ()) 20 - 21 - 22 17 setCurrentTime : Time.Posix -> Manager 23 18 setCurrentTime time model = 24 19 Return.singleton { model | currentTime = time }
-21
src/Applications/Brain/Ports.elm
··· 46 46 -- 📣 ░░ USER LAYER SERVICES 47 47 48 48 49 - port deconstructBlockstack : () -> Cmd msg 50 - 51 - 52 49 port deconstructRemoteStorage : () -> Cmd msg 53 - 54 - 55 - port handlePendingBlockstackSignIn : String -> Cmd msg 56 50 57 51 58 52 port provideArtworkTrackUrls : Json.Value -> Cmd msg 59 53 60 54 61 - port redirectToBlockstackSignIn : () -> Cmd msg 62 - 63 - 64 - port requestBlockstack : Alien.Event -> Cmd msg 65 - 66 - 67 55 port requestDropbox : Alien.Event -> Cmd msg 68 56 69 57 ··· 76 64 port requestRemoteStorage : Alien.Event -> Cmd msg 77 65 78 66 79 - port requestTextile : Alien.Event -> Cmd msg 80 - 81 - 82 - port toBlockstack : Alien.Event -> Cmd msg 83 - 84 - 85 67 port toDropbox : Alien.Event -> Cmd msg 86 68 87 69 ··· 89 71 90 72 91 73 port toRemoteStorage : Alien.Event -> Cmd msg 92 - 93 - 94 - port toTextile : Alien.Event -> Cmd msg 95 74 96 75 97 76
-1
src/Applications/Brain/Types.elm
··· 63 63 ----------------------------------------- 64 64 -- 📭 Other 65 65 ----------------------------------------- 66 - | RedirectToBlockstackSignIn 67 66 | SetCurrentTime Time.Posix 68 67 | ToCache Json.Value 69 68
+5 -69
src/Applications/Brain/User/State.elm
··· 29 29 30 30 31 31 initialCommand : Url -> Cmd Brain.Msg 32 - initialCommand initialUrl = 33 - case Url.action initialUrl of 34 - [ "authenticate", "blockstack" ] -> 35 - case Url.extractQueryParam "authResponse" initialUrl of 36 - Just authResponse -> 37 - Cmd.batch 38 - [ do (UserMsg RetrieveEnclosedData) 39 - , Ports.handlePendingBlockstackSignIn authResponse 40 - ] 41 - 42 - Nothing -> 43 - Cmd.batch 44 - [ do (UserMsg RetrieveMethod) 45 - , do (UserMsg RetrieveEnclosedData) 46 - ] 47 - 48 - _ -> 49 - Cmd.batch 50 - [ do (UserMsg RetrieveMethod) 51 - , do (UserMsg RetrieveEnclosedData) 52 - ] 32 + initialCommand _ = 33 + Cmd.batch 34 + [ do (UserMsg RetrieveMethod) 35 + , do (UserMsg RetrieveEnclosedData) 36 + ] 53 37 54 38 55 39 ··· 207 191 208 192 -- 209 193 , case model.authMethod of 210 - Just Blockstack -> 211 - Ports.deconstructBlockstack () 212 - 213 194 Just (Dropbox _) -> 214 195 Cmd.none 215 196 ··· 221 202 222 203 Just (RemoteStorage _) -> 223 204 Ports.deconstructRemoteStorage () 224 - 225 - Just (Textile _) -> 226 - Cmd.none 227 205 228 206 Nothing -> 229 207 Cmd.none ··· 359 337 in 360 338 case model.authMethod of 361 339 -- 🚀 362 - Just Blockstack -> 363 - [ ( "file", file ) ] 364 - |> Json.object 365 - |> Alien.broadcast Alien.AuthBlockstack 366 - |> Ports.requestBlockstack 367 - |> return model 368 - 369 340 Just (Dropbox { token }) -> 370 341 [ ( "file", file ) 371 342 , ( "token", Json.string token ) ··· 401 372 |> Ports.requestRemoteStorage 402 373 |> return model 403 374 404 - Just (Textile { apiOrigin }) -> 405 - [ ( "apiOrigin", Json.string apiOrigin ) 406 - , ( "file", file ) 407 - ] 408 - |> Json.object 409 - |> Alien.broadcast Alien.AuthTextile 410 - |> Ports.requestTextile 411 - |> return model 412 - 413 375 -- ✋ 414 376 Nothing -> 415 377 Return.singleton model ··· 423 385 in 424 386 case model.authMethod of 425 387 -- 🚀 426 - Just Blockstack -> 427 - [ ( "file", file ) ] 428 - |> Json.object 429 - |> Alien.broadcast Alien.AuthBlockstack 430 - |> Ports.requestBlockstack 431 - |> return { model | legacyMode = True } 432 - 433 388 Just Local -> 434 389 Alien.AuthAnonymous 435 390 |> Alien.trigger ··· 466 421 in 467 422 case model.authMethod of 468 423 -- 🚀 469 - Just Blockstack -> 470 - [ ( "data", json ) 471 - , ( "file", file ) 472 - ] 473 - |> Json.object 474 - |> Alien.broadcast Alien.AuthBlockstack 475 - |> Ports.toBlockstack 476 - |> return model 477 - 478 424 Just (Dropbox { token }) -> 479 425 [ ( "data", json ) 480 426 , ( "file", file ) ··· 513 459 |> Json.object 514 460 |> Alien.broadcast Alien.AuthRemoteStorage 515 461 |> Ports.toRemoteStorage 516 - |> return model 517 - 518 - Just (Textile { apiOrigin }) -> 519 - [ ( "apiOrigin", Json.string apiOrigin ) 520 - , ( "data", json ) 521 - , ( "file", file ) 522 - ] 523 - |> Json.object 524 - |> Alien.broadcast Alien.AuthTextile 525 - |> Ports.toTextile 526 462 |> return model 527 463 528 464 -- ✋
-6
src/Applications/UI.elm
··· 643 643 Alien.AuthAnonymous -> 644 644 AuthenticationMsg (Authentication.BootFailure err) 645 645 646 - Alien.AuthBlockstack -> 647 - AuthenticationMsg (Authentication.BootFailure err) 648 - 649 646 Alien.AuthDropbox -> 650 647 AuthenticationMsg (Authentication.BootFailure err) 651 648 ··· 653 650 AuthenticationMsg (Authentication.BootFailure err) 654 651 655 652 Alien.AuthRemoteStorage -> 656 - AuthenticationMsg (Authentication.BootFailure err) 657 - 658 - Alien.AuthTextile -> 659 653 AuthenticationMsg (Authentication.BootFailure err) 660 654 661 655 Alien.StoreTracksInCache ->
-6
src/Applications/UI/Authentication/ContextMenu.elm
··· 21 21 , msg = AuthenticationMsg Authentication.PingIpfs 22 22 , active = False 23 23 } 24 - , Item 25 - { icon = \_ _ -> Svg.map never UI.Svg.Elements.textileLogo 26 - , label = "Textile (Experimental)" 27 - , msg = AuthenticationMsg Authentication.PingTextile 28 - , active = False 29 - } 30 24 ]
-85
src/Applications/UI/Authentication/State.elm
··· 191 191 ConfirmInput -> 192 192 confirmInput 193 193 194 - ----------------------------------------- 195 - -- Textile 196 - ----------------------------------------- 197 - PingTextile -> 198 - pingTextile 199 - 200 - PingTextileCallback a -> 201 - pingTextileCallback a 202 - 203 - PingOtherTextile a -> 204 - pingOtherTextile a 205 - 206 - PingOtherTextileCallback a b -> 207 - pingOtherTextileCallback a b 208 - 209 194 210 195 organize : Organizer Authentication.State -> Manager 211 196 organize = ··· 258 243 externalAuth : Method -> String -> Manager 259 244 externalAuth method string model = 260 245 case method of 261 - Blockstack -> 262 - Alien.RedirectToBlockstackSignIn 263 - |> Alien.trigger 264 - |> Ports.toBrain 265 - |> return model 266 - 267 246 Dropbox _ -> 268 247 [ ( "response_type", "token" ) 269 248 , ( "client_id", "te0c9pbeii8f8bw" ) ··· 627 606 InputScreen (RemoteStorage r) { value } -> 628 607 externalAuth (RemoteStorage r) value model 629 608 630 - InputScreen (Textile t) { value } -> 631 - pingOtherTextile (String.chopEnd "/" value) model 632 - 633 609 _ -> 634 610 Return.singleton model 635 - 636 - 637 - 638 - -- TEXTILE 639 - 640 - 641 - pingTextile : Manager 642 - pingTextile model = 643 - { url = "//localhost:40600/api/v0/summary" 644 - , expect = Http.expectWhatever (AuthenticationMsg << PingTextileCallback) 645 - } 646 - |> Http.get 647 - |> return model 648 - 649 - 650 - pingTextileCallback : Result Http.Error () -> Manager 651 - pingTextileCallback result = 652 - case result of 653 - Ok _ -> 654 - { apiOrigin = "//localhost:40600" } 655 - |> Textile 656 - |> signIn 657 - 658 - Err _ -> 659 - askForInput 660 - (Textile { apiOrigin = "" }) 661 - { placeholder = "//localhost:40600" 662 - , question = """ 663 - Where's your Textile API located?<br /> 664 - <span class="font-normal text-white-60"> 665 - You might need to do some CORS configuration.<br /> 666 - You can find the instructions for that 667 - <a href="about#CORS__Textile" target="_blank" class="border-b border-current-color font-semibold inline-block leading-tight">here</a>.<br /> 668 - You can't connect to a HTTP server while on HTTPS. 669 - </span> 670 - """ 671 - , value = "//localhost:40600" 672 - } 673 - 674 - 675 - pingOtherTextile : String -> Manager 676 - pingOtherTextile origin model = 677 - { url = origin ++ "/api/v0/summary" 678 - , expect = Http.expectWhatever (AuthenticationMsg << PingOtherTextileCallback origin) 679 - } 680 - |> Http.get 681 - |> return model 682 - 683 - 684 - pingOtherTextileCallback : String -> Result Http.Error () -> Manager 685 - pingOtherTextileCallback origin result = 686 - case result of 687 - Ok _ -> 688 - { apiOrigin = origin } 689 - |> Textile 690 - |> signIn 691 - 692 - Err _ -> 693 - "Can't reach this Textile API, maybe it's offline? Or I don't have access?" 694 - |> Notifications.error 695 - |> Common.showNotification 696 611 697 612 698 613
-7
src/Applications/UI/Authentication/Types.elm
··· 67 67 | AskForInput Method Question 68 68 | Input String 69 69 | ConfirmInput 70 - ----------------------------------------- 71 - -- Textile 72 - ----------------------------------------- 73 - | PingTextile 74 - | PingTextileCallback (Result Http.Error ()) 75 - | PingOtherTextile String 76 - | PingOtherTextileCallback String (Result Http.Error ())
-7
src/Applications/UI/Authentication/View.elm
··· 255 255 , outOfOrder = False 256 256 } 257 257 , choiceButton 258 - { action = TriggerExternalAuth Blockstack "" 259 - , icon = \_ _ -> Svg.map never UI.Svg.Elements.blockstackLogo 260 - , infoLink = Just "https://blockstack.org" 261 - , label = "Blockstack" 262 - , outOfOrder = False 263 - } 264 - , choiceButton 265 258 { action = TriggerExternalAuth (Dropbox { token = "" }) "" 266 259 , icon = \_ _ -> Svg.map never UI.Svg.Elements.dropboxLogo 267 260 , infoLink = Just "https://dropbox.com/"
-12
src/Applications/UI/Settings.elm
··· 97 97 , lineBreak 98 98 , text "You're storing the data for this application " 99 99 , case deps.authenticationMethod of 100 - Just Blockstack -> 101 - text "on Blockstack." 102 - 103 100 Just (Dropbox _) -> 104 101 text "on Dropbox." 105 102 ··· 111 108 112 109 Just (RemoteStorage _) -> 113 110 text "on a RemoteStorage server." 114 - 115 - Just (Textile _) -> 116 - text "on Textile." 117 111 118 112 Nothing -> 119 113 text "on nothing, wtf?" 120 114 121 115 -- Change passphrase (if applicable) 122 116 , case deps.authenticationMethod of 123 - Just Blockstack -> 124 - nothing 125 - 126 117 Just (Dropbox d) -> 127 118 changePassphrase (Dropbox d) 128 119 ··· 134 125 135 126 Just (RemoteStorage r) -> 136 127 changePassphrase (RemoteStorage r) 137 - 138 - Just (Textile _) -> 139 - nothing 140 128 141 129 Nothing -> 142 130 nothing
-3
src/Applications/UI/Settings/ImportExport.elm
··· 55 55 RequestImport 56 56 (text "Choose file") 57 57 , case userLayerMethod of 58 - Just Blockstack -> 59 - otherImportOptions 60 - 61 58 Just Local -> 62 59 otherImportOptions 63 60
-19
src/Applications/UI/User/State/Import.elm
··· 127 127 ) 128 128 |> andThen 129 129 (\m -> 130 - let 131 - notification = 132 - Notifications.stickyWarning 133 - """ 134 - Blockstack and Textile support will be removed in v3, please migrate to a different data-storage service (by exporting and then importing). v3 will add support for storing your data on [Fission](https://fission.codes). 135 - """ 136 - in 137 - case UI.Authentication.Common.extractMethod m.authentication of 138 - Just Blockstack -> 139 - Common.showNotificationWithModel m notification 140 - 141 - Just (Textile _) -> 142 - Common.showNotificationWithModel m notification 143 - 144 - _ -> 145 - Return.singleton m 146 - ) 147 - |> andThen 148 - (\m -> 149 130 if m.processAutomatically then 150 131 Sources.process m 151 132
-138
src/Javascript/Brain/user.js
··· 7 7 8 8 import * as crypto from "../crypto" 9 9 import { identity } from "../common" 10 - import Textile from "../textile" 11 10 12 11 import { SECRET_KEY_LOCATION, decryptIfNeeded, encryptWithSecretKey } from "./common" 13 12 import { fromCache, isLocalHost, removeCache, reportError } from "./common" ··· 31 30 }) 32 31 }) 33 32 .catch(reportError(app, event)) 34 - } 35 - 36 - 37 - 38 - // Blockstack 39 - // ---------- 40 - 41 - let bl 42 - 43 - 44 - function bl0ckst4ck() { 45 - if (!bl) { 46 - importScripts("vendor/blockstack.min.js") 47 - 48 - bl = new blockstack.UserSession({ 49 - appConfig: new blockstack.AppConfig({ 50 - appDomain: location.origin 51 - }), 52 - sessionStore: BLOCKSTACK_SESSION_STORE 53 - }) 54 - } 55 - 56 - return bl 57 - } 58 - 59 - 60 - const BLOCKSTACK_SESSION_STORE = { 61 - key: "AUTH_BLOCKSTACK_SESSION", 62 - getSessionData() { return fromCache(this.key).then(a => a || {}) }, 63 - setSessionData(data) { return toCache(this.key, data) }, 64 - deleteSessionData() { return removeCache(this.key) } 65 - } 66 - 67 - 68 - ports.deconstructBlockstack = _app => _ => { 69 - BLOCKSTACK_SESSION_STORE.deleteSessionData() 70 - bl = null 71 - } 72 - 73 - 74 - ports.handlePendingBlockstackSignIn = app => authResponse => { 75 - const session = bl0ckst4ck() 76 - 77 - session.handlePendingSignIn(authResponse).then(_ => { 78 - app.ports.fromAlien.send({ 79 - tag: "SIGN_IN", 80 - data: { method: "BLOCKSTACK", passphrase: null }, 81 - error: null 82 - }) 83 - 84 - }).catch( 85 - reportError({ tag: "AUTH_BLOCKSTACK" }) 86 - 87 - ) 88 - } 89 - 90 - 91 - ports.redirectToBlockstackSignIn = app => event => { 92 - const session = bl0ckst4ck() 93 - 94 - session.generateAndStoreTransitKey().then(transitKey => { 95 - const dir = location.pathname.replace("brain.js", "") 96 - 97 - return session.makeAuthRequest( 98 - transitKey, 99 - location.origin + dir + "?action=authenticate/blockstack", 100 - location.origin + dir + "manifest.json", 101 - [ "store_write" ] 102 - ) 103 - 104 - }).then(authRequest => { 105 - self.postMessage({ 106 - action: "REDIRECT_TO_BLOCKSTACK", 107 - data: authRequest 108 - }) 109 - 110 - }).catch( 111 - reportError(app, event) 112 - 113 - ) 114 - } 115 - 116 - 117 - ports.requestBlockstack = app => event => { 118 - const session = bl0ckst4ck() 119 - 120 - session 121 - .getFile(event.data.file) 122 - .then( sendJsonData(app, event) ) 123 - .catch( reportError(app, event) ) 124 - } 125 - 126 - 127 - ports.toBlockstack = app => event => { 128 - const json = JSON.stringify(event.data.data) 129 - const session = bl0ckst4ck() 130 - 131 - session 132 - .putFile(event.data.file, json) 133 - .then( storageCallback(app, event) ) 134 - .catch( reportError(app, event) ) 135 33 } 136 34 137 35 ··· 334 232 335 233 toCache(event.tag + "_" + event.data.file, event.data.data) 336 234 .then( isOffline ? storageCallback(app, event) : identity ) 337 - .catch( reportError(app, event) ) 338 - } 339 - 340 - 341 - 342 - // Textile 343 - // ------- 344 - 345 - 346 - ports.requestTextile = app => event => { 347 - const apiOrigin = event.data.apiOrigin 348 - 349 - Textile.ensureThread 350 - (apiOrigin) 351 - 352 - .then(_ => Textile.getFile(apiOrigin, event.data.file)) 353 - .then(f => f ? Textile.readFile(apiOrigin, f) : null) 354 - 355 - .then( sendJsonData(app, event) ) 356 - .catch( reportError(app, event) ) 357 - } 358 - 359 - 360 - ports.toTextile = app => event => { 361 - const apiOrigin = event.data.apiOrigin 362 - const json = JSON.stringify(event.data.data) 363 - 364 - Textile.ensureThread 365 - (apiOrigin) 366 - 367 - .then(_ => Textile.getFile(apiOrigin)) 368 - .then(f => f ? Textile.deleteBlock(apiOrigin, f) : null) 369 - .then(_ => Textile.useMill(apiOrigin, event.data.file, json)) 370 - .then(m => Textile.addFileToThread(apiOrigin, m)) 371 - 372 - .then( storageCallback(app, event) ) 373 235 .catch( reportError(app, event) ) 374 236 } 375 237
-18
src/Javascript/index.js
··· 61 61 62 62 function handleAction(action, data) { switch (action) { 63 63 case "DOWNLOAD_TRACKS": return downloadTracks(data) 64 - case "REDIRECT_TO_BLOCKSTACK": return redirectToBlockstack(data) 65 64 }} 66 65 67 66 ··· 137 136 app.ports.setRepeat.subscribe(repeat => { 138 137 orchestrion.repeat = repeat 139 138 }) 140 - 141 - 142 - 143 - // Authentication 144 - // -------------- 145 - 146 - function redirectToBlockstack(authRequest) { 147 - switch (location.hostname) { 148 - case "0.0.0.0": 149 - case "127.0.0.1": 150 - case "localhost": 151 - return window.location.href = `http://localhost:8888/auth?authRequest=${authRequest}` 152 - 153 - default: 154 - return window.location.href = `https://browser.blockstack.org/auth?authRequest=${authRequest}` 155 - } 156 - } 157 139 158 140 159 141
-164
src/Javascript/textile.js
··· 1 - // 2 - // Textile 3 - // \ (•◡•) / 4 - // 5 - // Communicating with the Textile HTTP API. 6 - 7 - 8 - const TEXTILE_THREAD = "Diffuse" 9 - const TEXTILE_SCHEMA = { 10 - name: TEXTILE_THREAD, 11 - pin: true, 12 - mill: "/blob", 13 - plaintext: false 14 - } 15 - 16 - 17 - const Textile = { 18 - activeThreadId: undefined 19 - } 20 - 21 - 22 - 23 - // Blocks 24 - // ------ 25 - 26 - Textile.deleteBlock = (apiOrigin, file) => { 27 - return fetch(apiOrigin + "/api/v0/blocks/" + file.block, { 28 - method: "DELETE" 29 - }) 30 - .then(r => r.json()) 31 - } 32 - 33 - 34 - 35 - // Threads 36 - // ------- 37 - 38 - Textile.ensureThread = (apiOrigin) => { 39 - if (!Textile.activeThreadId) { 40 - return Textile.getThread(apiOrigin) 41 - .then(thread => { 42 - if (thread) return thread 43 - 44 - return Textile 45 - .createSchema(apiOrigin) 46 - .then(schema => Textile.createThread(apiOrigin, schema)) 47 - }) 48 - .then(t => { 49 - Textile.activeThreadId = t.id 50 - return t.id 51 - }) 52 - } 53 - 54 - return Promise.resolve(Textile.activeThreadId) 55 - } 56 - 57 - 58 - Textile.getThread = (apiOrigin) => { 59 - return fetch(apiOrigin + "/api/v0/threads") 60 - .then(r => r.json()) 61 - .then(r => r.items.find(i => i.name === TEXTILE_THREAD)) 62 - } 63 - 64 - 65 - Textile.createThread = (apiOrigin, schema) => { 66 - const headers = new Headers() 67 - headers.append("X-Textile-Args", TEXTILE_THREAD) 68 - headers.append("X-Textile-Opts", "schema=" + schema.hash + ",type=private,sharing=invite_only") 69 - 70 - return fetch(apiOrigin + "/api/v0/threads", { 71 - headers: headers, 72 - method: "POST" 73 - }) 74 - .then(r => r.json()) 75 - } 76 - 77 - 78 - 79 - // Files 80 - // ----- 81 - 82 - Textile.addFileToThread = (apiOrigin, millResult) => { 83 - const headers = new Headers() 84 - headers.append("Content-Type", "application/json") 85 - 86 - const files = {} 87 - files[":single"] = millResult 88 - 89 - return fetch(apiOrigin + "/api/v0/threads/" + Textile.activeThreadId + "/files", { 90 - body: JSON.stringify({ 91 - items: [{ files: files }] 92 - }), 93 - headers: headers, 94 - method: "POST" 95 - }) 96 - .then(r => r.json()) 97 - } 98 - 99 - 100 - Textile.getFile = (apiOrigin, file_name) => { 101 - const headers = new Headers() 102 - headers.append("X-Textile-Opts", "thread=" + Textile.activeThreadId) 103 - 104 - return fetch(apiOrigin + "/api/v0/files", { 105 - headers: headers, 106 - method: "GET" 107 - }) 108 - .then(r => r.json()) 109 - .then(r => r.items.find(i => i.files[0].file.name === file_name)) 110 - } 111 - 112 - 113 - Textile.readFile = (apiOrigin, file) => { 114 - const headers = new Headers() 115 - headers.append("X-Textile-Opts", "key=" + file.files[0].file.key) 116 - 117 - return fetch(apiOrigin + "/api/v0/ipfs/cat/" + file.files[0].file.hash, { 118 - headers: headers, 119 - method: "GET" 120 - }) 121 - .then(r => r.text()) 122 - } 123 - 124 - 125 - 126 - // Mills 127 - // ----- 128 - 129 - Textile.createSchema = (apiOrigin) => { 130 - const headers = new Headers() 131 - headers.append("Content-Type", "application/json") 132 - 133 - return fetch(apiOrigin + "/api/v0/mills/schema", { 134 - body: JSON.stringify(TEXTILE_SCHEMA), 135 - headers: headers, 136 - method: "POST" 137 - }) 138 - .then(r => r.json()) 139 - } 140 - 141 - 142 - Textile.useMill = (apiOrigin, file_name, data) => { 143 - const blob = new Blob([data], { type : "application/json" }) 144 - const file = new File([blob], file_name) 145 - 146 - const formData = new FormData() 147 - formData.append("file", file) 148 - 149 - const headers = new Headers() 150 - headers.append("X-Textile-Opts", "plaintext=false") 151 - 152 - return fetch(apiOrigin + "/api/v0/mills/blob", { 153 - body: formData, 154 - method: "POST" 155 - }) 156 - .then(r => r.json()) 157 - } 158 - 159 - 160 - 161 - // Export 162 - // ------ 163 - 164 - export default Textile
-6
src/Library/Alien.elm
··· 25 25 26 26 type Tag 27 27 = AuthAnonymous 28 - | AuthBlockstack 29 28 | AuthDropbox 30 29 | AuthEnclosedData 31 30 | AuthIpfs 32 31 | AuthMethod 33 32 | AuthRemoteStorage 34 33 | AuthSecretKey 35 - | AuthTextile 36 34 | FabricateSecretKey 37 35 | SearchTracks 38 36 ----------------------------------------- ··· 41 39 | DownloadTracks 42 40 | ImportLegacyData 43 41 | ProcessSources 44 - | RedirectToBlockstackSignIn 45 42 | RemoveEncryptionKey 46 43 | RemoveTracksBySourceId 47 44 | RemoveTracksFromCache ··· 81 78 enum = 82 79 Enum.create 83 80 [ ( "AUTH_ANONYMOUS", AuthAnonymous ) 84 - , ( "AUTH_BLOCKSTACK", AuthBlockstack ) 85 81 , ( "AUTH_DROPBOX", AuthDropbox ) 86 82 , ( "AUTH_ENCLOSED_DATA", AuthEnclosedData ) 87 83 , ( "AUTH_IPFS", AuthIpfs ) 88 84 , ( "AUTH_METHOD", AuthMethod ) 89 85 , ( "AUTH_REMOTE_STORAGE", AuthRemoteStorage ) 90 86 , ( "AUTH_SECRET_KEY", AuthSecretKey ) 91 - , ( "AUTH_TEXTILE", AuthTextile ) 92 87 , ( "FABRICATE_SECRET_KEY", FabricateSecretKey ) 93 88 , ( "SEARCH_TRACKS", SearchTracks ) 94 89 ··· 98 93 , ( "DOWNLOAD_TRACKS", DownloadTracks ) 99 94 , ( "IMPORT_LEGACY_DATA", ImportLegacyData ) 100 95 , ( "PROCESS_SOURCES", ProcessSources ) 101 - , ( "REDIRECT_TO_BLOCKSTACK_SIGN_IN", RedirectToBlockstackSignIn ) 102 96 , ( "REMOVE_ENCRYPTION_KEY", RemoveEncryptionKey ) 103 97 , ( "REMOVE_TRACKS_BY_SOURCE_ID", RemoveTracksBySourceId ) 104 98 , ( "REMOVE_TRACKS_FROM_CACHE", RemoveTracksFromCache )
+1 -19
src/Library/User/Layer.elm
··· 37 37 38 38 39 39 type Method 40 - = Blockstack 41 - | Dropbox { token : String } 40 + = Dropbox { token : String } 42 41 | Ipfs { apiOrigin : String } 43 42 | Local 44 43 | RemoteStorage { userAddress : String, token : String } 45 - | Textile { apiOrigin : String } 46 44 47 45 48 46 ··· 105 103 methodFromString : String -> Maybe Method 106 104 methodFromString string = 107 105 case String.split methodSeparator string of 108 - [ "BLOCKSTACK" ] -> 109 - Just Blockstack 110 - 111 106 [ "DROPBOX", t ] -> 112 107 Just (Dropbox { token = t }) 113 108 ··· 119 114 120 115 [ "REMOTE_STORAGE", u, t ] -> 121 116 Just (RemoteStorage { userAddress = u, token = t }) 122 - 123 - [ "TEXTILE", a ] -> 124 - Just (Textile { apiOrigin = a }) 125 117 126 118 _ -> 127 119 Nothing ··· 130 122 methodToString : Method -> String 131 123 methodToString method = 132 124 case method of 133 - Blockstack -> 134 - "BLOCKSTACK" 135 - 136 125 Dropbox { token } -> 137 126 String.join 138 127 methodSeparator ··· 156 145 [ "REMOTE_STORAGE" 157 146 , userAddress 158 147 , token 159 - ] 160 - 161 - Textile { apiOrigin } -> 162 - String.join 163 - methodSeparator 164 - [ "TEXTILE" 165 - , apiOrigin 166 148 ] 167 149 168 150
-22
src/Static/About/About.md
··· 26 26 27 27 This layer will use a single service on which to store your data. Your data being your settings, favourites, playlists, etc. You can choose between these services: 28 28 29 - - [Blockstack](https://blockstack.org/) 30 29 - [Dropbox](https://www.dropbox.com/) 31 30 - [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) <small>(Browser)</small> 32 31 - [IPFS](https://ipfs.io/) <small>(using MFS)</small> 33 32 - [RemoteStorage](https://remotestorage.io/) 34 - - [Textile](https://github.com/textileio/go-textile) 35 33 36 34 37 35 ··· 158 156 ALLOWED HEADERS Range 159 157 EXPOSED HEADERS Content-Length, Content-Range 160 158 MAX AGE 0 161 - ``` 162 - 163 - <div id="CORS__Textile" /> 164 - 165 - #### Textile 166 - 167 - Add the domain of the app, with the protocol, to the __list of allowed origins__ in the configuration. 168 - 169 - ```json 170 - { 171 - "API": { 172 - "HTTPHeaders": { 173 - "Access-Control-Allow-Origin": [ 174 - "https://diffuse.sh", 175 - "http://127.0.0.1:8080", 176 - "http://127.0.0.1:44999" 177 - ] 178 - } 179 - } 180 - } 181 159 ``` 182 160 183 161 <div id="CORS__WebDAV" />