[READ-ONLY] Mirror of https://github.com/probablykasper/ferrum. Music library app for Mac, Linux and Windows ferrum.kasper.space
electron linux macos music music-library music-player napi windows
0

Configure Feed

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

Fix slider dragging

Kasper (Apr 12, 2023, 3:03 PM +0200) 0357f50b 5d5a1268

+66 -18
+3
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 + ## Next 4 + - Fix slider dragging 5 + 3 6 ## 0.16.9 - 2023 Apr 12 4 7 - Fix error loading library 5 8 - Fix errors causing crashes, show error messages instead
+1 -1
index.html
··· 6 6 7 7 <link href="./src/assets/fonts.css" rel="stylesheet" /> 8 8 </head> 9 - <body> 9 + <body tabindex="-1"> 10 10 <script defer type="module" src="./src/main.ts"></script> 11 11 </body> 12 12 </html>
+50 -16
src/components/Player.svelte
··· 56 56 } 57 57 </script> 58 58 59 - <!-- on:mousedown|preventDefault prevents focus --> 60 59 <!-- svelte-ignore a11y-no-noninteractive-tabindex --> 61 - <div class="player" class:stopped={$stopped} class:dev={isDev} on:mousedown|preventDefault> 60 + <div class="player" class:stopped={$stopped} class:dev={isDev}> 62 61 <div class="left"> 63 62 {#if !$stopped && $playingTrack} 64 63 <div ··· 92 91 <button 93 92 class="side-controls shuffle" 94 93 class:on={$shuffle} 94 + tabindex="-1" 95 + on:mousedown|preventDefault 95 96 on:click={() => ($shuffle = !$shuffle)} 96 97 > 97 98 <svg xmlns="http://www.w3.org/2000/svg" width="24" viewBox="-8 -8 40 40" height="24" ··· 100 101 /></svg 101 102 > 102 103 </button> 103 - <button on:click={previous}> 104 + <button on:click={previous} tabindex="-1" on:mousedown|preventDefault> 104 105 <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"> 105 106 <path 106 107 d="M7 6c.55 0 1 .45 1 1v10c0 .55-.45 1-1 1s-1-.45-1-1V7c0-.55.45-1 1-1zm3.66 6.82l5.77 4.07c.66.47 1.58-.01 1.58-.82V7.93c0-.81-.91-1.28-1.58-.82l-5.77 4.07c-.57.4-.57 1.24 0 1.64z" ··· 108 109 </svg> 109 110 </button> 110 111 111 - {#if $paused} 112 - <button class="play" on:click={playPause}> 112 + <button class="play-pause" on:click={playPause} tabindex="-1" on:mousedown|preventDefault> 113 + {#if $paused} 113 114 <svg xmlns="http://www.w3.org/2000/svg" height="36" viewBox="0 0 24 24" width="36"> 114 115 <path 115 116 d="M8 6.82v10.36c0 .79.87 1.27 1.54.84l8.14-5.18c.62-.39.62-1.29 0-1.69L9.54 5.98C8.87 5.55 8 6.03 8 6.82z" 116 117 /> 117 118 </svg> 118 - </button> 119 - {:else} 120 - <button class="pause" on:click={playPause}> 119 + {:else} 121 120 <svg xmlns="http://www.w3.org/2000/svg" height="36" viewBox="0 0 24 24" width="36"> 122 121 <path 123 122 d="M8 19c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2v10c0 1.1.9 2 2 2zm6-12v10c0 1.1.9 2 2 2s2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2z" 124 123 /> 125 124 </svg> 126 - </button> 127 - {/if} 125 + {/if} 126 + </button> 128 127 129 - <button on:click={skipToNext}> 128 + <button on:click={skipToNext} tabindex="-1" on:mousedown|preventDefault> 130 129 <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"> 131 130 <path 132 131 d="M7.58 16.89l5.77-4.07c.56-.4.56-1.24 0-1.63L7.58 7.11C6.91 6.65 6 7.12 6 7.93v8.14c0 .81.91 1.28 1.58.82zM16 7v10c0 .55.45 1 1 1s1-.45 1-1V7c0-.55-.45-1-1-1s-1 .45-1 1z" ··· 134 133 </svg> 135 134 </button> 136 135 137 - <button class="side-controls repeat" class:on={$repeat} on:click={() => ($repeat = !$repeat)}> 136 + <button 137 + class="side-controls repeat" 138 + class:on={$repeat} 139 + tabindex="-1" 140 + on:mousedown|preventDefault 141 + on:click={() => ($repeat = !$repeat)} 142 + > 138 143 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-8 -8 40 40" 139 144 ><path 140 145 d="M2 12c0 .999.381 1.902.989 2.604l-1.098.732-.587.392c-.814-1.025-1.304-2.318-1.304-3.728 0-3.313 2.687-6 6-6h9v-3l6 4-6 4v-3h-9c-2.206 0-4 1.794-4 4zm20.696-3.728l-.587.392-1.098.732c.608.702.989 1.605.989 2.604 0 2.206-1.795 4-4 4h-9v-3l-6 4 6 4v-3h9c3.313 0 6-2.687 6-6 0-1.41-.489-2.703-1.304-3.728z" ··· 146 151 <small class="current-time">{getDuration($currentTime)}</small> 147 152 <input 148 153 type="range" 154 + tabindex="-1" 149 155 class="time" 150 156 min="0" 151 157 max={sliderSteps} 152 158 bind:value={sliderValue} 159 + on:focus={(e) => { 160 + if (e.relatedTarget instanceof HTMLElement) { 161 + e.relatedTarget.focus() 162 + } else { 163 + e.currentTarget.blur() 164 + } 165 + }} 153 166 on:mousedown={sliderMousedown} 154 167 on:mouseup={sliderMouseup} 155 168 /> ··· 157 170 </div> 158 171 </div> 159 172 <div class="right"> 160 - <button class="volume-icon" on:click={volume.toggle}> 173 + <button class="volume-icon" tabindex="-1" on:click={volume.toggle}> 161 174 {#if $volume > 0.5} 162 175 <svg 163 176 class="high" ··· 199 212 </svg> 200 213 {/if} 201 214 </button> 202 - <input type="range" class="volume" min="0" max="1" step="0.01" bind:value={$volume} /> 203 - <button class="queue" tabindex="-1" on:click={toggleQueueVisibility} class:on={$queueVisible}> 215 + <input 216 + type="range" 217 + tabindex="-1" 218 + class="volume" 219 + min="0" 220 + max="1" 221 + step="0.01" 222 + bind:value={$volume} 223 + on:focus={(e) => { 224 + if (e.relatedTarget instanceof HTMLElement) { 225 + e.relatedTarget.focus() 226 + } else { 227 + e.currentTarget.blur() 228 + } 229 + }} 230 + /> 231 + <button 232 + class="queue" 233 + tabindex="-1" 234 + on:mousedown|preventDefault 235 + on:click={toggleQueueVisibility} 236 + class:on={$queueVisible} 237 + > 204 238 <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"> 205 239 <path 206 240 d="M5 10h10c.55 0 1 .45 1 1s-.45 1-1 1H5c-.55 0-1-.45-1-1s.45-1 1-1zm0-4h10c.55 0 1 .45 1 1s-.45 1-1 1H5c-.55 0-1-.45-1-1s.45-1 1-1zm0 8h6c.55 0 1 .45 1 1s-.45 1-1 1H5c-.55 0-1-.45-1-1s.45-1 1-1zm9 .88v4.23c0 .39.42.63.76.43l3.53-2.12c.32-.19.32-.66 0-.86l-3.53-2.12c-.34-.19-.76.05-.76.44z" ··· 282 316 opacity: 0.8 283 317 &.on svg 284 318 opacity: 0.9 285 - button.play, button.pause 319 + button.play-pause 286 320 margin: 0px 14px 287 321 .controls 288 322 display: flex
+1
src/components/Sidebar.svelte
··· 101 101 } 102 102 </script> 103 103 104 + <!-- NOTE: aside is used as css selector in --> 104 105 <aside on:mousedown|self|preventDefault> 105 106 {#if isMac} 106 107 <div class="titlebar-spacer" />
+1 -1
src/components/SidebarItems.svelte
··· 267 267 box-shadow: inset 2px 0px 0px 0px hsl(var(--hue), 30%, 60%) 268 268 background-image: linear-gradient(90deg, hsl(var(--hue), 20%, 25%) 30%, transparent 66.6666%) 269 269 background-position: 0% 0% 270 - :global(:focus) 270 + :global(aside :focus) 271 271 .active 272 272 box-shadow: inset 2px 0px 0px 0px hsl(var(--hue), 70%, 60%) 273 273 background-image: linear-gradient(90deg, hsl(var(--hue), 45%, 30%) 30%, transparent 66.6666%)
+1
src/components/TrackList.svelte
··· 284 284 itemHeight={24} 285 285 itemCount={$page.length} 286 286 bind:this={virtualList} 287 + isMain={-1} 287 288 on:keydown={keydown} 288 289 on:mousedown-self={selection.clear} 289 290 let:item={track}
+9
src/components/VirtualList.svelte
··· 5 5 6 6 type T = $$Generic 7 7 export let getItem: (index: number) => T 8 + export let isMain = 0 8 9 export let itemCount: number 9 10 export let itemHeight: number 10 11 let startIndex = -1 ··· 85 86 } 86 87 } 87 88 </script> 89 + 90 + <svelte:body 91 + on:keydown={(e) => { 92 + if (isMain) { 93 + keydown(e) 94 + } 95 + }} 96 + /> 88 97 89 98 <!-- svelte-ignore a11y-no-noninteractive-tabindex --> 90 99 <div