[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 track dragline

Kasper (May 28, 2025, 7:03 AM +0200) f7fe7183 24e608d8

+41 -68
+3 -3
src/components/DragGhost.svelte
··· 1 1 <script lang="ts" context="module"> 2 2 export let drag_el: HTMLElement 3 - let text = '' 3 + export let div: HTMLElement 4 4 export function set_inner_text(new_text: string) { 5 - text = new_text 5 + div.innerText = new_text 6 6 } 7 7 </script> 8 8 9 9 <div class="drag-ghost" bind:this={drag_el}> 10 - <div>{text}</div> 10 + <div bind:this={div}></div> 11 11 </div> 12 12 13 13 <style lang="sass">
+38 -65
src/components/TrackList.svelte
··· 144 144 delete_tracks_with_item_ids(item_ids) 145 145 } 146 146 } 147 - function scroll_container_keydown(e: KeyboardEvent & { currentTarget: HTMLElement }) { 147 + function scroll_container_keydown(e: KeyboardEvent & { currentTarget: Element }) { 148 148 let prevent = true 149 149 const scroll_area = e.currentTarget.querySelector('.vertical-inner.scroll-rgRow') 150 150 if (!scroll_area) return ··· 271 271 // $: if (virtual_list) { 272 272 // virtual_list.refresh() 273 273 // } 274 + 275 + let grid: HTMLRevoGridElement 274 276 275 277 type ColumnDef = ColumnRegular & 276 278 ( ··· 391 393 'dateAdded', 392 394 'year', 393 395 ] 394 - let container_el: HTMLElement 395 396 let columns: ColumnRegular[] = load_columns() 396 397 onMount(() => (columns = load_columns())) 397 398 function load_columns(): ColumnRegular[] { ··· 404 405 .filter((col) => col !== undefined) 405 406 const total_fixed_width = columns.reduce((sum, col) => sum + (col.width_px || 0), 0) 406 407 const total_percent_pct = columns.reduce((sum, col) => sum + (col.width_pct || 0), 0) 407 - const container_width = container_el?.clientWidth ?? total_fixed_width 408 + const container_width = grid?.clientWidth ?? total_fixed_width 408 409 const total_percent_width = container_width - total_fixed_width 409 410 return columns.map((col) => { 410 411 let size: number ··· 470 471 }), 471 472 ) 472 473 473 - const grid = document.createElement('revo-grid') 474 - grid.setAttribute('theme', 'darkCompact') 475 - grid.readonly = true 476 - grid.rowSize = item_height 477 - grid.style.lineHeight = 'item_height' + 'px' 478 - grid.canFocus = false 479 - grid.resize = false 480 - grid.canDrag = false 481 - grid.canMoveColumns = false 482 - grid.hideAttribution = true 483 - grid.rowClass = 'row_class' 484 - $: grid.columns = columns 474 + $: if (grid) grid.columns = columns 485 475 $: source_rows = to_source_rows(tracks_page.itemIds) 486 - $: grid.source = source_rows 476 + $: if (grid) grid.source = source_rows 487 477 488 478 /** This is a function because we need it to be non-reactive */ 489 479 function to_source_rows(item_ids: ItemId[]) { ··· 537 527 } 538 528 }) 539 529 540 - $: $selection, apply_selection() 530 + $: if (grid && $selection) apply_selection() 541 531 function apply_selection() { 542 532 const rows = grid.querySelectorAll('.rgRow') 543 533 for (const row of rows) { ··· 550 540 } 551 541 } 552 542 553 - $: $playing_id, apply_playing() 543 + $: if (grid && $playing_id) apply_playing() 554 544 function apply_playing() { 555 545 const rows = grid.querySelectorAll('.rgRow') 556 546 for (const row of rows) { ··· 639 629 columns = load_columns() 640 630 }} 641 631 /> 642 - <div class="relative"> 643 - <div class="drag-line" class:hidden={drag_to_index === null} bind:this={drag_line}></div> 644 - </div> 645 632 <!-- svelte-ignore a11y_no_static_element_interactions --> 646 - <div 647 - bind:this={container_el} 648 - class="grid-container grow" 649 - {@attach (element) => { 650 - element.appendChild(grid) 633 + <revo-grid 634 + bind:this={grid} 635 + class="grid grow" 636 + {@attach (grid: HTMLRevoGridElement) => { 637 + grid.setAttribute('theme', 'darkCompact') 638 + grid.readonly = true 639 + grid.rowSize = item_height 640 + grid.style.lineHeight = 'item_height' + 'px' 641 + grid.canFocus = false 642 + grid.resize = false 643 + grid.canDrag = false 644 + grid.canMoveColumns = false 645 + grid.hideAttribution = true 646 + grid.rowClass = 'row_class' 651 647 }} 652 - onkeydown={(e) => { 648 + onkeydown={(e: KeyboardEvent & { currentTarget: Element }) => { 653 649 scroll_container_keydown(e) 654 650 keydown(e) 655 651 }} 656 - onmousedown={(e) => { 652 + onmousedown={(e: MouseEvent) => { 657 653 if (e.target instanceof HTMLElement && e.target.tagName === 'REVOGR-VIEWPORT-SCROLL') { 658 654 selection.clear() 659 655 return ··· 668 664 return 669 665 } 670 666 }} 671 - onclick={(e) => { 667 + onclick={(e: MouseEvent) => { 672 668 const row = get_row(e) 673 669 if (row) { 674 670 selection.handle_click(e, row.index) 675 671 } 676 672 }} 677 - ondblclick={(e) => { 673 + ondblclick={(e: MouseEvent) => { 678 674 const row = get_row(e) 679 675 if (row) { 680 676 double_click(e, row.index) 681 677 } 682 678 }} 683 - oncontextmenu={(e) => { 679 + oncontextmenu={(e: MouseEvent) => { 684 680 const row = get_row(e) 685 681 if (row) { 686 682 selection.handle_contextmenu(e, row.index) 687 683 } 688 684 }} 689 685 ondragstart={on_drag_start} 690 - ondragover={(e) => { 686 + ondragover={(e: DragEvent) => { 691 687 const row = get_row(e) 692 688 if (row) { 693 689 on_drag_over(e, row.element, row.index) ··· 695 691 }} 696 692 ondrop={drop_handler} 697 693 ondragend={drag_end_handler} 698 - ></div> 694 + > 695 + <div class="relative" slot="data-rgCol-rgRow"> 696 + <div class="drag-line" class:hidden={drag_to_index === null} bind:this={drag_line}></div> 697 + </div> 698 + </revo-grid> 699 699 700 700 <!-- <div 701 701 bind:this={tracklist_element} ··· 750 750 class="main-focus-element relative h-full overflow-y-auto outline-none" 751 751 tabindex="0" 752 752 > 753 - <VirtualListBlock 754 - bind:this={virtual_list} 755 - items={tracks_page.itemIds} 756 - get_key={(item) => item} 757 - item_height={24} 758 - {scroll_container} 759 - let:item={item_id} 760 - let:i 761 - buffer={5} 762 - > 763 - {@const { id: track_id, track } = get_item(item_id)} 764 - {#if track !== null} 765 - <div 766 - class="row" 767 - role="row" 768 - draggable="true" 769 - on:dragstart={on_drag_start} 770 - on:dragover={(e) => on_drag_over(e, i)} 771 - on:drop={drop_handler} 772 - on:dragend={drag_end_handler} 773 - > 774 - {/each} 775 - </div> 776 - {/if} 777 - </VirtualListBlock> 778 - <div class="drag-line" class:hidden={drag_to_index === null} bind:this={drag_line}></div> 779 753 </div> 780 754 </div> --> 781 755 782 756 <style lang="sass"> 783 - .grid-container :global 784 - revo-grid 785 - outline: none 757 + .grid :global 758 + outline: none 759 + min-height: 50px 786 760 .header-rgRow 787 761 height: 24px 788 762 line-height: 24px ··· 846 820 .playing.selected > .index 847 821 // #ffffff 848 822 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z'/%3E%3C/svg%3E") 849 - .grid-container:focus-within :global 823 + .grid:focus-within :global 850 824 .rgRow.selected 851 825 background-color: hsla(var(--hue), 70%, 46%, 1) 852 - 853 826 854 827 // .tracklist 855 828 // display: flex ··· 893 866 // .dateAdded 894 867 // font-variant-numeric: tabular-nums 895 868 .drag-line 896 - margin-top: 24px 897 869 position: absolute 898 870 width: 100% 899 871 height: 2px 900 872 background-color: var(--drag-line-color) 901 873 pointer-events: none 874 + z-index: 5 902 875 // .col-drag-line 903 876 // position: absolute 904 877 // width: 2px