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

Prevent moving playlist inside itself

Kasper (Jul 26, 2022, 1:14 PM +0200) f944f29e bec8e1b0

+45 -6
+28 -1
native/src/playlists.rs
··· 3 3 use crate::data::Data; 4 4 use crate::data_js::get_data; 5 5 use crate::js::{arg_to_bool, arg_to_number_vector, arg_to_string, arg_to_string_vector}; 6 - use crate::library_types::{Library, SpecialTrackListName, TrackList}; 6 + use crate::library_types::{Library, SpecialTrackListName, TrackID, TrackList}; 7 7 use crate::{str_to_option, UniResult}; 8 8 use napi::{CallContext, JsUndefined, JsUnknown, Result as NResult}; 9 9 use napi_derive::js_function; ··· 172 172 return ctx.env.get_undefined(); 173 173 } 174 174 175 + fn get_all_tracklist_children(data: &Data, playlist_id: &str) -> UniResult<Vec<TrackID>> { 176 + let direct_children = match data.library.get_tracklist(playlist_id)? { 177 + TrackList::Folder(folder) => &folder.children, 178 + TrackList::Special(special) => &special.children, 179 + TrackList::Playlist(_) => return Ok(Vec::new()), 180 + }; 181 + let mut all_children = Vec::new(); 182 + for child_id in direct_children { 183 + all_children.push(child_id.clone()); 184 + match data.library.get_tracklist(child_id)? { 185 + TrackList::Playlist(_) => {} 186 + TrackList::Folder(folder) => { 187 + all_children.extend(get_all_tracklist_children(data, &folder.id)?) 188 + } 189 + TrackList::Special(special) => { 190 + all_children.extend(get_all_tracklist_children(data, &special.id)?) 191 + } 192 + } 193 + } 194 + Ok(all_children) 195 + } 196 + 175 197 fn get_children_if_user_editable<'a>( 176 198 library: &'a mut Library, 177 199 id: &'a str, ··· 202 224 203 225 // check that the to_id is valid before we remove it from from_id 204 226 get_children_if_user_editable(&mut data.library, &to_id)?; 227 + 228 + let from_id_children = get_all_tracklist_children(&data, &id)?; 229 + if from_id_children.contains(&to_id) { 230 + throw!("Cannot move playlist to a child of itself"); 231 + } 205 232 206 233 let children = get_children_if_user_editable(&mut data.library, &from_id)?; 207 234 let i = match children.iter().position(|child_id| child_id == &id) {
+16 -5
src/components/SidebarItems.svelte
··· 116 116 let dragTrackOntoIndex = null as number | null 117 117 let dragPlaylistOntoIndex = null as number | null 118 118 119 - let playlistId: string | null = null 119 + let dragPlaylistId: string | null = null 120 120 function onDragStart(e: DragEvent, tracklist: TrackList) { 121 121 if (e.dataTransfer && tracklist.type !== 'special' && parentId) { 122 122 e.dataTransfer.effectAllowed = 'move' 123 - playlistId = tracklist.id 123 + dragPlaylistId = tracklist.id 124 124 dragGhost.setInnerText(tracklist.name) 125 125 dragged.playlist = { 126 - id: playlistId, 126 + id: dragPlaylistId, 127 127 fromFolder: parentId, 128 + level, 128 129 } 129 130 e.dataTransfer.setDragImage(dragGhost.dragEl, 0, 0) 130 131 e.dataTransfer.setData('ferrum.playlist', '') ··· 147 148 if ( 148 149 e.currentTarget && 149 150 e.dataTransfer?.types[0] === 'ferrum.playlist' && 150 - dragged.playlist 151 + dragged.playlist && 152 + level <= dragged.playlist.level && 153 + dragged.playlist.id !== childList.id 151 154 ) { 152 155 movePlaylist(dragged.playlist.id, dragged.playlist.fromFolder, childList.id) 153 156 } ··· 176 179 <div 177 180 class="text" 178 181 on:dragover={(e) => { 179 - if (e.currentTarget && e.dataTransfer?.types[0] === 'ferrum.playlist') { 182 + if ( 183 + e.currentTarget && 184 + e.dataTransfer?.types[0] === 'ferrum.playlist' && 185 + dragged.playlist && 186 + level <= dragged.playlist.level && 187 + dragged.playlist.id !== childList.id 188 + ) { 180 189 dragPlaylistOntoIndex = i 181 190 e.preventDefault() 182 191 } ··· 280 289 background-position: 100% 0% 281 290 background-size: 150% 150% 282 291 transition: 260ms background-position cubic-bezier(0, 0.02, 0.2, 1) 292 + .prevent-child-drop > :global(*) 293 + pointer-events: none 283 294 .item.droppable .text 284 295 border-radius: 6px 285 296 box-shadow: inset 0px 0px 0px 2px var(--accent-1)
+1
src/lib/drag-drop.ts
··· 1 1 type DragPlaylist = { 2 2 id: string 3 3 fromFolder: string 4 + level: number 4 5 } 5 6 6 7 export const dragged = {