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

Kasper (May 28, 2025, 6:25 AM +0200) 24e608d8 31b072bc

+84 -67
+84 -67
src/components/TrackList.svelte
··· 195 195 new_playback_instance(all_track_ids, index) 196 196 } 197 197 198 - // let drag_line: HTMLElement 199 - // let drag_item_ids: ItemId[] = [] 200 - // function on_drag_start(e: DragEvent) { 201 - // if (e.dataTransfer) { 202 - // drag_item_ids = Array.from(selection.items) 203 - // e.dataTransfer.effectAllowed = 'move' 204 - // if (drag_item_ids.length === 1) { 205 - // const { track } = get_track_by_item_id(drag_item_ids[0]) 206 - // dragGhost.set_inner_text(track.artist + ' - ' + track.name) 207 - // } else { 208 - // dragGhost.set_inner_text(drag_item_ids.length + ' items') 209 - // } 210 - // dragged.tracks = { 211 - // ids: get_track_ids(drag_item_ids), 212 - // playlist_indexes: drag_item_ids, 213 - // } 214 - // e.dataTransfer.setDragImage(dragGhost.drag_el, 0, 0) 215 - // e.dataTransfer.setData('ferrum.tracks', '') 216 - // } 217 - // } 218 - // let drag_to_index: null | number = null 219 - // function on_drag_over(e: DragEvent, index: number) { 220 - // if ( 221 - // !$sort_desc || 222 - // $sort_key !== 'index' || 223 - // $filter || 224 - // tracks_page.playlistKind !== 'playlist' 225 - // ) { 226 - // drag_to_index = null 227 - // return 228 - // } 229 - // if ( 230 - // dragged.tracks?.playlist_indexes && 231 - // e.currentTarget instanceof HTMLElement && 232 - // e.dataTransfer?.types[0] === 'ferrum.tracks' 233 - // ) { 234 - // e.preventDefault() 235 - // const rect = e.currentTarget.getBoundingClientRect() 236 - // const container_rect = scroll_container.getBoundingClientRect() 237 - // if (e.pageY < rect.bottom - rect.height / 2) { 238 - // const top = rect.top - container_rect.top + scroll_container.scrollTop - 1 239 - // drag_line.style.top = Math.max(0, top) + 'px' 240 - // drag_to_index = index 241 - // } else { 242 - // const top = rect.bottom - container_rect.top + scroll_container.scrollTop - 1 243 - // const max_top = scroll_container.scrollHeight - 2 244 - // drag_line.style.top = Math.min(max_top, top) + 'px' 245 - // drag_to_index = index + 1 246 - // } 247 - // } 248 - // } 249 - // async function drop_handler() { 250 - // if (drag_to_index !== null) { 251 - // move_tracks(params.playlist_id, drag_item_ids, drag_to_index) 252 - // drag_to_index = null 253 - // } 254 - // } 255 - // function drag_end_handler() { 256 - // drag_to_index = null 257 - // } 198 + let drag_line: HTMLElement 199 + let drag_item_ids: ItemId[] = [] 200 + function on_drag_start(e: DragEvent) { 201 + if (e.dataTransfer) { 202 + drag_item_ids = Array.from(selection.items) 203 + e.dataTransfer.effectAllowed = 'move' 204 + if (drag_item_ids.length === 1) { 205 + const { track } = get_track_by_item_id(drag_item_ids[0]) 206 + dragGhost.set_inner_text(track.artist + ' - ' + track.name) 207 + } else { 208 + dragGhost.set_inner_text(drag_item_ids.length + ' items') 209 + } 210 + dragged.tracks = { 211 + ids: get_track_ids(drag_item_ids), 212 + playlist_indexes: drag_item_ids, 213 + } 214 + e.dataTransfer.setDragImage(dragGhost.drag_el, 0, 0) 215 + e.dataTransfer.setData('ferrum.tracks', '') 216 + } 217 + } 218 + let drag_to_index: null | number = null 219 + function on_drag_over(e: DragEvent, element: Element, index: number) { 220 + if ( 221 + !$sort_desc || 222 + $sort_key !== 'index' || 223 + $filter || 224 + tracks_page.playlistKind !== 'playlist' 225 + ) { 226 + drag_to_index = null 227 + return 228 + } 229 + const scroll_container = grid.querySelector('.vertical-inner.scroll-rgRow') 230 + if ( 231 + dragged.tracks?.playlist_indexes && 232 + e.currentTarget instanceof HTMLElement && 233 + e.dataTransfer?.types[0] === 'ferrum.tracks' && 234 + scroll_container 235 + ) { 236 + e.preventDefault() 237 + const rect = element.getBoundingClientRect() 238 + const container_rect = scroll_container.getBoundingClientRect() 239 + if (e.pageY < rect.bottom - rect.height / 2) { 240 + const top = rect.top - container_rect.top + scroll_container.scrollTop - 1 241 + drag_line.style.top = Math.max(0, top) + 'px' 242 + drag_to_index = index 243 + } else { 244 + const top = rect.bottom - container_rect.top + scroll_container.scrollTop - 1 245 + const max_top = scroll_container.scrollHeight - 2 246 + drag_line.style.top = Math.min(max_top, top) + 'px' 247 + drag_to_index = index + 1 248 + } 249 + } 250 + } 251 + async function drop_handler() { 252 + if (drag_to_index !== null) { 253 + move_tracks(params.playlist_id, drag_item_ids, drag_to_index) 254 + drag_to_index = null 255 + } 256 + } 257 + function drag_end_handler() { 258 + drag_to_index = null 259 + } 258 260 259 261 function get_item(item_id: ItemId) { 260 262 try { ··· 427 429 classes[col.prop] = true 428 430 return { 429 431 class: classes, 432 + draggable: true, 430 433 } 431 434 }, 432 435 } ··· 616 619 } 617 620 const row = e.target?.closest('[data-rgrow]') 618 621 const row_index_str = parseInt(row?.getAttribute('data-rgrow') ?? '') 619 - if (!Number.isInteger(row_index_str)) { 622 + if (!row || !Number.isInteger(row_index_str)) { 620 623 return null 621 624 } 622 625 return { 623 626 index: row_index_str, 627 + element: row, 624 628 } 625 629 } 626 630 </script> ··· 635 639 columns = load_columns() 636 640 }} 637 641 /> 642 + <div class="relative"> 643 + <div class="drag-line" class:hidden={drag_to_index === null} bind:this={drag_line}></div> 644 + </div> 638 645 <!-- svelte-ignore a11y_no_static_element_interactions --> 639 646 <div 640 647 bind:this={container_el} ··· 679 686 selection.handle_contextmenu(e, row.index) 680 687 } 681 688 }} 689 + ondragstart={on_drag_start} 690 + ondragover={(e) => { 691 + const row = get_row(e) 692 + if (row) { 693 + on_drag_over(e, row.element, row.index) 694 + } 695 + }} 696 + ondrop={drop_handler} 697 + ondragend={drag_end_handler} 682 698 ></div> 683 699 684 700 <!-- <div ··· 876 892 // padding-right: 5px 877 893 // .dateAdded 878 894 // font-variant-numeric: tabular-nums 879 - // .drag-line 880 - // position: absolute 881 - // width: 100% 882 - // height: 2px 883 - // background-color: var(--drag-line-color) 884 - // pointer-events: none 895 + .drag-line 896 + margin-top: 24px 897 + position: absolute 898 + width: 100% 899 + height: 2px 900 + background-color: var(--drag-line-color) 901 + pointer-events: none 885 902 // .col-drag-line 886 903 // position: absolute 887 904 // width: 2px