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.

fix: #434

+17 -20
+1 -1
src/Javascript/UI/audio.ts
··· 387 387 // Audio node 388 388 const audio = new Audio() 389 389 audio.setAttribute("id", item.trackId) 390 - audio.setAttribute("crossorigin", "anonymous") 390 + audio.setAttribute("crossorigin", "use-credentials") 391 391 audio.setAttribute("data-initial-progress", JSON.stringify(item.progress)) 392 392 audio.setAttribute("data-is-preload", item.isPreload ? "true" : "false") 393 393 audio.setAttribute("muted", "true")
+1 -1
src/Javascript/UI/service-worker.ts
··· 35 35 36 36 if (serverIsOnline) return navigator.serviceWorker.register( 37 37 "service-worker.js", 38 - { type: "module" } 38 + // { type: "module" } 39 39 ) 40 40 41 41 if (registrations[0]) return registrations
+10 -13
src/Javascript/Workers/service.ts
··· 11 11 12 12 13 13 const KEY = 14 - /* eslint-disable no-undef */ 14 + /* eslint-disable no-undef *//* @ts-ignore */ 15 15 `diffuse-${BUILD_TIMESTAMP}` 16 16 17 17 ··· 56 56 const promise = fetch("tree.json") 57 57 .then(response => response.json()) 58 58 .then(tree => { 59 - const filteredTree = tree.filter(t => !EXCLUDE.find(u => u === t)) 59 + const filteredTree = tree 60 + .filter(t => !EXCLUDE.find(u => u === t)) 61 + .filter(u => u.endsWith(".jpg")) 60 62 const whatToCache = [ href, `${href.replace(/\/+$/, "")}/about/` ].concat(filteredTree) 61 63 return caches.open(KEY).then(c => Promise.all(whatToCache.map(x => c.add(x)))) 62 64 }) ··· 81 83 ) 82 84 83 85 // When doing a request with basic authentication in the url, put it in the headers instead 84 - } else if (event.request.url.includes("service_worker_authentication=")) { 86 + } else if (event.request.url.includes("basic_auth=")) { 85 87 const url = new URL(event.request.url) 86 - const token = url.searchParams.get("service_worker_authentication") 88 + const token = url.searchParams.get("basic_auth") 87 89 88 - url.searchParams.delete("service_worker_authentication") 90 + url.searchParams.delete("basic_auth") 89 91 url.search = "?" + url.searchParams.toString() 90 92 91 93 newRequestWithAuth( ··· 161 163 // ⚗️ 162 164 163 165 164 - function newRequestWithAuth(event, urlWithoutToken, authToken) { 166 + function newRequestWithAuth(event: FetchEvent, urlWithoutToken: string, authToken: string) { 165 167 const request = event.request 166 - const newHeaders = Object.fromEntries( 167 - request.headers.entries() 168 - ) 169 - 170 - newHeaders[ "authorization" ] = authToken 168 + const newHeaders = new Headers(event.request.headers) 169 + newHeaders.append("authorization", authToken) 171 170 172 171 const newRequest = new Request( 173 172 new Request(urlWithoutToken, event.request), ··· 182 181 } 183 182 ) 184 183 185 - // TODO: When request fails because access token is expired, 186 - // refresh the token, and retry the request. 187 184 const makeFetch = () => fetch(newRequest).then(r => { 188 185 if (r.ok) { 189 186 return r
+1 -1
src/Library/Sources/Services/WebDav.elm
··· 199 199 200 200 authBit = 201 201 if addAuth && String.length authPrefix > 0 then 202 - "?service_worker_authentication=" ++ Url.percentEncode (Base64.encode authPrefix) 202 + "?basic_auth=" ++ Url.percentEncode (Base64.encode authPrefix) 203 203 204 204 else 205 205 ""
+4 -4
src/Static/About/CORS.md
··· 21 21 [ 22 22 { 23 23 "AllowedHeaders": [ 24 - "Range" 24 + "Range", 25 + "X-Playback-Session-Id" 25 26 ], 26 27 "AllowedMethods": [ 27 28 "GET", ··· 118 119 ``` 119 120 ALLOWED ORIGINS * 120 121 ALLOWED METHODS GET, HEAD 121 - ALLOWED HEADERS Range 122 + ALLOWED HEADERS Range, X-Playback-Session-Id 122 123 EXPOSED HEADERS Accept-Ranges, Content-Length, Content-Range 123 124 MAX AGE 0 124 125 ``` ··· 137 138 138 139 allowed_headers: 139 140 - Authorization 140 - - Content-Type 141 141 - Depth 142 - - Range 142 + - X-Playback-Session-Id 143 143 allowed_methods: 144 144 - GET 145 145 - HEAD