diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/DiscoverSongAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/DiscoverSongAdapter.java index 98df9a48..c42bf0c4 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/DiscoverSongAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/DiscoverSongAdapter.java @@ -40,7 +40,7 @@ public class DiscoverSongAdapter extends PagerAdapter { @Override public Object instantiateItem(@NonNull ViewGroup container, final int position) { layoutInflater = LayoutInflater.from(context); - View view = layoutInflater.inflate(R.layout.item_discover_song, container, false); + View view = layoutInflater.inflate(R.layout.item_home_discover_song, container, false); TextView title; TextView desc; diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/RecentMusicAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/RecentMusicAdapter.java index 6b4958d2..85114d33 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/RecentMusicAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/RecentMusicAdapter.java @@ -1,7 +1,6 @@ package com.cappielloantonio.play.adapter; import android.content.Context; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,6 +13,9 @@ import com.cappielloantonio.play.model.Song; import java.util.List; +/** + * Adapter per i brani recenti in home + */ public class RecentMusicAdapter extends RecyclerView.Adapter { private static final String TAG = "RecentMusicAdapter"; private List songs; @@ -27,10 +29,9 @@ public class RecentMusicAdapter extends RecyclerView.Adapter { + private static final String TAG = "GenreAdapter"; + private List searches; + private LayoutInflater mInflater; + private Context context; + private ItemClickListener itemClickListener; + + public RecentSearchAdapter(Context context, List searches) { + this.context = context; + this.mInflater = LayoutInflater.from(context); + this.searches = searches; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = mInflater.inflate(R.layout.item_search_recent_searches, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + RecentSearch search = searches.get(position); + + holder.recentSearch.setText(search.getSearch()); + } + + @Override + public int getItemCount() { + return searches.size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + TextView recentSearch; + + ViewHolder(View itemView) { + super(itemView); + + recentSearch = itemView.findViewById(R.id.recent_search_text_view); + + itemView.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + if (itemClickListener != null) + itemClickListener.onItemClick(view, getAdapterPosition()); + } + } + + public void setItems(List searches) { + this.searches = searches; + notifyDataSetChanged(); + } + + public RecentSearch getItem(int id) { + return searches.get(id); + } + + public void setClickListener(ItemClickListener itemClickListener) { + this.itemClickListener = itemClickListener; + } + + public interface ItemClickListener { + void onItemClick(View view, int position); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/SongResultSearchAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/SongResultSearchAdapter.java new file mode 100644 index 00000000..27e9f8a5 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/adapter/SongResultSearchAdapter.java @@ -0,0 +1,91 @@ +package com.cappielloantonio.play.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.cappielloantonio.play.R; +import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.util.Util; + +import java.util.List; + +/** + * Adapter per i brani ritrovati nella ricerca + */ +public class SongResultSearchAdapter extends RecyclerView.Adapter { + private static final String TAG = "SongResultSearchAdapter"; + private List songs; + private LayoutInflater mInflater; + private Context context; + private ItemClickListener itemClickListener; + + public SongResultSearchAdapter(Context context, List songs) { + this.context = context; + this.mInflater = LayoutInflater.from(context); + this.songs = songs; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = mInflater.inflate(R.layout.item_search_result_song, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + Song song = songs.get(position); + + holder.songTitle.setText(song.getTitle()); + holder.songArtist.setText(song.getArtistName()); + holder.songDuration.setText(Util.getReadableDurationString(song.getDuration())); + } + + @Override + public int getItemCount() { + return songs.size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + TextView songTitle; + TextView songArtist; + TextView songDuration; + + ViewHolder(View itemView) { + super(itemView); + + songTitle = itemView.findViewById(R.id.search_result_song_title_text_view); + songArtist = itemView.findViewById(R.id.search_result_song_artist_text_view); + songDuration = itemView.findViewById(R.id.search_result_song_duration_text_view); + + itemView.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + if (itemClickListener != null) + itemClickListener.onItemClick(view, getAdapterPosition()); + } + } + + public void setItems(List songs) { + this.songs = songs; + notifyDataSetChanged(); + } + + public Song getItem(int id) { + return songs.get(id); + } + + public void setClickListener(ItemClickListener itemClickListener) { + this.itemClickListener = itemClickListener; + } + + public interface ItemClickListener { + void onItemClick(View view, int position); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java index 5221a51a..bd86daaa 100644 --- a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java +++ b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java @@ -10,14 +10,16 @@ import com.cappielloantonio.play.database.dao.AlbumDao; import com.cappielloantonio.play.database.dao.ArtistDao; import com.cappielloantonio.play.database.dao.GenreDao; import com.cappielloantonio.play.database.dao.PlaylistDao; +import com.cappielloantonio.play.database.dao.RecentSearchDao; import com.cappielloantonio.play.database.dao.SongDao; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Genre; import com.cappielloantonio.play.model.Playlist; +import com.cappielloantonio.play.model.RecentSearch; import com.cappielloantonio.play.model.Song; -@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class}, version = 2, exportSchema = false) +@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class}, version = 3, exportSchema = false) public abstract class AppDatabase extends RoomDatabase { private static final String TAG = "AppDatabase"; @@ -43,4 +45,6 @@ public abstract class AppDatabase extends RoomDatabase { public abstract PlaylistDao playlistDao(); public abstract SongDao songDao(); + + public abstract RecentSearchDao recentSearchDao(); } diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java new file mode 100644 index 00000000..c7076322 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java @@ -0,0 +1,24 @@ +package com.cappielloantonio.play.database.dao; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import com.cappielloantonio.play.model.RecentSearch; + +import java.util.List; + +@Dao +public interface RecentSearchDao { + @Query("SELECT * FROM recent_search GROUP BY search ORDER BY id DESC LIMIT :limit") + LiveData> getLast(int limit); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(RecentSearch search); + + @Query("DELETE FROM recent_search") + void deleteAll(); +} \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java index 038a1809..e2f178cc 100644 --- a/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java +++ b/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java @@ -16,6 +16,9 @@ public interface SongDao { @Query("SELECT * FROM song") LiveData> getAll(); + @Query("SELECT * FROM song WHERE title LIKE '%' || :title || '%'") + LiveData> searchSong(String title); + @Query("SELECT EXISTS(SELECT * FROM song WHERE id = :id)") boolean exist(String id); diff --git a/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java b/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java new file mode 100644 index 00000000..2380275b --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java @@ -0,0 +1,38 @@ +package com.cappielloantonio.play.model; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "recent_search") +public class RecentSearch { + @NonNull + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "id") + private int id; + + @ColumnInfo(name = "search") + private String search; + + public RecentSearch(String search) { + this.search = search; + } + + @NonNull + public int getId() { + return id; + } + + public void setId(@NonNull int id) { + this.id = id; + } + + public String getSearch() { + return search; + } + + public void setSearch(String search) { + this.search = search; + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/repository/RecentSearchRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/RecentSearchRepository.java new file mode 100644 index 00000000..a3d6f61d --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/repository/RecentSearchRepository.java @@ -0,0 +1,67 @@ +package com.cappielloantonio.play.repository; + +import android.app.Application; + +import androidx.lifecycle.LiveData; + +import com.cappielloantonio.play.database.AppDatabase; +import com.cappielloantonio.play.database.dao.RecentSearchDao; +import com.cappielloantonio.play.model.RecentSearch; + +import java.util.List; + +public class RecentSearchRepository { + private RecentSearchDao recentSearchDao; + private LiveData> listLiveRecentSearches; + + public RecentSearchRepository(Application application) { + AppDatabase database = AppDatabase.getInstance(application); + recentSearchDao = database.recentSearchDao(); + listLiveRecentSearches = recentSearchDao.getLast(3); + } + + public LiveData> getListLiveRecentSearches() { + return listLiveRecentSearches; + } + + public void insert(RecentSearch recentSearch) { + InsertThreadSafe insert = new InsertThreadSafe(recentSearchDao, recentSearch); + Thread thread = new Thread(insert); + thread.start(); + } + + public void deleteAll() { + DeleteAllThreadSafe delete = new DeleteAllThreadSafe(recentSearchDao); + Thread thread = new Thread(delete); + thread.start(); + } + + private static class InsertThreadSafe implements Runnable { + private RecentSearchDao recentSearchDao; + private RecentSearch recentSearch; + + public InsertThreadSafe(RecentSearchDao recentSearchDao, RecentSearch recentSearch) { + this.recentSearchDao = recentSearchDao; + this.recentSearch = recentSearch; + } + + @Override + public void run() { + recentSearchDao.insert(recentSearch); + } + } + + + private static class DeleteAllThreadSafe implements Runnable { + private RecentSearchDao recentSearchDao; + + public DeleteAllThreadSafe(RecentSearchDao recentSearchDao) { + this.recentSearchDao = recentSearchDao; + } + + @Override + public void run() { + recentSearchDao.deleteAll(); + } + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java index bdcf8272..13dc7d4c 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java @@ -14,17 +14,23 @@ import java.util.List; public class SongRepository { private SongDao songDao; private LiveData> listLiveSongs; + private LiveData> searchListLiveSongs; public SongRepository(Application application) { AppDatabase database = AppDatabase.getInstance(application); songDao = database.songDao(); - listLiveSongs = songDao.getAll(); } public LiveData> getListLiveSongs() { + listLiveSongs = songDao.getAll(); return listLiveSongs; } + public LiveData> searchListLiveSongs(String title) { + searchListLiveSongs = songDao.searchSong(title); + return searchListLiveSongs; + } + public boolean exist(Song song) { boolean exist = false; @@ -35,8 +41,7 @@ public class SongRepository { try { thread.join(); exist = existThread.exist(); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java new file mode 100644 index 00000000..50e15913 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java @@ -0,0 +1,62 @@ +package com.cappielloantonio.play.ui.fragment; + +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; + +import com.cappielloantonio.play.R; +import com.cappielloantonio.play.databinding.FragmentFilterBinding; +import com.cappielloantonio.play.model.Genre; +import com.cappielloantonio.play.ui.activities.MainActivity; +import com.cappielloantonio.play.viewmodel.SearchViewModel; +import com.google.android.material.chip.Chip; + +public class FilterFragment extends Fragment { + private static final String TAG = "FilterFragment"; + + private MainActivity activity; + private FragmentFilterBinding bind; + private SearchViewModel searchViewModel; + + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); + + bind = FragmentFilterBinding.inflate(inflater, container, false); + View view = bind.getRoot(); + searchViewModel = new ViewModelProvider(requireActivity()).get(SearchViewModel.class); + + setFilterChips(); + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind = null; + } + + private void setFilterChips() { + searchViewModel.getGenreList().observe(requireActivity(), genres -> { + bind.loadingProgressBar.setVisibility(View.GONE); + for (Genre genre : genres) { + Chip mChip = (Chip) requireActivity().getLayoutInflater().inflate(R.layout.chip_search_filter_genre, null, false); + mChip.setText(genre.getName()); + + mChip.setOnCheckedChangeListener((buttonView, isChecked) -> Toast.makeText(requireContext(), buttonView.getText() + ": " + isChecked, Toast.LENGTH_SHORT).show()); + + bind.filtersChipsGroup.addView(mChip); + } + }); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java index c608a3f5..871a2f55 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java @@ -1,31 +1,40 @@ package com.cappielloantonio.play.ui.fragment; -import android.app.Activity; -import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import com.cappielloantonio.play.R; +import com.cappielloantonio.play.adapter.RecentSearchAdapter; +import com.cappielloantonio.play.adapter.SongResultSearchAdapter; import com.cappielloantonio.play.databinding.FragmentSearchBinding; +import com.cappielloantonio.play.model.RecentSearch; +import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.ui.activities.MainActivity; -import com.paulrybitskyi.persistentsearchview.utils.VoiceRecognitionDelegate; +import com.cappielloantonio.play.viewmodel.SearchViewModel; + +import java.util.ArrayList; +import java.util.List; public class SearchFragment extends Fragment { private static final String TAG = "SearchFragment"; - public static final int REQUEST_CODE = 64545; private FragmentSearchBinding bind; private MainActivity activity; + private SearchViewModel searchViewModel; - protected LinearLayout emptyLinearLayout; - - protected String query = ""; + private RecentSearchAdapter recentSearchAdapter; + private SongResultSearchAdapter songResultSearchAdapter; @Nullable @Override @@ -34,8 +43,12 @@ public class SearchFragment extends Fragment { bind = FragmentSearchBinding.inflate(inflater, container, false); View view = bind.getRoot(); + searchViewModel = new ViewModelProvider(requireActivity()).get(SearchViewModel.class); - searchInit(); + init(); + initRecentSearchView(); + initSearchResultView(); + initSearchView(); return view; } @@ -46,23 +59,38 @@ public class SearchFragment extends Fragment { bind = null; } - @Override - public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (requestCode == REQUEST_CODE) { - if (resultCode == Activity.RESULT_OK) { - String code = data.getStringExtra("result"); - search(code); - } - } - - VoiceRecognitionDelegate.handleResult(bind.persistentSearchView, requestCode, resultCode, data); + private void init() { + bind.clearAllSearchTextViewClickable.setOnClickListener(v -> searchViewModel.deleteAllRecentSearch()); } - private void searchInit() { - bind.persistentSearchView.showRightButton(); + private void initRecentSearchView() { + bind.recentlySearchedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); + bind.recentlySearchedTracksRecyclerView.setHasFixedSize(true); + recentSearchAdapter = new RecentSearchAdapter(requireContext(), new ArrayList<>()); + recentSearchAdapter.setClickListener((view, position) -> { + RecentSearch search = recentSearchAdapter.getItem(position); + search(search.getSearch()); + }); + bind.recentlySearchedTracksRecyclerView.setAdapter(recentSearchAdapter); + + searchViewModel.getSearchList().observe(requireActivity(), recentSearches -> recentSearchAdapter.setItems(recentSearches)); + } + + private void initSearchResultView() { + bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); + bind.searchResultTracksRecyclerView.setHasFixedSize(true); + + songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), new ArrayList<>()); + songResultSearchAdapter.setClickListener((view, position) -> { + Toast.makeText(requireContext(), "Song " + position, Toast.LENGTH_SHORT).show(); + }); + bind.searchResultTracksRecyclerView.setAdapter(songResultSearchAdapter); + } + + private void initSearchView() { + bind.persistentSearchView.showRightButton(); + bind.persistentSearchView.setOnSearchQueryChangeListener((searchView, oldQuery, newQuery) -> { }); @@ -70,49 +98,25 @@ public class SearchFragment extends Fragment { }); bind.persistentSearchView.setOnRightBtnClickListener(view -> { + activity.navController.navigate(R.id.action_searchFragment_to_filterFragment); }); - bind.persistentSearchView.setVoiceRecognitionDelegate(new VoiceRecognitionDelegate(this)); - bind.persistentSearchView.setOnSearchConfirmedListener((searchView, query) -> { - if (!query.equals("")) { - searchView.collapse(); - search(query); - } + search(query); }); - - bind.persistentSearchView.setSuggestionsDisabled(true); } public void search(String query) { - emptyScreen(); - this.query = query; + if (!query.equals("")) { + searchViewModel.insertNewSearch(query); + bind.persistentSearchView.collapse(); - bind.persistentSearchView.setInputQuery(query); - performSearch(query); + bind.persistentSearchView.setInputQuery(query); + performSearch(query); + } } private void performSearch(String query) { - - } - - private void loadMoreItemSearch(String query, int page) { - manageProgressBar(true); - - } - - private void emptyScreen() { - emptyLinearLayout.setVisibility(View.GONE); - } - - - private void manageProgressBar(boolean show) { - if (show) { - bind.persistentSearchView.hideLeftButton(); - bind.persistentSearchView.showProgressBar(true); - } else { - bind.persistentSearchView.showLeftButton(); - bind.persistentSearchView.hideProgressBar(true); - } + searchViewModel.searchSong(query).observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs)); } } diff --git a/app/src/main/java/com/cappielloantonio/play/util/Util.java b/app/src/main/java/com/cappielloantonio/play/util/Util.java new file mode 100644 index 00000000..4cd32808 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/util/Util.java @@ -0,0 +1,18 @@ +package com.cappielloantonio.play.util; + +import java.util.Locale; + +public class Util { + public static String getReadableDurationString(long songDurationMillis) { + long minutes = (songDurationMillis / 1000) / 60; + long seconds = (songDurationMillis / 1000) % 60; + + if (minutes < 60) { + return String.format(Locale.getDefault(), "%01d:%02d", minutes, seconds); + } else { + long hours = minutes / 60; + minutes = minutes % 60; + return String.format(Locale.getDefault(), "%d:%02d:%02d", hours, minutes, seconds); + } + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/SearchViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/SearchViewModel.java new file mode 100644 index 00000000..43602035 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/SearchViewModel.java @@ -0,0 +1,57 @@ +package com.cappielloantonio.play.viewmodel; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; + +import com.cappielloantonio.play.model.Genre; +import com.cappielloantonio.play.model.RecentSearch; +import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.repository.GenreRepository; +import com.cappielloantonio.play.repository.RecentSearchRepository; +import com.cappielloantonio.play.repository.SongRepository; + +import java.util.List; + +public class SearchViewModel extends AndroidViewModel { + private SongRepository songRepository; + private GenreRepository genreRepository; + private RecentSearchRepository recentSearchRepository; + + private LiveData> searchSong; + private LiveData> allGenres; + private LiveData> recentSearches; + + public SearchViewModel(@NonNull Application application) { + super(application); + + songRepository = new SongRepository(application); + genreRepository = new GenreRepository(application); + recentSearchRepository = new RecentSearchRepository(application); + } + + public LiveData> searchSong(String title) { + searchSong = songRepository.searchListLiveSongs(title); + return searchSong; + } + + public LiveData> getGenreList() { + allGenres = genreRepository.getListLiveGenres(); + return allGenres; + } + + public LiveData> getSearchList() { + recentSearches = recentSearchRepository.getListLiveRecentSearches(); + return recentSearches; + } + + public void insertNewSearch(String search) { + recentSearchRepository.insert(new RecentSearch(search)); + } + + public void deleteAllRecentSearch() { + recentSearchRepository.deleteAll(); + } +} diff --git a/app/src/main/res/color/color_chip_status.xml b/app/src/main/res/color/color_chip_status.xml new file mode 100644 index 00000000..96c6dbf4 --- /dev/null +++ b/app/src/main/res/color/color_chip_status.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..1f6bb290 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..0d025f9b --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/chip_search_filter_genre.xml b/app/src/main/res/layout/chip_search_filter_genre.xml new file mode 100644 index 00000000..3fa21c23 --- /dev/null +++ b/app/src/main/res/layout/chip_search_filter_genre.xml @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_filter.xml b/app/src/main/res/layout/fragment_filter.xml new file mode 100644 index 00000000..f6f1450e --- /dev/null +++ b/app/src/main/res/layout/fragment_filter.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index e48530e9..c1056690 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -8,21 +8,19 @@ android:id="@+id/persistentSearchView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="4dp" - android:paddingLeft="4dp" - android:paddingTop="4dp" - android:paddingEnd="4dp" - android:paddingRight="4dp" + android:paddingStart="8dp" + android:paddingTop="8dp" + android:paddingEnd="8dp" app:areSuggestionsDisabled="true" app:cardBackgroundColor="@color/cardColor" app:cardCornerRadius="4dp" - app:cardElevation="2dp" + app:cardElevation="0dp" app:clearInputButtonDrawable="@drawable/ic_close" app:dividerColor="@color/dividerColor" app:isClearInputButtonEnabled="true" app:isDismissableOnTouchOutside="true" app:isProgressBarEnabled="true" - app:isVoiceInputButtonEnabled="true" + app:isVoiceInputButtonEnabled="false" app:leftButtonDrawable="@drawable/ic_search" app:progressBarColor="@color/colorAccent" app:queryInputBarIconColor="@color/darkIconColor" @@ -31,18 +29,98 @@ app:queryInputHintColor="@color/hintTextColor" app:queryInputTextColor="@color/hintTextColor" app:rightButtonDrawable="@drawable/ic_filter" - app:shouldDimBehind="true" /> + app:shouldDimBehind="false" /> - + android:layout_height="wrap_content" + android:layout_below="@id/persistentSearchView" + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_discover_song.xml b/app/src/main/res/layout/item_home_discover_song.xml similarity index 97% rename from app/src/main/res/layout/item_discover_song.xml rename to app/src/main/res/layout/item_home_discover_song.xml index d0fe0fb9..74d3b1d4 100644 --- a/app/src/main/res/layout/item_discover_song.xml +++ b/app/src/main/res/layout/item_home_discover_song.xml @@ -9,7 +9,7 @@ + android:layout_height="156dp"> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_result_song.xml b/app/src/main/res/layout/item_search_result_song.xml new file mode 100644 index 00000000..db030e54 --- /dev/null +++ b/app/src/main/res/layout/item_search_result_song.xml @@ -0,0 +1,68 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index a6ac0a9d..898f3ed5 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 00000000..dffca360 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 6bba2f5f..64ba76f7 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 00000000..dae5e082 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 93e13869..e5ed4659 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 00000000..14ed0af3 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 24a9a7f2..b0907cac 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..d8ae0315 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 9d33613a..2c18de9e 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..beed3cdd Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index ecd5b124..fc8a15a6 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -52,7 +52,7 @@ @@ -72,14 +72,24 @@ android:name="com.cappielloantonio.play.ui.fragment.LibraryFragment" android:label="LibraryFragment" tools:layout="@layout/fragment_library"/> - + + + + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index a455df34..f7d310eb 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -26,6 +26,7 @@ #CFCFCF #CFCFCF #121212 + #101010 #F3F3F3 #A0A0A0 @@ -33,5 +34,9 @@ #FFFFFF #EEEEEE #707070 + + #707070 + #444444 + #1D1D1D diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 5df8f573..1193f4b1 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -27,6 +27,7 @@ #303030 #303030 #EEEEEE + #EFEFEF #383838 #757575 @@ -34,4 +35,8 @@ #252525 #303030 #AFAFAF + + #AFAFAF + #EBEBEB + #FFFFFF \ No newline at end of file