[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 mousedown row selection

Kasper (May 27, 2025, 9:39 AM +0200) 80a6b765 6beb99eb

+60 -21
+60 -21
src/components/TrackList.svelte
··· 399 399 const grid = document.createElement('revo-grid') 400 400 grid.setAttribute('theme', 'darkCompact') 401 401 grid.readonly = true 402 - $: grid.columns = columns 403 402 grid.rowSize = 24 404 403 grid.style.lineHeight = '24px' 405 - const tracks = tracks_page.itemIds 404 + grid.canFocus = false 405 + grid.resize = false 406 + grid.canDrag = false 407 + grid.canMoveColumns = false 408 + grid.hideAttribution = true 409 + grid.rowClass = 'row_class' 410 + $: grid.columns = columns 411 + $: tracks_data = tracks_page.itemIds 406 412 .map((item_id, i) => { 407 413 const track = get_item(item_id).track 408 414 if (track === null) return null 409 415 return { 410 416 ...track, 417 + item_id, 411 418 duration: track.duration ? get_duration(track.duration) : '', 412 419 dateAdded: format_date(track.dateAdded), 413 - index: i + 1, 414 - odd: i % 2 === 0 ? 'odd' : null, 415 420 } 416 421 }) 417 422 .filter((track) => track !== null) 418 - grid.source = tracks 419 - grid.canFocus = false 420 - grid.resize = false 421 - grid.canDrag = false 422 - grid.canMoveColumns = false 423 - grid.hideAttribution = true 424 - grid.rowClass = 'odd' 423 + $: grid.source = tracks_data.map((track, i) => { 424 + let row_class = '' 425 + if (i % 2 === 0) { 426 + row_class += 'odd' 427 + } 428 + if ($selection.has(track.item_id)) { 429 + row_class += ' selected' 430 + } 431 + return { 432 + ...track, 433 + index: i + 1, 434 + row_class, 435 + } 436 + }) 425 437 426 438 // let col_container: HTMLElement 427 439 // let col_drag_line: HTMLElement ··· 462 474 // function col_drag_end_handler() { 463 475 // col_drag_to_index = null 464 476 // } 477 + 478 + function get_row(e: Event) { 479 + if (!(e.target instanceof Element)) { 480 + return null 481 + } 482 + const row = e.target?.closest('[data-rgrow]') 483 + const row_index_str = parseInt(row?.getAttribute('data-rgrow') ?? '') 484 + if (!Number.isInteger(row_index_str)) { 485 + return null 486 + } 487 + return { 488 + index: row_index_str, 489 + } 490 + } 465 491 </script> 466 492 467 493 <Header ··· 477 503 <!-- svelte-ignore a11y_no_static_element_interactions --> 478 504 <div 479 505 bind:this={container_el} 480 - class="grow" 506 + class="grid-container grow" 481 507 {@attach (element) => { 482 508 element.appendChild(grid) 483 509 }} 484 510 onkeydown={(e) => { 485 511 scroll_container_keydown(e) 486 512 }} 513 + onmousedown={(e) => { 514 + if (e.target instanceof HTMLElement && e.target.tagName === 'REVOGR-VIEWPORT-SCROLL') { 515 + selection.clear() 516 + return 517 + } 518 + const row = get_row(e) 519 + if (row) { 520 + selection.handle_mousedown(e, row.index) 521 + setTimeout(() => { 522 + // Prevent cell focus 523 + grid.focus() 524 + }) 525 + return 526 + } 527 + }} 487 528 ></div> 488 529 489 530 <!-- <div ··· 538 579 bind:this={scroll_container} 539 580 class="main-focus-element relative h-full overflow-y-auto outline-none" 540 581 tabindex="0" 541 - on:mousedown|self={() => selection.clear()} 542 582 on:keydown={keydown} 543 583 > 544 584 <VirtualListBlock ··· 557 597 class="row" 558 598 role="row" 559 599 on:dblclick={(e) => double_click(e, i)} 560 - on:mousedown={(e) => selection.handle_mousedown(e, i)} 561 600 on:contextmenu={(e) => selection.handle_contextmenu(e, i)} 562 601 on:click={(e) => selection.handle_click(e, i)} 563 602 draggable="true" ··· 565 604 on:dragover={(e) => on_drag_over(e, i)} 566 605 on:drop={drop_handler} 567 606 on:dragend={drag_end_handler} 568 - class:selected={$selection.has(item_id)} 569 607 class:playing={track_id === $playing_id} 570 608 > 571 609 {#each columns as column} ··· 606 644 </div> --> 607 645 608 646 <style lang="sass"> 609 - :global revo-grid[theme=darkCompact] 647 + .grid-container :global revo-grid 610 648 --revo-grid-focused-bg: hsla(var(--hue), 70%, 46%, 1) 649 + outline: none 611 650 revogr-data, revogr-header 612 651 .rgCell, .rgHeaderCell 613 652 padding: 0 5px ··· 626 665 box-shadow: none 627 666 .rgRow.odd 628 667 background-color: hsla(0, 0%, 90%, 0.06) 668 + .rgRow.selected 669 + background-color: hsla(var(--hue), 20%, 42%, 0.8) 629 670 revogr-header .header-rgRow 630 671 height: 24px 631 672 line-height: 24px ··· 634 675 font-weight: 400 635 676 revogr-header .rgHeaderCell .resizable 636 677 display: none 637 - // .selected 638 - // background-color: hsla(var(--hue), 20%, 42%, 0.8) 639 - // :global(:focus) 640 - // .selected 641 - // background-color: hsla(var(--hue), 70%, 46%, 1) 678 + .grid-container:focus-within :global revo-grid 679 + revogr-data .rgRow.selected 680 + background-color: hsla(var(--hue), 70%, 46%, 1) 642 681 // .tracklist 643 682 // display: flex 644 683 // flex-direction: column