[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.

Add epilepsy warning

Kasper (Oct 3, 2025, 1:14 AM +0200) 88d3ca24 c1aafe52

+68 -13
+2 -7
src/App.svelte
··· 120 120 let el = e.target as HTMLAudioElement 121 121 const space_tags = ['INPUT', 'TEXTAREA', 'BUTTON', 'SELECT'] 122 122 if (el && !space_tags.includes(el.tagName) && $modal_count === 0) { 123 - if (e.key === ' ') { 123 + const prevent_el = el.closest('[data-prevent-space-play]') 124 + if (!prevent_el && e.key === ' ') { 124 125 e.preventDefault() 125 126 play_pause() 126 127 } ··· 355 356 color: var(--text-color) 356 357 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif 357 358 user-select: none 358 - :global(h1), :global(h2), :global(h3) 359 - font-weight: 400 360 - margin: 0px 361 - :global(h4), :global(h5), :global(h6) 362 - font-weight: 600 363 - margin: 0px 364 359 .dropzone, .drag-overlay 365 360 position: fixed 366 361 width: 100%
+13
src/app.css
··· 27 27 a { 28 28 cursor: default; 29 29 } 30 + 31 + h1, 32 + h2, 33 + h3 { 34 + font-weight: 400; 35 + margin: 0px; 36 + } 37 + h4, 38 + h5, 39 + h6 { 40 + font-weight: 600; 41 + margin: 0px; 42 + } 30 43 } 31 44 32 45 @layer utilities {
+3 -3
src/components/Button.svelte
··· 65 65 &:hover::before 66 66 background-color: hsl(220, 100%, 52%) 67 67 transform: scale(1.04, 1) 68 - &:focus::before 68 + &:focus-visible::before 69 69 box-shadow: 0px 0px 0px 3px hsla(220, 100%, 50%, 0.5) 70 70 button.secondary 71 71 &::before ··· 74 74 &:hover::before 75 75 background-color: hsl(220, 20%, 31%) 76 76 transform: scale(1.04, 1) 77 - &:focus::before 77 + &:focus-visible::before 78 78 border-color: hsla(220, 30%, 50%, 1) 79 79 box-shadow: 0px 0px 0px 3px hsla(220, 30%, 50%, 0.5) 80 80 button.danger ··· 84 84 &:hover::before 85 85 background-color: hsl(0, 100%, 45%) 86 86 transform: scale(1.04, 1) 87 - &:focus::before 87 + &:focus-visible::before 88 88 border-color: hsla(0, 100%, 70%, 1) 89 89 box-shadow: 0px 0px 0px 3px hsla(0, 100%, 47%, 0.5) 90 90 </style>
+50 -3
src/lib/visualizer/Visualizer.svelte
··· 4 4 import { onDestroy } from 'svelte' 5 5 import { audio_context, media_element_source } from '$lib/player' 6 6 import Player from '$components/Player.svelte' 7 - import { fly } from 'svelte/transition' 8 - import { check_modifiers } from '$lib/helpers' 7 + import { fade, fly } from 'svelte/transition' 8 + import { check_modifiers, check_shortcut } from '$lib/helpers' 9 9 import { error_popup } from '$lib/error' 10 + import Button from '$components/Button.svelte' 10 11 11 12 let { on_close }: { on_close: () => void } = $props() 13 + 14 + let vis_epilepsy_warning_dismissed = $state( 15 + localStorage.getItem('vis_epilepsy_warning_dismissed') === 'true', 16 + ) 17 + function dismiss_vis_epilepsy_warning() { 18 + vis_epilepsy_warning_dismissed = true 19 + localStorage.setItem('vis_epilepsy_warning_dismissed', 'true') 20 + } 12 21 13 22 const shaders = [ 14 23 { ··· 459 468 }} 460 469 ></canvas> 461 470 {/each} 471 + {#if !vis_epilepsy_warning_dismissed} 472 + <!-- svelte-ignore a11y_click_events_have_key_events --> 473 + <!-- svelte-ignore a11y_no_static_element_interactions --> 474 + <div 475 + class="fixed inset-0 z-10 flex flex-col items-center justify-center gap-4 bg-black text-center text-lg text-white" 476 + onmousemove={show_player_temporarily} 477 + out:fade={{ duration: 200 }} 478 + > 479 + <h1 class="text-3xl font-medium">⚠️ Epilepsy Warning ⚠️</h1> 480 + <!-- tabindex+outline-none to prevent button autofocus --> 481 + <div 482 + class="flex outline-none" 483 + tabindex="-1" 484 + data-prevent-space-play 485 + onkeydown={(e) => { 486 + if (check_shortcut(e, ' ')) { 487 + e.preventDefault() 488 + on_close() 489 + } else if (check_shortcut(e, 'Enter')) { 490 + e.stopPropagation() // prevent player from revealing 491 + dismiss_vis_epilepsy_warning() 492 + } 493 + }} 494 + > 495 + <Button 496 + secondary 497 + onclick={() => { 498 + on_close() 499 + }}>Go back</Button 500 + > 501 + <Button 502 + onclick={() => { 503 + dismiss_vis_epilepsy_warning() 504 + }}>Continue</Button 505 + > 506 + </div> 507 + </div> 508 + {/if} 462 509 {#if show_player} 463 510 <!-- svelte-ignore a11y_no_static_element_interactions --> 464 511 <div 465 - class="fixed bottom-0 z-10 flex w-full flex-col justify-end" 512 + class="fixed bottom-0 z-20 flex w-full flex-col justify-end" 466 513 transition:fly={{ y: '100%', duration: 500 }} 467 514 onmouseenter={() => { 468 515 show_player = true