diff --git a/app/src/main/java/com/stormtales/notevault/data/dao/SongDao.java b/app/src/main/java/com/stormtales/notevault/data/dao/SongDao.java index 886faea..f16a614 100644 --- a/app/src/main/java/com/stormtales/notevault/data/dao/SongDao.java +++ b/app/src/main/java/com/stormtales/notevault/data/dao/SongDao.java @@ -42,4 +42,10 @@ public interface SongDao { @Query("SELECT * FROM Song WHERE serverID IN (:serverIDs)") List getSongsByServerIDs(List serverIDs); + + @Query("DELETE FROM Song WHERE serverID IN (:serverIDs)") + void deleteSongsByServerIDs(List serverIDs); + + @Query("DELETE FROM SONG WHERE localID IN (:localIDs)") + void deleteSongsByLocalIDs(List localIDs); } diff --git a/app/src/main/java/com/stormtales/notevault/data/repositories/SongSyncRepository.java b/app/src/main/java/com/stormtales/notevault/data/repositories/SongSyncRepository.java index 9060197..2c98207 100644 --- a/app/src/main/java/com/stormtales/notevault/data/repositories/SongSyncRepository.java +++ b/app/src/main/java/com/stormtales/notevault/data/repositories/SongSyncRepository.java @@ -41,6 +41,14 @@ public class SongSyncRepository { }); } + public void loadDeletedSongs(LoadDataCallback> callback) { + Executors.newSingleThreadExecutor().execute(() -> { + List deletedSongs = songDao.getSongsBySyncStatus(SyncStatus.DELETED); + Handler mainHandler = new Handler(Looper.getMainLooper()); + mainHandler.post(()-> callback.onResult(deletedSongs)); + }); + } + public void markCreatedSongsAsSynced(BatchCreateResponse createdSongs) { Executors.newSingleThreadExecutor().execute(() -> { List localIDs = createdSongs.getCreateResponses().stream().map(CreateResponse::getLocalID).collect(Collectors.toList()); @@ -78,6 +86,13 @@ public class SongSyncRepository { }); } + public void markDeletedSongsAsSynced(List remoteDeletedSongs, List localDeletedSongs) { + Executors.newSingleThreadExecutor().execute(() -> { + songDao.deleteSongsByServerIDs(remoteDeletedSongs); + songDao.deleteSongsByLocalIDs(localDeletedSongs); + }); + } + public interface LoadDataCallback { void onResult(T result); } diff --git a/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncAPI.java b/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncAPI.java index ddec0fb..5ec6449 100644 --- a/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncAPI.java +++ b/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncAPI.java @@ -2,10 +2,7 @@ package com.stormtales.notevault.network.sync; import com.stormtales.notevault.network.auth.LoginRequest; import com.stormtales.notevault.network.auth.LoginResponse; -import com.stormtales.notevault.network.sync.models.BatchCreateResponse; -import com.stormtales.notevault.network.sync.models.BatchModifyResponse; -import com.stormtales.notevault.network.sync.models.SongCreateBatchRequest; -import com.stormtales.notevault.network.sync.models.SongModifyBatchRequest; +import com.stormtales.notevault.network.sync.models.*; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; @@ -17,4 +14,7 @@ public interface SongSyncAPI { @POST("/sync/songs/modify") Call syncModifiedSongs(@Body SongModifyBatchRequest songModifyBatchRequest); + + @POST("/sync/songs/delete") + Call syncDeletedSongs(@Body SongBatchDeleteRequest songBatchDeleteRequest); } diff --git a/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncModule.java b/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncModule.java index 8c0b6ff..f46d3c8 100644 --- a/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncModule.java +++ b/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncModule.java @@ -7,6 +7,8 @@ import com.stormtales.notevault.network.sync.models.BatchCreateResponse; import com.stormtales.notevault.network.sync.models.BatchModifyResponse; import com.stormtales.notevault.ui.gallery.GalleryViewModel; +import java.util.List; + public class SongSyncModule { private SongRepository songRepository; private SongSyncRepository songSyncRepository; @@ -38,6 +40,15 @@ public class SongSyncModule { }); } + public void syncDeletedSongs() { + songSyncRepository.loadDeletedSongs(result -> { + songSyncService.syncDeletedSong(result, (remoteDeletedSongs, localDeletedSongs) -> { + songSyncRepository.markDeletedSongsAsSynced(remoteDeletedSongs, localDeletedSongs); + syncViewModel.finishDeleteSongSyncinc(); + }); + }); + } + public interface FinishSongCreateSyncingCallback { void finishSongSyncing(BatchCreateResponse response); } diff --git a/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncService.java b/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncService.java index 469dfb4..0aadb9b 100644 --- a/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncService.java +++ b/app/src/main/java/com/stormtales/notevault/network/sync/SongSyncService.java @@ -58,4 +58,37 @@ public class SongSyncService { } }); } + + public void syncDeletedSong(List songs, SyncDeletedSongsCallback callback) { + List deleteRequests = new ArrayList<>(); + List deletedNotSyncedSongs = new ArrayList<>(); + for(Song song : songs) { + if(song.getServerID() == null) { + deletedNotSyncedSongs.add(song.getLocalID()); + } else { + deleteRequests.add(song.getServerID()); + } + } + + SongBatchDeleteRequest songBatchDeleteRequest = new SongBatchDeleteRequest(deleteRequests); + songSyncAPI.syncDeletedSongs(songBatchDeleteRequest).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful() && response.body() != null) { + callback.finishSongSyncing(response.body().getModifiedServerObjects(), deletedNotSyncedSongs); + } + } + + @Override + public void onFailure(Call call, Throwable throwable) { + + } + }); + } + + + + public interface SyncDeletedSongsCallback { + void finishSongSyncing(List remoteDeletedSongs, List localDeletedSongs); + } } diff --git a/app/src/main/java/com/stormtales/notevault/network/sync/models/SongBatchDeleteRequest.java b/app/src/main/java/com/stormtales/notevault/network/sync/models/SongBatchDeleteRequest.java new file mode 100644 index 0000000..918c09e --- /dev/null +++ b/app/src/main/java/com/stormtales/notevault/network/sync/models/SongBatchDeleteRequest.java @@ -0,0 +1,19 @@ +package com.stormtales.notevault.network.sync.models; + +import java.util.List; + +public class SongBatchDeleteRequest { + private List songs; + + public SongBatchDeleteRequest(List songs) { + this.songs = songs; + } + + public List getSongs() { + return songs; + } + + public void setSongs(List songs) { + this.songs = songs; + } +} diff --git a/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryFragment.java b/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryFragment.java index 16b804d..157cdff 100644 --- a/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryFragment.java +++ b/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryFragment.java @@ -24,6 +24,8 @@ public class GalleryFragment extends Fragment { private Button sync_created_songs_btn; private ProgressBar progress_sync_modified_songs; private Button sync_modified_songs_btn; + private ProgressBar progress_sync_deleted_songs; + private Button sync_deleted_songs_btn; public View onCreateView(@NonNull LayoutInflater inflater, @@ -36,10 +38,15 @@ public class GalleryFragment extends Fragment { progress_sync_created_songs = binding.progressSyncCreatedSongs; sync_created_songs_btn = binding.syncCreatedBtn; sync_created_songs_btn.setOnClickListener(v -> onSyncCreatedSongs()); + progress_sync_modified_songs = binding.progressSyncModifiedSongs; sync_modified_songs_btn = binding.syncModifiedBtn; sync_modified_songs_btn.setOnClickListener(v -> onSyncModifiedSogs()); + progress_sync_deleted_songs = binding.progressSyncDeletedSongs; + sync_deleted_songs_btn = binding.syncDeletedBtn; + sync_deleted_songs_btn.setOnClickListener(v -> onSyncDeletedSongs()); + galleryViewModel.setSongSyncModule(new SongSyncModule(getContext(), galleryViewModel)); galleryViewModel.getIsCreatedSongSyncing().observe(getViewLifecycleOwner(), isCreatedSyncinc -> { @@ -61,9 +68,23 @@ public class GalleryFragment extends Fragment { sync_modified_songs_btn.setEnabled(true); } }); + + galleryViewModel.getIsDeletedSongSyncing().observe(getViewLifecycleOwner(), isDeletedSyncinc -> { + if(isDeletedSyncinc) { + progress_sync_deleted_songs.setIndeterminate(true); + sync_deleted_songs_btn.setEnabled(false); + } else { + progress_sync_deleted_songs.setIndeterminate(false); + sync_deleted_songs_btn.setEnabled(true); + } + }); return root; } + private void onSyncDeletedSongs() { + galleryViewModel.startDeletedSongSyncing(); + } + @Override public void onDestroyView() { diff --git a/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryViewModel.java b/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryViewModel.java index bf33e43..d6207dd 100644 --- a/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryViewModel.java +++ b/app/src/main/java/com/stormtales/notevault/ui/gallery/GalleryViewModel.java @@ -10,6 +10,7 @@ public class GalleryViewModel extends ViewModel { private final MutableLiveData isCreatedSongSyncing; private final MutableLiveData isModifiedSongSyncing; + private final MutableLiveData isDeletedSongSyncing; private SongSyncModule songSyncModule; public GalleryViewModel() { @@ -19,6 +20,9 @@ public class GalleryViewModel extends ViewModel { isModifiedSongSyncing = new MutableLiveData<>(); isModifiedSongSyncing.setValue(false); + + isDeletedSongSyncing = new MutableLiveData<>(); + isDeletedSongSyncing.setValue(false); } public MutableLiveData getIsCreatedSongSyncing() { @@ -53,4 +57,18 @@ public class GalleryViewModel extends ViewModel { public void finishModifiedSongSyncinc() { this.isModifiedSongSyncing.setValue(false); } + + public MutableLiveData getIsDeletedSongSyncing() { + return isDeletedSongSyncing; + } + + public void startDeletedSongSyncing() { + if(this.songSyncModule == null) throw new RuntimeException("SongSyncModule is not initialized"); + this.isDeletedSongSyncing.setValue(true); + this.songSyncModule.syncDeletedSongs(); + } + + public void finishDeleteSongSyncinc() { + this.isDeletedSongSyncing.setValue(false); + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_gallery.xml b/app/src/main/res/layout/fragment_gallery.xml index 6ce550d..19ef9d4 100644 --- a/app/src/main/res/layout/fragment_gallery.xml +++ b/app/src/main/res/layout/fragment_gallery.xml @@ -103,6 +103,49 @@ android:layout_marginEnd="16dp" /> + + + + + + + + + +