Implement bulk reoder (inefficient)

This commit is contained in:
2025-11-24 01:03:15 +05:00
parent 04d99760e2
commit a281b92425
6 changed files with 62 additions and 9 deletions

View File

@ -31,4 +31,5 @@ public class PlaylistController {
@RequestBody PlaylistCreateRequest playlist) {
return service.createPlaylist(user.getId(), playlist);
}
}

View File

@ -10,10 +10,13 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.bivashy.backend.composer.dto.track.AddLocalTrackRequest;
import com.bivashy.backend.composer.dto.track.PlaylistTrackResponse;
import com.bivashy.backend.composer.dto.track.TrackBulkReorderRequest;
import com.bivashy.backend.composer.dto.track.TrackReorderAfterRequest;
import com.bivashy.backend.composer.dto.track.TrackResponse;
import com.bivashy.backend.composer.model.User;
import com.bivashy.backend.composer.service.TrackService;
@ -42,4 +45,11 @@ public class TrackController {
List<PlaylistTrackResponse> tracks = trackService.getPlaylistTracks(user, playlistId);
return ResponseEntity.ok(tracks);
}
@PostMapping("/playlist/{playlistId}/bulk-reorder")
public void bulkReorder(@AuthenticationPrincipal User user,
@RequestBody TrackBulkReorderRequest request,
@PathVariable Long playlistId) {
trackService.bulkReorder(user, playlistId, request);
}
}

View File

@ -0,0 +1,6 @@
package com.bivashy.backend.composer.dto.track;
import java.util.List;
public record TrackBulkReorderRequest(List<Long> trackIds) {
}

View File

@ -0,0 +1,4 @@
package com.bivashy.backend.composer.dto.track;
public record TrackReorderAfterRequest(long moveTrackId, long targetTrackId) {
}

View File

@ -2,7 +2,10 @@ package com.bivashy.backend.composer.service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
@ -41,11 +44,9 @@ public class TrackPlaylistService {
private void addTrack(Long playlistId, Long trackId, BigDecimal afterOrder) {
BigDecimal newOrder;
if (afterOrder == null) {
// Insert at the end
BigDecimal maxOrder = repository.findMaxOrderByPlaylistId(playlistId);
newOrder = findIntermediateOrder(maxOrder, null);
} else {
// Insert after a specific track
BigDecimal nextOrder = repository.findNextOrderByPlaylistIdAndOrderGreaterThan(playlistId, afterOrder);
newOrder = findIntermediateOrder(afterOrder, nextOrder);
}
@ -53,15 +54,39 @@ public class TrackPlaylistService {
repository.save(trackPlaylist);
}
public void reorderTrack(Long playlistId, Long trackId, BigDecimal afterOrder) {
TrackPlaylist trackPlaylist = repository.findById(new PlaylistTrackId(playlistId, trackId))
.orElseThrow(() -> new RuntimeException("TrackPlaylist not found"));
public void bulkReorder(Long playlistId, List<Long> orderedTrackIds) {
List<TrackPlaylist> existingTracks = repository.findByPlaylistIdOrderByOrderAsc(playlistId);
Set<Long> existingTrackIds = existingTracks.stream()
.map(TrackPlaylist::getTrackId)
.collect(Collectors.toSet());
BigDecimal nextOrder = repository.findNextOrderByPlaylistIdAndOrderGreaterThan(playlistId, afterOrder);
BigDecimal newOrder = findIntermediateOrder(afterOrder, nextOrder);
if (!existingTrackIds.containsAll(orderedTrackIds) ||
orderedTrackIds.size() != existingTrackIds.size()) {
throw new IllegalArgumentException("Invalid track IDs provided for reordering");
}
trackPlaylist.setOrder(newOrder);
repository.save(trackPlaylist);
List<BigDecimal> newOrders = calculateNewOrders(orderedTrackIds.size());
for (int i = 0; i < orderedTrackIds.size(); i++) {
Long trackId = orderedTrackIds.get(i);
BigDecimal newOrder = newOrders.get(i);
TrackPlaylist trackPlaylist = repository.findById(new PlaylistTrackId(playlistId, trackId))
.orElseThrow(() -> new RuntimeException("Track not found in playlist"));
trackPlaylist.setOrder(newOrder);
repository.save(trackPlaylist);
}
}
private List<BigDecimal> calculateNewOrders(int count) {
List<BigDecimal> orders = new ArrayList<>();
BigDecimal step = BigDecimal.valueOf(1000);
for (int i = 0; i < count; i++) {
orders.add(step.multiply(BigDecimal.valueOf(i + 1)));
}
return orders;
}
}

View File

@ -10,6 +10,8 @@ import org.springframework.web.server.ResponseStatusException;
import com.bivashy.backend.composer.dto.track.AddLocalTrackRequest;
import com.bivashy.backend.composer.dto.track.PlaylistTrackResponse;
import com.bivashy.backend.composer.dto.track.TrackBulkReorderRequest;
import com.bivashy.backend.composer.dto.track.TrackReorderAfterRequest;
import com.bivashy.backend.composer.dto.track.TrackResponse;
import com.bivashy.backend.composer.model.SourceTypes;
import com.bivashy.backend.composer.model.Track;
@ -83,7 +85,12 @@ public class TrackService {
.toList();
}
public void bulkReorder(User user, Long playlistId, TrackBulkReorderRequest request) {
trackPlaylistService.bulkReorder(playlistId, request.trackIds());
}
private String fileNameWithoutExtension(String fileName) {
return fileName.replaceFirst("[.][^.]+$", "");
}
}