nextNoteVault #23
@ -1,5 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="GradleMigrationSettings" migrationVersion="1" />
 | 
			
		||||
  <component name="GradleSettings">
 | 
			
		||||
    <option name="linkedExternalProjectsSettings">
 | 
			
		||||
      <GradleProjectSettings>
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  <component name="FrameworkDetectionExcludesConfiguration">
 | 
			
		||||
    <file type="web" url="file://$PROJECT_DIR$" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="21" project-jdk-type="JavaSDK">
 | 
			
		||||
  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
 | 
			
		||||
    <output url="file://$PROJECT_DIR$/build/classes" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="ProjectType">
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								.idea/runConfigurations.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.idea/runConfigurations.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="RunConfigurationProducerService">
 | 
			
		||||
    <option name="ignoredProducers">
 | 
			
		||||
      <set>
 | 
			
		||||
        <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
 | 
			
		||||
        <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
 | 
			
		||||
        <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
 | 
			
		||||
      </set>
 | 
			
		||||
    </option>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										6
									
								
								.idea/vcs.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/vcs.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="VcsDirectoryMappings">
 | 
			
		||||
    <mapping directory="" vcs="Git" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
@ -26,14 +26,14 @@ public class MainActivity extends AppCompatActivity {
 | 
			
		||||
        setContentView(binding.getRoot());
 | 
			
		||||
 | 
			
		||||
        setSupportActionBar(binding.appBarMain.toolbar);
 | 
			
		||||
        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
        /*binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
 | 
			
		||||
                        .setAction("Action", null)
 | 
			
		||||
                        .setAnchorView(R.id.fab).show();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        });*/
 | 
			
		||||
        DrawerLayout drawer = binding.drawerLayout;
 | 
			
		||||
        NavigationView navigationView = binding.navView;
 | 
			
		||||
        // Passing each menu ID as a set of Ids because each
 | 
			
		||||
 | 
			
		||||
@ -6,11 +6,12 @@ import androidx.room.Room;
 | 
			
		||||
import androidx.room.RoomDatabase;
 | 
			
		||||
import androidx.room.TypeConverters;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.data.repositories.SongDao;
 | 
			
		||||
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)
 | 
			
		||||
@TypeConverters(SyncStatusConverter.class)
 | 
			
		||||
@TypeConverters({SyncStatusConverter.class, DateConverter.class})
 | 
			
		||||
public abstract class MusicDatabase extends RoomDatabase {
 | 
			
		||||
    public abstract SongDao getSongTable();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,17 @@
 | 
			
		||||
package com.stormtales.notevault.data.dao;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Dao;
 | 
			
		||||
import androidx.room.Insert;
 | 
			
		||||
import androidx.room.Query;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Dao
 | 
			
		||||
public interface SongDao {
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insert(Song song);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM song")
 | 
			
		||||
    List<Song> getAllSongs();
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package com.stormtales.notevault.data.entities;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Entity;
 | 
			
		||||
import androidx.room.Ignore;
 | 
			
		||||
import androidx.room.PrimaryKey;
 | 
			
		||||
import com.stormtales.notevault.data.sync.SyncStatus;
 | 
			
		||||
 | 
			
		||||
@ -22,6 +23,14 @@ public class Song {
 | 
			
		||||
    private String genre;
 | 
			
		||||
    private int year;
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
    public Song(String title, String composer, String genre, int year) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.composer = composer;
 | 
			
		||||
        this.genre = genre;
 | 
			
		||||
        this.year = year;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLocalID() {
 | 
			
		||||
        return localID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +0,0 @@
 | 
			
		||||
package com.stormtales.notevault.data.repositories;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Dao;
 | 
			
		||||
 | 
			
		||||
@Dao
 | 
			
		||||
public interface SongDao {
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
package com.stormtales.notevault.data.repositories;
 | 
			
		||||
 | 
			
		||||
import android.app.Application;
 | 
			
		||||
import com.stormtales.notevault.data.MusicDatabase;
 | 
			
		||||
import com.stormtales.notevault.data.dao.SongDao;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
public class SongRepository {
 | 
			
		||||
    private SongDao songDao;
 | 
			
		||||
    public SongRepository(Application application) {
 | 
			
		||||
        MusicDatabase database = MusicDatabase.getDatabase(application);
 | 
			
		||||
        songDao = database.getSongTable();
 | 
			
		||||
    }
 | 
			
		||||
    public void insert(Song song) {
 | 
			
		||||
        Executors.newSingleThreadExecutor().execute(() -> {
 | 
			
		||||
            songDao.insert(song);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,20 @@
 | 
			
		||||
package com.stormtales.notevault.data.sync;
 | 
			
		||||
 | 
			
		||||
import androidx.room.TypeConverter;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.format.DateTimeFormatter;
 | 
			
		||||
 | 
			
		||||
public class DateConverter {
 | 
			
		||||
    // Konvertiere LocalDateTime in String
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    public static String fromLocalDateTime(LocalDateTime localDateTime) {
 | 
			
		||||
        return localDateTime == null ? null : localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Konvertiere String zurück in LocalDateTime
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    public static LocalDateTime toLocalDateTime(String dateTimeString) {
 | 
			
		||||
        return dateTimeString == null ? null : LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,18 +1,30 @@
 | 
			
		||||
package com.stormtales.notevault.ui.home;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import androidx.activity.result.ActivityResult;
 | 
			
		||||
import androidx.activity.result.ActivityResultCallback;
 | 
			
		||||
import androidx.activity.result.ActivityResultLauncher;
 | 
			
		||||
import androidx.activity.result.contract.ActivityResultContracts;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.lifecycle.ViewModelProvider;
 | 
			
		||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
 | 
			
		||||
import com.stormtales.notevault.R;
 | 
			
		||||
import com.stormtales.notevault.databinding.FragmentHomeBinding;
 | 
			
		||||
import com.stormtales.notevault.ui.songeditor.SongEditorDialog;
 | 
			
		||||
 | 
			
		||||
public class HomeFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private FragmentHomeBinding binding;
 | 
			
		||||
    private static final int PICK_FILE_REQUEST_CODE = 1;
 | 
			
		||||
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater,
 | 
			
		||||
                             ViewGroup container, Bundle savedInstanceState) {
 | 
			
		||||
@ -21,6 +33,42 @@ public class HomeFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
        binding = FragmentHomeBinding.inflate(inflater, container, false);
 | 
			
		||||
        View root = binding.getRoot();
 | 
			
		||||
        ActivityResultLauncher<Intent> launcher = registerForActivityResult(
 | 
			
		||||
                new ActivityResultContracts.StartActivityForResult(),
 | 
			
		||||
                activityResult -> {
 | 
			
		||||
                    getActivity();
 | 
			
		||||
                    if(activityResult.getResultCode() == Activity.RESULT_OK && activityResult.getData() != null) {
 | 
			
		||||
                        if(activityResult.getData().getClipData() != null) {
 | 
			
		||||
                            int fileNumber = activityResult.getData().getClipData().getItemCount();
 | 
			
		||||
                            Uri[] files = new Uri[fileNumber];
 | 
			
		||||
                            for(int i = 0; i < fileNumber; i++) {
 | 
			
		||||
                                files[i] = activityResult.getData().getClipData().getItemAt(i).getUri();
 | 
			
		||||
                                Toast.makeText(requireContext(), "Uri: " + files[i].toString(), Toast.LENGTH_SHORT).show();
 | 
			
		||||
                            }
 | 
			
		||||
                            handleSelectedNoteSheets(files);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Uri uri = activityResult.getData().getData();
 | 
			
		||||
                            Toast.makeText(requireContext(), "Uri: " + uri.toString(), Toast.LENGTH_SHORT).show();
 | 
			
		||||
                            handleSelectedNoteSheets(uri);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        FloatingActionButton importBtn = root.findViewById(R.id.addSongBtn);
 | 
			
		||||
        importBtn.setOnClickListener(v -> {
 | 
			
		||||
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
 | 
			
		||||
            intent.setType("*/*"); // Alle Dateitypen
 | 
			
		||||
 | 
			
		||||
            String[] mimeTypes = {"application/pdf", "image/png", "image/jpeg"};
 | 
			
		||||
            intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
 | 
			
		||||
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
 | 
			
		||||
 | 
			
		||||
            intent.addCategory(Intent.CATEGORY_OPENABLE);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            launcher.launch(intent);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        final TextView textView = binding.textHome;
 | 
			
		||||
        homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
 | 
			
		||||
@ -32,4 +80,13 @@ public class HomeFragment extends Fragment {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
        binding = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void handleSelectedNoteSheets(Uri... files) {
 | 
			
		||||
        SongEditorDialog songEditorDialog = new SongEditorDialog();
 | 
			
		||||
 | 
			
		||||
        int width = getResources().getDisplayMetrics().widthPixels;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        songEditorDialog.show(getParentFragmentManager(), "songEditorDialog");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -3,10 +3,13 @@ package com.stormtales.notevault.ui.home;
 | 
			
		||||
import androidx.lifecycle.LiveData;
 | 
			
		||||
import androidx.lifecycle.MutableLiveData;
 | 
			
		||||
import androidx.lifecycle.ViewModel;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.data.repositories.SongRepository;
 | 
			
		||||
 | 
			
		||||
public class HomeViewModel extends ViewModel {
 | 
			
		||||
 | 
			
		||||
    private final MutableLiveData<String> mText;
 | 
			
		||||
    private SongRepository songRepository;
 | 
			
		||||
 | 
			
		||||
    public HomeViewModel() {
 | 
			
		||||
        mText = new MutableLiveData<>();
 | 
			
		||||
@ -16,4 +19,8 @@ public class HomeViewModel extends ViewModel {
 | 
			
		||||
    public LiveData<String> getText() {
 | 
			
		||||
        return mText;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addSong(Song song) {
 | 
			
		||||
        songRepository.insert(song);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,67 @@
 | 
			
		||||
package com.stormtales.notevault.ui.songeditor;
 | 
			
		||||
 | 
			
		||||
import android.app.AlertDialog;
 | 
			
		||||
import android.app.Dialog;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.text.Layout;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.fragment.app.DialogFragment;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import androidx.lifecycle.ViewModelProvider;
 | 
			
		||||
import com.stormtales.notevault.R;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.ui.home.HomeViewModel;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class SongEditorDialog extends DialogFragment {
 | 
			
		||||
 | 
			
		||||
    Dialog dialog;
 | 
			
		||||
 | 
			
		||||
    public SongEditorDialog() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull Dialog onCreateDialog(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
 | 
			
		||||
        LayoutInflater inflater = LayoutInflater.from(getContext());
 | 
			
		||||
        View dialogView = inflater.inflate(R.layout.fragment_song_editor_dialog, null);
 | 
			
		||||
 | 
			
		||||
        dialogView.findViewById(R.id.btnCancel).setOnClickListener(v-> onCancel());
 | 
			
		||||
 | 
			
		||||
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
 | 
			
		||||
        builder.setCancelable(false);
 | 
			
		||||
        builder.setView(dialogView);
 | 
			
		||||
 | 
			
		||||
        dialog = builder.create();
 | 
			
		||||
        dialog.setCanceledOnTouchOutside(false);
 | 
			
		||||
        return dialog;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void onCancel() {
 | 
			
		||||
        dialog.dismiss();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void onSave() {
 | 
			
		||||
        String title = ((EditText) dialog.findViewById(R.id.etTitle)).getText().toString();
 | 
			
		||||
        String composer = ((EditText) dialog.findViewById(R.id.etComposer)).getText().toString();
 | 
			
		||||
        int releaseYear = Integer.parseInt(((EditText) dialog.findViewById(R.id.etYear)).getText().toString());
 | 
			
		||||
        String genre = ((EditText) dialog.findViewById(R.id.etGenre)).getText().toString();
 | 
			
		||||
 | 
			
		||||
        Song song = new Song(title, composer, genre, releaseYear);
 | 
			
		||||
 | 
			
		||||
        HomeViewModel homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class);
 | 
			
		||||
        homeViewModel.addSong(song);
 | 
			
		||||
 | 
			
		||||
        dialog.dismiss();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,49 @@
 | 
			
		||||
package com.stormtales.notevault.utils;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.media.ExifInterface;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class NoteSheetsUtil {
 | 
			
		||||
    private static long getImageTimestamp(Context context, Uri imageUri) {
 | 
			
		||||
        try  {
 | 
			
		||||
            InputStream inputStream = context.getContentResolver().openInputStream(imageUri);
 | 
			
		||||
            ExifInterface exif = new ExifInterface(inputStream);
 | 
			
		||||
 | 
			
		||||
            String dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
 | 
			
		||||
            if(dateTime != null) {
 | 
			
		||||
                SimpleDateFormat format = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.getDefault());
 | 
			
		||||
                Date date = format.parse(dateTime);
 | 
			
		||||
                return date != null ? date.getTime() : 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                File file = new File(imageUri.getPath());
 | 
			
		||||
                return file.lastModified();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException | ParseException e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sortNoteSheetsByTimestamp(Context context, Uri[] uris) {
 | 
			
		||||
        ArrayList<UriTimestamp> uriTimestamps = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        for(Uri uri : uris) {
 | 
			
		||||
            long timestamp = getImageTimestamp(context, uri);
 | 
			
		||||
            uriTimestamps.add(new UriTimestamp(uri, timestamp));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Collections.sort(uriTimestamps, Comparator.comparingLong(UriTimestamp::getTimestamp));
 | 
			
		||||
 | 
			
		||||
        for(int i=0; i<uriTimestamps.size(); i++) {
 | 
			
		||||
            uris[i] = uriTimestamps.get(i).getUri();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
package com.stormtales.notevault.utils;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
public class UriTimestamp {
 | 
			
		||||
    private final Uri uri;
 | 
			
		||||
    private final long timestamp;
 | 
			
		||||
 | 
			
		||||
    public UriTimestamp(Uri uri, long timestamp) {
 | 
			
		||||
        this.uri = uri;
 | 
			
		||||
        this.timestamp = timestamp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Uri getUri() {
 | 
			
		||||
        return uri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getTimestamp() {
 | 
			
		||||
        return timestamp;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -23,13 +23,4 @@
 | 
			
		||||
 | 
			
		||||
    <include layout="@layout/content_main"/>
 | 
			
		||||
 | 
			
		||||
    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
			
		||||
            android:id="@+id/fab"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_gravity="bottom|end"
 | 
			
		||||
            android:layout_marginEnd="@dimen/fab_margin"
 | 
			
		||||
            android:layout_marginBottom="16dp"
 | 
			
		||||
            app:srcCompat="@android:drawable/ic_dialog_email"/>
 | 
			
		||||
 | 
			
		||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
 | 
			
		||||
@ -7,6 +7,14 @@
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        tools:context=".ui.home.HomeFragment">
 | 
			
		||||
 | 
			
		||||
    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
			
		||||
            android:src="@android:drawable/ic_input_add"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:clickable="true" android:id="@+id/addSongBtn"
 | 
			
		||||
            app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
            android:layout_marginBottom="16dp" android:layout_marginEnd="16dp"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent" android:accessibilityPaneTitle="Add a Song"/>
 | 
			
		||||
    <TextView
 | 
			
		||||
            android:id="@+id/text_home"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										122
									
								
								app/src/main/res/layout/fragment_song_editor_dialog.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								app/src/main/res/layout/fragment_song_editor_dialog.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
              android:layout_width="match_parent"
 | 
			
		||||
              android:layout_height="wrap_content"
 | 
			
		||||
              android:orientation="vertical"
 | 
			
		||||
              android:padding="24dp"
 | 
			
		||||
              android:background="?android:attr/windowBackground">
 | 
			
		||||
 | 
			
		||||
    <!-- Titel des Songs -->
 | 
			
		||||
    <TextView
 | 
			
		||||
            android:id="@+id/tvTitle"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:text="Song Title"
 | 
			
		||||
            android:textSize="16sp"
 | 
			
		||||
            android:textColor="#000000"
 | 
			
		||||
            android:paddingBottom="8dp"
 | 
			
		||||
            android:fontFamily="sans-serif-medium"/>
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
            android:id="@+id/etTitle"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:hint="Enter Song Title"
 | 
			
		||||
            android:inputType="text"
 | 
			
		||||
            android:padding="12dp"
 | 
			
		||||
            android:layout_marginBottom="16dp"
 | 
			
		||||
            android:backgroundTint="@color/light_blue_600"/>
 | 
			
		||||
 | 
			
		||||
    <!-- Komponist -->
 | 
			
		||||
    <TextView
 | 
			
		||||
            android:id="@+id/tvComposer"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:text="Composer"
 | 
			
		||||
            android:textSize="16sp"
 | 
			
		||||
            android:textColor="#000000"
 | 
			
		||||
            android:paddingBottom="8dp"
 | 
			
		||||
            android:fontFamily="sans-serif-medium"/>
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
            android:id="@+id/etComposer"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:hint="Enter Composer"
 | 
			
		||||
            android:inputType="text"
 | 
			
		||||
            android:padding="12dp"
 | 
			
		||||
            android:layout_marginBottom="16dp"
 | 
			
		||||
            android:backgroundTint="@color/light_blue_600"/>
 | 
			
		||||
 | 
			
		||||
    <!-- Erscheinungsjahr -->
 | 
			
		||||
    <TextView
 | 
			
		||||
            android:id="@+id/tvYear"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:text="Release Year"
 | 
			
		||||
            android:textSize="16sp"
 | 
			
		||||
            android:textColor="#000000"
 | 
			
		||||
            android:paddingBottom="8dp"
 | 
			
		||||
            android:fontFamily="sans-serif-medium"/>
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
            android:id="@+id/etYear"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:hint="Enter Release Year"
 | 
			
		||||
            android:inputType="number"
 | 
			
		||||
            android:padding="12dp"
 | 
			
		||||
            android:layout_marginBottom="16dp"
 | 
			
		||||
            android:backgroundTint="@color/light_blue_600"/>
 | 
			
		||||
 | 
			
		||||
    <!-- Genre -->
 | 
			
		||||
    <TextView
 | 
			
		||||
            android:id="@+id/tvGenre"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:text="Genre"
 | 
			
		||||
            android:textSize="16sp"
 | 
			
		||||
            android:textColor="#000000"
 | 
			
		||||
            android:paddingBottom="8dp"
 | 
			
		||||
            android:fontFamily="sans-serif-medium"/>
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
            android:id="@+id/etGenre"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:hint="Enter Genre"
 | 
			
		||||
            android:inputType="text"
 | 
			
		||||
            android:padding="12dp"
 | 
			
		||||
            android:layout_marginBottom="16dp"
 | 
			
		||||
            android:backgroundTint="@color/light_blue_600"/>
 | 
			
		||||
 | 
			
		||||
    <!-- Buttons -->
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:orientation="horizontal"
 | 
			
		||||
            android:gravity="end">
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
                android:id="@+id/btnCancel"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:text="Cancel"
 | 
			
		||||
                android:layout_marginEnd="8dp"
 | 
			
		||||
                android:backgroundTint="@android:color/darker_gray"
 | 
			
		||||
                android:textColor="@android:color/white"
 | 
			
		||||
                android:paddingHorizontal="16dp"
 | 
			
		||||
                android:paddingVertical="8dp" />
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
                android:id="@+id/btnSave"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:text="Save"
 | 
			
		||||
                android:backgroundTint="@color/light_blue_600"
 | 
			
		||||
                android:textColor="@android:color/white"
 | 
			
		||||
                android:paddingHorizontal="16dp"
 | 
			
		||||
                android:paddingVertical="8dp" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@ -7,4 +7,8 @@
 | 
			
		||||
    <color name="teal_700">#FF018786</color>
 | 
			
		||||
    <color name="black">#FF000000</color>
 | 
			
		||||
    <color name="white">#FFFFFFFF</color>
 | 
			
		||||
    <color name="light_blue_400">#FF29B6F6</color>
 | 
			
		||||
    <color name="light_blue_600">#FF039BE5</color>
 | 
			
		||||
    <color name="gray_400">#FFBDBDBD</color>
 | 
			
		||||
    <color name="gray_600">#FF757575</color>
 | 
			
		||||
</resources>
 | 
			
		||||
@ -10,4 +10,6 @@
 | 
			
		||||
    <string name="menu_home">Home</string>
 | 
			
		||||
    <string name="menu_gallery">Gallery</string>
 | 
			
		||||
    <string name="menu_slideshow">Slideshow</string>
 | 
			
		||||
    <!-- TODO: Remove or change this placeholder text -->
 | 
			
		||||
    <string name="hello_blank_fragment">Hello blank fragment</string>
 | 
			
		||||
</resources>
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user