Save NoteSheets

This commit is contained in:
Fawkes100 2025-01-18 17:51:04 +01:00
parent d9b59ba07c
commit c04dbe565a
8 changed files with 146 additions and 18 deletions

View File

@ -5,12 +5,13 @@ import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import com.stormtales.notevault.data.entities.NoteSheet;
import com.stormtales.notevault.data.entities.Song;
import com.stormtales.notevault.data.dao.SongDao;
import com.stormtales.notevault.data.sync.DateConverter;
import com.stormtales.notevault.data.sync.SyncStatusConverter;
@Database(entities = {Song.class}, version = 1, exportSchema = false)
@Database(entities = {Song.class, NoteSheet.class}, version = 1, exportSchema = false)
@TypeConverters({SyncStatusConverter.class, DateConverter.class})
public abstract class MusicDatabase extends RoomDatabase {
public abstract SongDao getSongTable();

View File

@ -1,10 +1,8 @@
package com.stormtales.notevault.data.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import androidx.room.*;
import com.stormtales.notevault.data.entities.NoteSheet;
import com.stormtales.notevault.data.entities.Song;
import java.util.List;
@ -12,11 +10,19 @@ import java.util.List;
@Dao
public interface SongDao {
@Insert
void insert(Song song);
long insert(Song song);
@Query("SELECT * FROM song WHERE syncStatus != 1")
List<Song> getAllSongs();
@Update
void update(Song song);
@Insert
void insert(List<NoteSheet> noteSheets);
@Delete
void deleteNoteSheets(List<NoteSheet> noteSheets);
List<NoteSheet> getNoteSheetsBySong(int songID);
}

View File

@ -7,13 +7,17 @@ import java.util.Objects;
@Entity
public class NoteSheet {
@PrimaryKey
@PrimaryKey(autoGenerate = true)
private int localID;
private int songID;
private String localFileName;
private String hash;
public NoteSheet(String localFileName, String hash) {
this.localFileName = localFileName;
this.hash = hash;
}
public int getLocalID() {
return localID;
}
@ -49,4 +53,12 @@ public class NoteSheet {
public int hashCode() {
return Objects.hash(localID, localFileName, hash);
}
public int getSongID() {
return songID;
}
public void setSongID(int songID) {
this.songID = songID;
}
}

View File

@ -7,7 +7,9 @@ import android.os.Looper;
import androidx.lifecycle.LiveData;
import com.stormtales.notevault.data.MusicDatabase;
import com.stormtales.notevault.data.dao.SongDao;
import com.stormtales.notevault.data.entities.NoteSheet;
import com.stormtales.notevault.data.entities.Song;
import com.stormtales.notevault.data.sync.SyncStatus;
import java.util.List;
import java.util.concurrent.ExecutorService;
@ -19,9 +21,11 @@ public class SongRepository {
MusicDatabase database = MusicDatabase.getDatabase(context);
songDao = database.getSongTable();
}
public void insert(Song song) {
public void insert(Song song, Callback<Long> callback) {
Executors.newSingleThreadExecutor().execute(() -> {
songDao.insert(song);
long result = songDao.insert(song);
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(()-> callback.onResult(result));
});
}
@ -43,4 +47,19 @@ public class SongRepository {
songDao.update(song);
});
}
public void insertNoteSheets(List<NoteSheet> noteSheets) {
Executors.newSingleThreadExecutor().execute(() -> {
songDao.insert(noteSheets);
});
}
public interface Callback<T> {
void onResult(T result);
}
public void deleteSong(Song song) {
song.setSyncStatus(SyncStatus.DELETED);
songDao.update(song);
}
}

View File

@ -1,15 +1,13 @@
package com.stormtales.notevault.ui.home;
import android.app.Application;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.stormtales.notevault.data.entities.NoteSheet;
import com.stormtales.notevault.data.entities.Song;
import com.stormtales.notevault.data.repositories.SongRepository;
import com.stormtales.notevault.data.sync.SyncStatus;
import kotlinx.coroutines.CoroutineScope;
import java.util.ArrayList;
import java.util.List;
@ -25,8 +23,15 @@ public class HomeViewModel extends ViewModel {
/*this.allSongs.setValue(songRepository.getAllSongs());*/
}
public void addSong(Song song) {
songRepository.insert(song);
public void addSong(Song song, List<NoteSheet> noteSheetList) {
songRepository.insert(song, internalSongID -> {
for(NoteSheet noteSheet : noteSheetList) {
noteSheet.setSongID(Math.toIntExact(internalSongID));
}
songRepository.insertNoteSheets(noteSheetList);
});
List<Song> currentSongs = allSongs.getValue();
if(currentSongs == null) {
currentSongs = new ArrayList<>();
@ -54,8 +59,7 @@ public class HomeViewModel extends ViewModel {
}
public void deleteSong(Song song) {
song.setSyncStatus(SyncStatus.DELETED);
songRepository.updateSong(song);
songRepository.deleteSong(song);
List<Song> currentSongs = allSongs.getValue();
if(currentSongs != null) {

View File

@ -2,6 +2,7 @@ package com.stormtales.notevault.ui.songeditor;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.text.Layout;
@ -16,11 +17,17 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.lifecycle.ViewModelProvider;
import com.stormtales.notevault.R;
import com.stormtales.notevault.data.entities.NoteSheet;
import com.stormtales.notevault.data.entities.Song;
import com.stormtales.notevault.data.sync.SyncStatus;
import com.stormtales.notevault.ui.home.HomeViewModel;
import com.stormtales.notevault.utils.NoteSheetsUtil;
import com.stormtales.notevault.utils.Tupel;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class SongEditorDialog extends DialogFragment {
@ -89,7 +96,15 @@ public class SongEditorDialog extends DialogFragment {
homeViewModel.updateSong(editedSong);
} else {
Song song = new Song(title, composer, genre, releaseYear);
homeViewModel.addSong(song);
List<NoteSheet> noteSheetList = new ArrayList<>();
Context context = this.getContext();
for(Uri uri : noteSheetFiles) {
Tupel<String, String> result = NoteSheetsUtil.saveImageInternally(context.getContentResolver(), uri, context.getFilesDir());
noteSheetList.add(new NoteSheet(result.getValue00(), result.getValue01()));
}
homeViewModel.addSong(song, noteSheetList);
}

View File

@ -1,5 +1,6 @@
package com.stormtales.notevault.utils;
import android.content.ContentResolver;
import android.content.Context;
import android.media.ExifInterface;
import android.net.Uri;
@ -7,6 +8,10 @@ import android.net.Uri;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@ -46,4 +51,37 @@ public class NoteSheetsUtil {
}
}
public static Tupel<String, String> saveImageInternally(ContentResolver contentResolver, Uri uri, File filesDir) {
try (InputStream inputStream = contentResolver.openInputStream(uri)) {
// Datei erstellen
File imageFile = new File(filesDir, "saved_image_" + System.currentTimeMillis() + ".jpg");
try (OutputStream outputStream = Files.newOutputStream(imageFile.toPath())) {
// SHA-256 Hash-Funktion initialisieren
MessageDigest digest = MessageDigest.getInstance("SHA-256");
// Daten blockweise lesen und gleichzeitig schreiben und hashen
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
digest.update(buffer, 0, bytesRead); // Hash aktualisieren
}
// Hash berechnen
byte[] hashBytes = digest.digest();
StringBuilder hashString = new StringBuilder();
for (byte b : hashBytes) {
hashString.append(String.format("%02x", b)); // Bytes in Hexadezimal umwandeln
}
// Hashwert zurückgeben (kann auch zusammen mit dem Pfad gespeichert werden)
return new Tupel<>(imageFile.getAbsolutePath(), hashString.toString());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,33 @@
package com.stormtales.notevault.utils;
import java.util.Objects;
public class Tupel<A,B> {
private final A value00;
private final B value01;
public Tupel(A value00, B value01) {
this.value00 = value00;
this.value01 = value01;
}
public A getValue00() {
return value00;
}
public B getValue01() {
return value01;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Tupel<?, ?> tupel = (Tupel<?, ?>) o;
return Objects.equals(value00, tupel.value00) && Objects.equals(value01, tupel.value01);
}
@Override
public int hashCode() {
return Objects.hash(value00, value01);
}
}