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

chore: some last.fm facet improvements

+49 -20
+5
src/components/supplement/last.fm/element.js
··· 42 42 43 43 #handle = signal(/** @type {string | null} */ (null)); 44 44 #sessionKey = signal(/** @type {string | null} */ (null)); 45 + #isAuthenticating = signal(false); 45 46 46 47 // STATE 47 48 48 49 handle = this.#handle.get; 49 50 isAuthenticated = computed(() => this.#sessionKey.value !== null); 51 + isAuthenticating = this.#isAuthenticating.get; 50 52 51 53 // LIFECYCLE 52 54 ··· 92 94 location.pathname + (newSearch ? "?" + newSearch : "") + location.hash, 93 95 ); 94 96 97 + this.#isAuthenticating.set(true); 95 98 try { 96 99 const session = await this.#getSession(urlToken); 97 100 this.#setSession(session); 98 101 } catch (err) { 99 102 console.warn("last.fm: failed to exchange token for session", err); 103 + } finally { 104 + this.#isAuthenticating.set(false); 100 105 } 101 106 102 107 return;
+1
src/components/supplement/types.d.ts
··· 4 4 5 5 export type ScrobbleElement = DiffuseElement & ScrobbleActions & { 6 6 isAuthenticated: SignalReader<boolean>; 7 + isAuthenticating: SignalReader<boolean>; 7 8 handle: SignalReader<string | null>; 8 9 }; 9 10
+35 -19
src/facets/scrobble/last.fm/index.html
··· 25 25 </wa-button> 26 26 </div> 27 27 </wa-card> 28 - </main> 29 28 30 - <wa-drawer id="credentials-drawer" label="API Credentials" placement="end"> 31 - <div class="drawer-body"> 32 - <wa-input id="api-key-input" label="API Key" placeholder="Default"></wa-input> 33 - <wa-input 34 - id="api-secret-input" 35 - label="API Secret" 36 - type="password" 37 - placeholder="Default" 38 - ></wa-input> 39 - </div> 40 - <div slot="footer" class="drawer-footer"> 41 - <wa-button id="save-creds-btn" variant="brand" appearance="filled">Save</wa-button> 42 - <wa-button id="reset-creds-btn" variant="neutral" appearance="outlined" 43 - >Reset to defaults</wa-button 44 - > 45 - </div> 46 - </wa-drawer> 29 + <wa-drawer id="credentials-drawer" label="API Credentials" placement="end"> 30 + <div class="drawer-body"> 31 + <wa-input id="api-key-input" label="API Key" placeholder="Default"></wa-input> 32 + <wa-input 33 + id="api-secret-input" 34 + label="API Secret" 35 + type="password" 36 + placeholder="Default" 37 + ></wa-input> 38 + </div> 39 + <div slot="footer" class="drawer-footer"> 40 + <wa-button id="save-creds-btn" variant="brand" appearance="filled">Save</wa-button> 41 + <wa-button id="reset-creds-btn" variant="neutral" appearance="outlined" 42 + >Reset to defaults</wa-button 43 + > 44 + </div> 45 + </wa-drawer> 46 + </main> 47 47 48 48 <style> 49 - body { 49 + #container { 50 50 display: flex; 51 51 align-items: center; 52 52 justify-content: center; 53 53 min-height: 100dvh; 54 54 margin: 0; 55 + } 56 + 57 + main { 58 + opacity: 0; 59 + pointer-events: none; 60 + transition: opacity 750ms; 61 + 62 + &.has-loaded { 63 + opacity: 1; 64 + pointer-events: auto; 65 + } 55 66 } 56 67 57 68 wa-card { ··· 91 102 </style> 92 103 93 104 <script type="module" src="./index.inline.js"></script> 105 + 106 + <script type="module"> 107 + await customElements.whenDefined("wa-button"); 108 + document.querySelector("main")?.classList.add("has-loaded"); 109 + </script>
+8 -1
src/facets/scrobble/last.fm/index.inline.js
··· 37 37 38 38 if (!lastFm) { 39 39 lastFm = new LastFmScrobbler(); 40 - lastFm.setAttribute("group", GROUP) 40 + lastFm.setAttribute("group", GROUP); 41 41 42 42 const creds = loadCredentials(); 43 43 if (creds) { ··· 57 57 const stateConnect = /** @type {HTMLElement} */ ( 58 58 document.querySelector("#state-connect") 59 59 ); 60 + 60 61 const stateConnected = /** @type {HTMLElement} */ ( 61 62 document.querySelector("#state-connected") 62 63 ); 64 + 63 65 const handleParagraph = /** @type {HTMLElement} */ ( 64 66 document.querySelector("#handle-paragraph") 65 67 ); 68 + 66 69 const handleText = /** @type {HTMLElement} */ ( 67 70 document.querySelector("#handle-text") 68 71 ); ··· 112 115 113 116 effect(() => { 114 117 const isAuthenticated = lastFm.isAuthenticated(); 118 + const isAuthenticating = lastFm.isAuthenticating(); 115 119 const handle = lastFm.handle(); 116 120 117 121 stateConnect.hidden = isAuthenticated; ··· 120 124 handleParagraph.hidden = !handle; 121 125 signOutBtn.hidden = !isAuthenticated; 122 126 if (handle) handleText.textContent = handle; 127 + 128 + // @ts-ignore 129 + signInBtn.disabled = isAuthenticating; 123 130 }); 124 131 125 132 ////////////////////////////////////////////