Add experimental bottom sheet player

This commit is contained in:
Antonio Cappiello 2020-12-05 21:31:12 +01:00
parent 9af0afa441
commit f837bb14e2
65 changed files with 1570 additions and 547 deletions

View file

@ -36,6 +36,7 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
// Jellyfin
implementation 'com.github.jellyfin.jellyfin-apiclient-java:android:0.7.7'
@ -48,13 +49,14 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation "androidx.room:room-runtime:2.2.5"
implementation "androidx.cardview:cardview:1.0.0"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.paging:paging-runtime:2.1.2'
implementation 'androidx.paging:paging-runtime-ktx:2.1.2'
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
// Android Material
implementation 'com.google.android.material:material:1.2.1'
@ -72,7 +74,7 @@ dependencies {
// Glide
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation "com.github.woltapp:blurhash:f41a23cc50"
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
annotationProcessor "androidx.room:room-compiler:2.2.5"
testImplementation 'junit:junit:4.13.1'

View file

@ -0,0 +1,76 @@
package com.cappielloantonio.play.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.recyclerview.widget.RecyclerView;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.SongRepository;
import java.util.ArrayList;
import java.util.List;
public class PlayerNowPlayingSongAdapter extends RecyclerView.Adapter<PlayerNowPlayingSongAdapter.ViewHolder> {
private static final String TAG = "DiscoverSongAdapter";
private List<Song> songs;
private LayoutInflater inflater;
private Context context;
public PlayerNowPlayingSongAdapter(Context context) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.songs = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_player_now_playing_song, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Song song = songs.get(position);
CustomGlideRequest.Builder
.from(context, song.getPrimary(), song.getPrimary(), CustomGlideRequest.PRIMARY, CustomGlideRequest.TOP_QUALITY)
.build()
.into(holder.cover);
}
@Override
public int getItemCount() {
return songs.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView cover;
ViewHolder(View itemView) {
super(itemView);
cover = itemView.findViewById(R.id.discover_song_cover_image_view);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
SongRepository songRepository = new SongRepository(App.getInstance());
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
}
}
public void setItems(List<Song> songs) {
this.songs = songs;
notifyDataSetChanged();
}
}

View file

@ -0,0 +1,100 @@
package com.cappielloantonio.play.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activities.MainActivity;
import java.util.ArrayList;
import java.util.List;
/**
* Adapter per i brani ritrovati nella ricerca
*/
public class PlayerSongQueueAdapter extends RecyclerView.Adapter<PlayerSongQueueAdapter.ViewHolder> {
private static final String TAG = "SongResultSearchAdapter";
private List<Song> songs;
private LayoutInflater mInflater;
private MainActivity mainActivity;
private Context context;
private FragmentManager fragmentManager;
public PlayerSongQueueAdapter(MainActivity mainActivity, Context context, FragmentManager fragmentManager) {
this.mainActivity = mainActivity;
this.context = context;
this.fragmentManager = fragmentManager;
this.mInflater = LayoutInflater.from(context);
this.songs = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.item_player_queue_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());
CustomGlideRequest.Builder
.from(context, song.getPrimary(), song.getBlurHash(), CustomGlideRequest.PRIMARY, CustomGlideRequest.TOP_QUALITY)
.build()
.into(holder.cover);
}
@Override
public int getItemCount() {
return songs.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView songTitle;
TextView songArtist;
ImageView cover;
ViewHolder(View itemView) {
super(itemView);
songTitle = itemView.findViewById(R.id.queue_song_title_text_view);
songArtist = itemView.findViewById(R.id.queue_song_artist_text_view);
cover = itemView.findViewById(R.id.queue_song_cover_image_view);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
SongRepository songRepository = new SongRepository(App.getInstance());
QueueRepository queueRepository = new QueueRepository(App.getInstance());
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
}
}
public void setItems(List<Song> songs) {
this.songs = songs;
notifyDataSetChanged();
}
public Song getItem(int id) {
return songs.get(id);
}
}

View file

@ -16,7 +16,9 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activities.MainActivity;
import java.util.ArrayList;
import java.util.List;
@ -29,10 +31,12 @@ public class RecentMusicAdapter extends RecyclerView.Adapter<RecentMusicAdapter.
private List<Song> songs;
private LayoutInflater mInflater;
private MainActivity mainActivity;
private Context context;
private FragmentManager fragmentManager;
public RecentMusicAdapter(Context context, FragmentManager fragmentManager) {
public RecentMusicAdapter(MainActivity mainActivity, Context context, FragmentManager fragmentManager) {
this.mainActivity = mainActivity;
this.context = context;
this.fragmentManager = fragmentManager;
this.mInflater = LayoutInflater.from(context);
@ -82,7 +86,12 @@ public class RecentMusicAdapter extends RecyclerView.Adapter<RecentMusicAdapter.
@Override
public void onClick(View view) {
SongRepository songRepository = new SongRepository(App.getInstance());
QueueRepository queueRepository = new QueueRepository(App.getInstance());
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
queueRepository.insertAllAndStartNew(songs.subList(getAdapterPosition(), songs.size()));
mainActivity.isBottomSheetInPeek(true);
}
@Override

View file

@ -16,7 +16,9 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activities.MainActivity;
import com.cappielloantonio.play.util.Util;
import java.util.ArrayList;
@ -30,10 +32,12 @@ public class SongResultSearchAdapter extends RecyclerView.Adapter<SongResultSear
private List<Song> songs;
private LayoutInflater mInflater;
private MainActivity mainActivity;
private Context context;
private FragmentManager fragmentManager;
public SongResultSearchAdapter(Context context, FragmentManager fragmentManager) {
public SongResultSearchAdapter(MainActivity mainActivity, Context context, FragmentManager fragmentManager) {
this.mainActivity = mainActivity;
this.context = context;
this.fragmentManager = fragmentManager;
this.mInflater = LayoutInflater.from(context);
@ -86,7 +90,12 @@ public class SongResultSearchAdapter extends RecyclerView.Adapter<SongResultSear
@Override
public void onClick(View view) {
SongRepository songRepository = new SongRepository(App.getInstance());
QueueRepository queueRepository = new QueueRepository(App.getInstance());
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
queueRepository.insertAllAndStartNew(songs.subList(getAdapterPosition(), songs.size()));
mainActivity.isBottomSheetInPeek(true);
}
@Override
@ -106,5 +115,4 @@ public class SongResultSearchAdapter extends RecyclerView.Adapter<SongResultSear
public Song getItem(int id) {
return songs.get(id);
}
}

View file

@ -21,9 +21,9 @@ public class ConnectivityStatusBroadcastReceiver extends BroadcastReceiver {
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (noConnectivity) {
activity.activityMainBinding.offlineModeLinearLayout.setVisibility(View.VISIBLE);
activity.bind.offlineModeTextView.setVisibility(View.VISIBLE);
} else {
activity.activityMainBinding.offlineModeLinearLayout.setVisibility(View.GONE);
activity.bind.offlineModeTextView.setVisibility(View.GONE);
}
}
}

View file

@ -10,6 +10,7 @@ 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.QueueDao;
import com.cappielloantonio.play.database.dao.RecentSearchDao;
import com.cappielloantonio.play.database.dao.SongDao;
import com.cappielloantonio.play.database.dao.SongGenreCrossDao;
@ -17,11 +18,12 @@ 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.Queue;
import com.cappielloantonio.play.model.RecentSearch;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.model.SongGenreCross;
@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class}, version = 5, exportSchema = false)
@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class}, version = 6, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static final String TAG = "AppDatabase";
@ -51,4 +53,6 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract RecentSearchDao recentSearchDao();
public abstract SongGenreCrossDao songGenreCrossDao();
public abstract QueueDao queueDao();
}

View file

@ -0,0 +1,37 @@
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.Queue;
import com.cappielloantonio.play.model.Song;
import java.util.List;
@Dao
public interface QueueDao {
@Query("SELECT * FROM song JOIN queue ON song.id = queue.song_id")
LiveData<List<Song>> getAll();
@Query("SELECT * FROM song JOIN queue ON song.id = queue.song_id")
List<Song> getAllSimple();
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Queue songQueueObject);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<Queue> songQueueObject);
@Delete
void delete(Queue songQueueObject);
@Query("DELETE FROM queue")
void deleteAll();
@Query("SELECT COUNT(*) FROM queue;")
int count();
}

View file

@ -0,0 +1,44 @@
package com.cappielloantonio.play.model;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
@Entity(tableName = "queue")
public class Queue {
@NonNull
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
private int id;
@ColumnInfo(name = "song_id")
private String songID;
public Queue(@NonNull int id, String songID) {
this.id = id;
this.songID = songID;
}
@Ignore
public Queue(String songID) {
this.songID = songID;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSongID() {
return songID;
}
public void setSongID(String songID) {
this.songID = songID;
}
}

View file

@ -0,0 +1,197 @@
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.QueueDao;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.util.QueueUtil;
import java.util.ArrayList;
import java.util.List;
public class QueueRepository {
private static final String TAG = "QueueRepository";
private QueueDao queueDao;
private LiveData<List<Song>> listLiveQueue;
public QueueRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
queueDao = database.queueDao();
}
public LiveData<List<Song>> getLiveQueue() {
listLiveQueue = queueDao.getAll();
return listLiveQueue;
}
public List<Song> getSongs() {
List<Song> songs = new ArrayList<>();
GetSongsThreadSafe getSongs = new GetSongsThreadSafe(queueDao);
Thread thread = new Thread(getSongs);
thread.start();
try {
thread.join();
songs = getSongs.getSongs();
} catch (InterruptedException e) {
e.printStackTrace();
}
return songs;
}
public void insert(Song song) {
InsertThreadSafe insert = new InsertThreadSafe(queueDao, song);
Thread thread = new Thread(insert);
thread.start();
}
public void insertAll(List<Song> songs) {
InsertAllThreadSafe insertAll = new InsertAllThreadSafe(queueDao, songs);
Thread thread = new Thread(insertAll);
thread.start();
}
public void insertAllAndStartNew(List<Song> songs) {
try {
final Thread delete = new Thread(new DeleteAllThreadSafe(queueDao));
final Thread insertAll = new Thread(new InsertAllThreadSafe(queueDao, songs));
delete.start();
delete.join();
insertAll.start();
insertAll.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void delete(Queue queueElement) {
DeleteThreadSafe delete = new DeleteThreadSafe(queueDao, queueElement);
Thread thread = new Thread(delete);
thread.start();
}
public void deleteAll() {
DeleteAllThreadSafe delete = new DeleteAllThreadSafe(queueDao);
Thread thread = new Thread(delete);
thread.start();
}
public int count() {
int count = 0;
CountThreadSafe countThread = new CountThreadSafe(queueDao);
Thread thread = new Thread(countThread);
thread.start();
try {
thread.join();
count = countThread.getCount();
} catch (InterruptedException e) {
e.printStackTrace();
}
return count;
}
private static class InsertThreadSafe implements Runnable {
private QueueDao queueDao;
private Song song;
public InsertThreadSafe(QueueDao queueDao, Song song) {
this.queueDao = queueDao;
this.song = song;
}
@Override
public void run() {
queueDao.insert(QueueUtil.getQueueElementFromSong(song));
}
}
private static class InsertAllThreadSafe implements Runnable {
private QueueDao queueDao;
private List<Song> songs;
public InsertAllThreadSafe(QueueDao queueDao, List<Song> songs) {
this.queueDao = queueDao;
this.songs = songs;
}
@Override
public void run() {
queueDao.insertAll(QueueUtil.getQueueElementsFromSongs(songs));
}
}
private static class DeleteThreadSafe implements Runnable {
private QueueDao queueDao;
private Queue queueElement;
public DeleteThreadSafe(QueueDao queueDao, Queue queueElement) {
this.queueDao = queueDao;
this.queueElement = queueElement;
}
@Override
public void run() {
queueDao.delete(queueElement);
}
}
private static class DeleteAllThreadSafe implements Runnable {
private QueueDao queueDao;
public DeleteAllThreadSafe(QueueDao queueDao) {
this.queueDao = queueDao;
}
@Override
public void run() {
queueDao.deleteAll();
}
}
private static class CountThreadSafe implements Runnable {
private QueueDao queueDao;
private int count = 0;
public CountThreadSafe(QueueDao queueDao) {
this.queueDao = queueDao;
}
@Override
public void run() {
count = queueDao.count();
}
public int getCount() {
return count;
}
}
private static class GetSongsThreadSafe implements Runnable {
private QueueDao queueDao;
private List<Song> songs;
public GetSongsThreadSafe(QueueDao queueDao) {
this.queueDao = queueDao;
}
@Override
public void run() {
songs = queueDao.getAllSimple();
}
public List<Song> getSongs() {
return songs;
}
}
}

View file

@ -3,9 +3,12 @@ package com.cappielloantonio.play.ui.activities;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
@ -15,9 +18,12 @@ import com.cappielloantonio.play.R;
import com.cappielloantonio.play.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
import com.cappielloantonio.play.databinding.ActivityMainBinding;
import com.cappielloantonio.play.ui.activities.base.BaseActivity;
import com.cappielloantonio.play.ui.fragment.PlayerBottomSheetFragment;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.MainViewModel;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import org.jellyfin.apiclient.interaction.EmptyResponse;
import org.jellyfin.apiclient.interaction.Response;
@ -29,21 +35,27 @@ import java.util.Objects;
public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity";
public ActivityMainBinding activityMainBinding;
public ActivityMainBinding bind;
private MainViewModel mainViewModel;
private FragmentManager fragmentManager;
private NavHostFragment navHostFragment;
private BottomNavigationView bottomNavigationView;
public NavController navController;
private BottomSheetBehavior bottomSheetBehavior;
ConnectivityStatusBroadcastReceiver connectivityStatusBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
View view = activityMainBinding.getRoot();
bind = ActivityMainBinding.inflate(getLayoutInflater());
View view = bind.getRoot();
setContentView(view);
mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
connectivityStatusBroadcastReceiver = new ConnectivityStatusBroadcastReceiver(this);
connectivityStatusReceiverManager(true);
@ -58,11 +70,9 @@ public class MainActivity extends BaseActivity {
public void init() {
fragmentManager = getSupportFragmentManager();
bottomNavigationView = findViewById(R.id.bottom_navigation);
navHostFragment = (NavHostFragment) fragmentManager.findFragmentById(R.id.nav_host_fragment);
navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
initBottomSheet();
initNavigation();
if (PreferenceUtil.getInstance(this).getToken() != null) {
checkPreviousSession();
@ -71,6 +81,42 @@ public class MainActivity extends BaseActivity {
}
}
private void initBottomSheet() {
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.player_bottom_sheet));
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallback);
fragmentManager.beginTransaction().replace(R.id.player_bottom_sheet, new PlayerBottomSheetFragment(), "PlayerBottomSheet").commit();
isBottomSheetInPeek(mainViewModel.isQueueLoaded());
}
public void isBottomSheetInPeek(Boolean isVisible) {
Log.d(TAG, "isBottomSheetInPeek: " + isVisible);
if (isVisible) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} else {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
}
private void initNavigation() {
bottomNavigationView = findViewById(R.id.bottom_navigation);
navHostFragment = (NavHostFragment) fragmentManager.findFragmentById(R.id.nav_host_fragment);
navController = navHostFragment.getNavController();
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
if(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED && (
destination.getId() == R.id.homeFragment ||
destination.getId() == R.id.libraryFragment ||
destination.getId() == R.id.searchFragment ||
destination.getId() == R.id.settingsFragment)
) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
});
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
private void checkPreviousSession() {
App.getApiClientInstance(getApplicationContext()).ChangeServerLocation(PreferenceUtil.getInstance(this).getServer());
App.getApiClientInstance(getApplicationContext()).SetAuthenticationInfo(PreferenceUtil.getInstance(this).getToken(), PreferenceUtil.getInstance(this).getUser());
@ -94,8 +140,6 @@ public class MainActivity extends BaseActivity {
});
}
// True: VISIBLE
// False: GONE
public void setBottomNavigationBarVisibility(boolean visibility) {
if (visibility) {
bottomNavigationView.setVisibility(View.VISIBLE);
@ -104,13 +148,50 @@ public class MainActivity extends BaseActivity {
}
}
public void setBottomSheetVisibility(boolean visibility) {
if (visibility) {
findViewById(R.id.player_bottom_sheet).setVisibility(View.VISIBLE);
} else {
findViewById(R.id.player_bottom_sheet).setVisibility(View.GONE);
}
}
private BottomSheetBehavior.BottomSheetCallback bottomSheetCallback =
new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View view, int state) {
switch (state) {
case BottomSheetBehavior.STATE_COLLAPSED:
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
if(playerBottomSheetFragment == null) break;
playerBottomSheetFragment.scrollOnTop();
break;
case BottomSheetBehavior.STATE_HIDDEN:
mainViewModel.deleteQueue();
break;
}
}
@Override
public void onSlide(@NonNull View view, float slideOffset) {
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
if(playerBottomSheetFragment == null) return;
float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f;
playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset);
playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE);
}
};
public void goToLogin() {
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment)
navController.navigate(R.id.action_landingFragment_to_loginFragment);
}
public void goToSync() {
bottomNavigationView.setVisibility(View.GONE);
setBottomNavigationBarVisibility(false);
setBottomSheetVisibility(false);
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) {
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, false);
@ -145,12 +226,19 @@ public class MainActivity extends BaseActivity {
}
private void connectivityStatusReceiverManager(boolean isActive) {
if(isActive) {
if (isActive) {
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectivityStatusBroadcastReceiver, filter);
}
else {
} else {
unregisterReceiver(connectivityStatusBroadcastReceiver);
}
}
@Override
public void onBackPressed() {
if(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
else
super.onBackPressed();
}
}

View file

@ -1,14 +1,18 @@
package com.cappielloantonio.play.ui.fragment;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
import com.cappielloantonio.play.databinding.FragmentAlbumPageBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
@ -24,7 +28,14 @@ public class AlbumPageFragment extends Fragment {
private SongResultSearchAdapter songResultSearchAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initAppBar();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activity = (MainActivity) getActivity();
bind = FragmentAlbumPageBinding.inflate(inflater, container, false);
@ -50,6 +61,29 @@ public class AlbumPageFragment extends Fragment {
bind = null;
}
private void init() {
albumPageViewModel.setAlbum(getArguments().getParcelable("album_object"));
}
private void initAppBar() {
activity.setSupportActionBar(bind.animToolbar);
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
bind.collapsingToolbar.setTitle(albumPageViewModel.getAlbum().getTitle());
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
bind.collapsingToolbar.setCollapsedTitleTextColor(getResources().getColor(R.color.titleTextColor, null));
bind.appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
if ((bind.collapsingToolbar.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.collapsingToolbar))) {
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.titleTextColor, null), PorterDuff.Mode.SRC_ATOP);
} else {
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.white, null), PorterDuff.Mode.SRC_ATOP);
}
});
}
private void initBackCover() {
CustomGlideRequest.Builder
.from(requireContext(), albumPageViewModel.getAlbum().getPrimary(), albumPageViewModel.getAlbum().getBlurHash(), CustomGlideRequest.PRIMARY, CustomGlideRequest.TOP_QUALITY)
@ -57,17 +91,11 @@ public class AlbumPageFragment extends Fragment {
.into(bind.albumBackCoverImageView);
}
private void init() {
albumPageViewModel.setAlbum(getArguments().getParcelable("album_object"));
bind.albumTitleLabel.setText(albumPageViewModel.getAlbum().getTitle());
}
private void initSongsView() {
bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.songRecyclerView.setHasFixedSize(true);
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
bind.songRecyclerView.setAdapter(songResultSearchAdapter);
albumPageViewModel.getAlbumSongList().observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
}

View file

@ -1,10 +1,13 @@
package com.cappielloantonio.play.ui.fragment;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -27,6 +30,13 @@ public class ArtistPageFragment extends Fragment {
private SongResultSearchAdapter songResultSearchAdapter;
private AlbumArtistPageAdapter albumArtistPageAdapter;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initAppBar();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activity = (MainActivity) getActivity();
@ -58,7 +68,6 @@ public class ArtistPageFragment extends Fragment {
private void init() {
artistPageViewModel.setArtist(getArguments().getParcelable("artist_object"));
bind.artistNameLabel.setText(artistPageViewModel.getArtist().getName());
bind.mostStreamedSongTextViewClickable.setOnClickListener(v -> {
Bundle bundle = new Bundle();
@ -68,6 +77,24 @@ public class ArtistPageFragment extends Fragment {
});
}
private void initAppBar() {
activity.setSupportActionBar(bind.animToolbar);
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
bind.collapsingToolbar.setTitle(artistPageViewModel.getArtist().getName());
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
bind.collapsingToolbar.setCollapsedTitleTextColor(getResources().getColor(R.color.titleTextColor, null));
bind.appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
if ((bind.collapsingToolbar.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.collapsingToolbar))) {
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.titleTextColor, null), PorterDuff.Mode.SRC_ATOP);
} else {
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.white, null), PorterDuff.Mode.SRC_ATOP);
}
});
}
private void initBackdrop() {
CustomGlideRequest.Builder
.from(requireContext(), artistPageViewModel.getArtist().getBackdrop(), artistPageViewModel.getArtist().getBackdropBlurHash(), CustomGlideRequest.BACKDROP, CustomGlideRequest.TOP_QUALITY)
@ -77,16 +104,14 @@ public class ArtistPageFragment extends Fragment {
private void initTopSongsView() {
bind.mostStreamedSongRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.mostStreamedSongRecyclerView.setHasFixedSize(true);
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
bind.mostStreamedSongRecyclerView.setAdapter(songResultSearchAdapter);
artistPageViewModel.getArtistTopSongList().observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
}
private void initAlbumsView() {
bind.albumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
bind.albumsRecyclerView.setHasFixedSize(true);
albumArtistPageAdapter = new AlbumArtistPageAdapter(requireContext());
bind.albumsRecyclerView.setAdapter(albumArtistPageAdapter);

View file

@ -66,6 +66,7 @@ public class HomeFragment extends Fragment {
public void onStart() {
super.onStart();
activity.setBottomNavigationBarVisibility(true);
activity.setBottomSheetVisibility(true);
}
@Override
@ -123,14 +124,14 @@ public class HomeFragment extends Fragment {
discoverSongAdapter = new DiscoverSongAdapter(requireContext(), homeViewModel.getDiscoverSongList());
bind.discoverSongViewPager.setAdapter(discoverSongAdapter);
bind.discoverSongViewPager.setOffscreenPageLimit(3);
settDiscoverSongSlideViewOffset(20, 16);
setDiscoverSongSlideViewOffset(20, 16);
}
private void initRecentAddedSongView() {
bind.recentlyAddedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
bind.recentlyAddedTracksRecyclerView.setHasFixedSize(true);
recentlyAddedMusicAdapter = new RecentMusicAdapter(requireContext(), getChildFragmentManager());
recentlyAddedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
bind.recentlyAddedTracksRecyclerView.setAdapter(recentlyAddedMusicAdapter);
homeViewModel.getRecentlyAddedSongList().observe(requireActivity(), songs -> recentlyAddedMusicAdapter.setItems(songs));
}
@ -153,7 +154,7 @@ public class HomeFragment extends Fragment {
bind.favoritesTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 5, GridLayoutManager.HORIZONTAL, false));
bind.favoritesTracksRecyclerView.setHasFixedSize(true);
favoriteSongAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
favoriteSongAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
bind.favoritesTracksRecyclerView.setAdapter(favoriteSongAdapter);
homeViewModel.getFavorites().observe(requireActivity(), songs -> favoriteSongAdapter.setItems(songs));
@ -165,7 +166,7 @@ public class HomeFragment extends Fragment {
bind.mostPlayedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
bind.mostPlayedTracksRecyclerView.setHasFixedSize(true);
mostPlayedMusicAdapter = new RecentMusicAdapter(requireContext(), getChildFragmentManager());
mostPlayedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
bind.mostPlayedTracksRecyclerView.setAdapter(mostPlayedMusicAdapter);
homeViewModel.getMostPlayedSongList().observe(requireActivity(), songs -> mostPlayedMusicAdapter.setItems(songs));
}
@ -174,12 +175,12 @@ public class HomeFragment extends Fragment {
bind.recentlyPlayedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
bind.recentlyPlayedTracksRecyclerView.setHasFixedSize(true);
recentlyPlayedMusicAdapter = new RecentMusicAdapter(requireContext(), getChildFragmentManager());
recentlyPlayedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
bind.recentlyPlayedTracksRecyclerView.setAdapter(recentlyPlayedMusicAdapter);
homeViewModel.getRecentlyPlayedSongList().observe(requireActivity(), songs -> recentlyPlayedMusicAdapter.setItems(songs));
}
private void settDiscoverSongSlideViewOffset(float pageOffset, float pageMargin) {
private void setDiscoverSongSlideViewOffset(float pageOffset, float pageMargin) {
bind.discoverSongViewPager.setPageTransformer((page, position) -> {
float myOffset = position * -(2 * pageOffset + pageMargin);
if (bind.discoverSongViewPager.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) {

View file

@ -0,0 +1,113 @@
package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.viewpager2.widget.ViewPager2;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.PlayerNowPlayingSongAdapter;
import com.cappielloantonio.play.adapter.PlayerSongQueueAdapter;
import com.cappielloantonio.play.databinding.FragmentPlayerBottomSheetBinding;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.ui.activities.MainActivity;
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
public class PlayerBottomSheetFragment extends Fragment {
private static final String TAG = "PlayerBottomSheetFragment";
private FragmentPlayerBottomSheetBinding bind;
private MainActivity activity;
private PlayerBottomSheetViewModel playerBottomSheetViewModel;
private PlayerNowPlayingSongAdapter playerNowPlayingSongAdapter;
private PlayerSongQueueAdapter playerSongQueueAdapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
activity = (MainActivity) getActivity();
bind = FragmentPlayerBottomSheetBinding.inflate(inflater, container, false);
View view = bind.getRoot();
playerBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PlayerBottomSheetViewModel.class);
initQueueSlideView();
initQueueRecyclerView();
return view;
}
private void initQueueSlideView() {
bind.playerSongCoverViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
playerNowPlayingSongAdapter = new PlayerNowPlayingSongAdapter(requireContext());
bind.playerSongCoverViewPager.setAdapter(playerNowPlayingSongAdapter);
playerBottomSheetViewModel.getQueueSong().observe(requireActivity(), songs -> playerNowPlayingSongAdapter.setItems(songs));
bind.playerSongCoverViewPager.setOffscreenPageLimit(3);
setDiscoverSongSlideViewOffset(40, 4);
bind.playerSongCoverViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
playerBottomSheetViewModel.setNowPlayingSong(position);
}
});
playerBottomSheetViewModel.getNowPlayingSong().observe(requireActivity(), song -> {
if(song != null)
setSongInfo(song);
});
}
private void initQueueRecyclerView() {
bind.playerQueueRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.playerQueueRecyclerView.setHasFixedSize(true);
playerSongQueueAdapter = new PlayerSongQueueAdapter(activity, requireContext(), getChildFragmentManager());
bind.playerQueueRecyclerView.setAdapter(playerSongQueueAdapter);
playerBottomSheetViewModel.getQueueSong().observe(requireActivity(), songs -> playerSongQueueAdapter.setItems(songs));
}
private void setDiscoverSongSlideViewOffset(float pageOffset, float pageMargin) {
bind.playerSongCoverViewPager.setPageTransformer((page, position) -> {
float myOffset = position * -(2 * pageOffset + pageMargin);
if (bind.playerSongCoverViewPager.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) {
if (ViewCompat.getLayoutDirection(bind.playerSongCoverViewPager) == ViewCompat.LAYOUT_DIRECTION_RTL) {
page.setTranslationX(-myOffset);
} else {
page.setTranslationX(myOffset);
}
} else {
page.setTranslationY(myOffset);
}
});
}
private void setSongInfo(Song song) {
if(song != null) {
bind.playerSongTitleLabel.setText(song.getTitle());
bind.playerArtistNameLabel.setText(song.getArtistName());
}
}
public View getPlayerHeader() {
return getView().findViewById(R.id.player_header_layout);
}
public void scrollOnTop() {
bind.playerNestedScrollView.fullScroll(ScrollView.FOCUS_UP);
}
}

View file

@ -92,7 +92,7 @@ public class SearchFragment extends Fragment {
bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.searchResultTracksRecyclerView.setHasFixedSize(true);
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
bind.searchResultTracksRecyclerView.setAdapter(songResultSearchAdapter);
// Albums

View file

@ -93,7 +93,7 @@ public class SongListPageFragment extends Fragment {
bind.songListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.songListRecyclerView.setHasFixedSize(true);
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
bind.songListRecyclerView.setAdapter(songResultSearchAdapter);
songListPageViewModel.getSongList().observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
}

View file

@ -58,7 +58,7 @@ public class PreferenceUtil {
}
public String getToken() {
return mPreferences.getString(TOKEN, "");
return mPreferences.getString(TOKEN, null);
}
public void setToken(String token) {

View file

@ -0,0 +1,23 @@
package com.cappielloantonio.play.util;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.Song;
import java.util.ArrayList;
import java.util.List;
public class QueueUtil {
public static Queue getQueueElementFromSong(Song song) {
return new Queue(song.getId());
}
public static List<Queue> getQueueElementsFromSongs(List<Song> songs) {
List<Queue> queue = new ArrayList<>();
for(Song song: songs) {
queue.add(new Queue(song.getId()));
}
return queue;
}
}

View file

@ -1,5 +1,7 @@
package com.cappielloantonio.play.util;
import android.content.Context;
import java.util.Locale;
public class Util {
@ -15,4 +17,12 @@ public class Util {
return String.format(Locale.getDefault(), "%d:%02d:%02d", hours, minutes, seconds);
}
}
public static float dpFromPx(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float pxFromDp(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
}

View file

@ -0,0 +1,31 @@
package com.cappielloantonio.play.viewmodel;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import com.cappielloantonio.play.repository.QueueRepository;
public class MainViewModel extends AndroidViewModel {
private static final String TAG = "SearchViewModel";
private QueueRepository queueRepository;
public MainViewModel(@NonNull Application application) {
super(application);
queueRepository = new QueueRepository(application);
}
public boolean isQueueLoaded() {
if(queueRepository.count() == 0)
return false;
return true;
}
public void deleteQueue(){
queueRepository.deleteAll();
}
}

View file

@ -0,0 +1,48 @@
package com.cappielloantonio.play.viewmodel;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import java.util.List;
public class PlayerBottomSheetViewModel extends AndroidViewModel {
private static final String TAG = "HomeViewModel";
private QueueRepository queueRepository;
private LiveData<List<Song>> queueSong;
private LiveData<Song> nowPlayingSong = new MutableLiveData<>();
public PlayerBottomSheetViewModel(@NonNull Application application) {
super(application);
queueRepository = new QueueRepository(application);
queueSong = queueRepository.getLiveQueue();
}
public LiveData<List<Song>> getQueueSong() {
return queueSong;
}
public LiveData<Song> getNowPlayingSong() {
return nowPlayingSong;
}
public LiveData<Song> setNowPlayingSong(int position) {
Song song = queueRepository.getSongs().get(position);
if(song != null) {
nowPlayingSong = new MutableLiveData<>(song);
}
return nowPlayingSong;
}
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_thumb_up" android:state_checked="true" android:color="@color/titleTextColor"/>
<item android:drawable="@drawable/ic_thumb_up_outlined" android:state_checked="false" android:color="@color/titleTextColor" />
<item android:drawable="@drawable/ic_favorite" android:state_checked="true" android:color="@color/titleTextColor"/>
<item android:drawable="@drawable/ic_favorites_outlined" android:state_checked="false" android:color="@color/titleTextColor" />
</selector>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_play_circle" android:state_checked="true" android:color="@color/titleTextColor"/>
<item android:drawable="@drawable/ic_pause_circle" android:state_checked="false" android:color="@color/titleTextColor" />
</selector>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#00000000"
android:endColor="#FF000000"
android:angle="90"
android:dither="true" />
</shape>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M15.88,9.29L12,13.17 8.12,9.29c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41l4.59,4.59c0.39,0.39 1.02,0.39 1.41,0l4.59,-4.59c0.39,-0.39 0.39,-1.02 0,-1.41 -0.39,-0.38 -1.03,-0.39 -1.42,0z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/titleTextColor"
android:pathData="M19,9H5c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h14c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1zM5,15h14c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1H5c-0.55,0 -1,0.45 -1,1s0.45,1 1,1z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/titleTextColor"
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:fillColor="@color/titleTextColor"
android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M10,16c0.55,0 1,-0.45 1,-1L11,9c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v6c0,0.55 0.45,1 1,1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM14,16c0.55,0 1,-0.45 1,-1L15,9c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v6c0,0.55 0.45,1 1,1z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:fillColor="@color/titleTextColor"
android:pathData="M8,6.82v10.36c0,0.79 0.87,1.27 1.54,0.84l8.14,-5.18c0.62,-0.39 0.62,-1.29 0,-1.69L9.54,5.98C8.87,5.55 8,6.03 8,6.82z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M10.8,15.9l4.67,-3.5c0.27,-0.2 0.27,-0.6 0,-0.8L10.8,8.1c-0.33,-0.25 -0.8,-0.01 -0.8,0.4v7c0,0.41 0.47,0.65 0.8,0.4zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M7.58,16.89l5.77,-4.07c0.56,-0.4 0.56,-1.24 0,-1.63L7.58,7.11C6.91,6.65 6,7.12 6,7.93v8.14c0,0.81 0.91,1.28 1.58,0.82zM16,7v10c0,0.55 0.45,1 1,1s1,-0.45 1,-1V7c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M7,6c0.55,0 1,0.45 1,1v10c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1L6,7c0,-0.55 0.45,-1 1,-1zM10.66,12.82l5.77,4.07c0.66,0.47 1.58,-0.01 1.58,-0.82L18.01,7.93c0,-0.81 -0.91,-1.28 -1.58,-0.82l-5.77,4.07c-0.57,0.4 -0.57,1.24 0,1.64z"/>
</vector>

View file

@ -1,50 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:imeOptions="actionDone">
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
android:layout_height="0dp"
android:layout_weight="1">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
<FrameLayout
android:id="@+id/player_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:behavior_hideable="true"
app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
app:layout_behavior="@string/bottom_sheet_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/bottom_nav_shape"
android:elevation="2dp"
android:visibility="gone"
app:itemIconTint="@drawable/bottom_nav_selector"
app:labelVisibilityMode="unlabeled"
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:menu="@menu/bottom_nav_menu">
app:menu="@menu/bottom_nav_menu"/>
<LinearLayout
android:id="@+id/offline_mode_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:layout_gravity="bottom"
android:gravity="center"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="6dp"
android:text="Offline mode"/>
</LinearLayout>
</com.google.android.material.bottomnavigation.BottomNavigationView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<TextView
android:id="@+id/offline_mode_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="6dp"
android:text="Offline mode"
android:visibility="gone"/>
</LinearLayout>

View file

@ -3,8 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading_progress_bar"
@ -27,7 +26,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:paddingBottom="@dimen/global_padding_bottom">
<TextView
android:layout_width="match_parent"

View file

@ -1,91 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent">
<LinearLayout
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_height="@dimen/appbar_header_height"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:id="@+id/card_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:backgroundTint="@color/cardColor"
app:layout_constraintDimensionRatio="W, 4:5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:cardCornerRadius="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/album_back_cover_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_backdrop_background_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/album_title_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="4dp"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="32dp"
android:textAlignment="center"
android:textColor="@android:color/white"
android:textFontWeight="900"
android:textSize="40sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Label and button -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_font_family"
android:layout_marginTop="12dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="Songs"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/song_recycler_view"
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="@dimen/activity_margin_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/album_back_cover_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/appbar_header_height"
android:layout_gravity="top"
android:fitsSystemWindows="true"
android:background="@drawable/gradient_backdrop_background_image"/>
<androidx.appcompat.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:titleTextColor="@color/titleTextColor"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/song_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="18dp"
android:paddingBottom="@dimen/global_padding_bottom"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading_progress_bar"
@ -27,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:paddingBottom="@dimen/global_padding_bottom">
<TextView
android:layout_width="match_parent"

View file

@ -1,135 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent">
<LinearLayout
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/appbar_header_height"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="@dimen/activity_margin_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/artist_backdrop_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/appbar_header_height"
android:layout_gravity="top"
android:fitsSystemWindows="true"
android:background="@drawable/gradient_backdrop_background_image"/>
<androidx.appcompat.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:titleTextColor="@color/titleTextColor"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:fillViewport="true"
android:paddingBottom="@dimen/global_padding_bottom"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:id="@+id/card_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:backgroundTint="@color/cardColor"
app:layout_constraintDimensionRatio="W, 4:5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:cardCornerRadius="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/artist_backdrop_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_backdrop_background_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/artist_name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="4dp"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="32dp"
android:textAlignment="center"
android:textColor="@android:color/white"
android:textFontWeight="900"
android:textSize="40sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Label and button -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingEnd="8dp">
android:clipToPadding="false"
android:paddingTop="18dp"
android:orientation="vertical">
<!-- Label and button -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="16dp"
android:paddingEnd="8dp"
android:text="Most Streamed Songs"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:id="@+id/most_streamed_song_text_view_clickable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_font_family"
android:paddingEnd="16dp"
android:text="See all"
android:textColor="@color/subtitleTextColor"
android:textSize="14sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/most_streamed_song_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="16dp" />
<TextView
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:text="Most Streamed Songs"
android:paddingTop="8dp"
android:paddingStart="16dp"
android:paddingEnd="20dp"
android:text="Albums"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:id="@+id/most_streamed_song_text_view_clickable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="8dp"
android:paddingTop="12dp"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/albums_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:text="See all"
android:textColor="@color/subtitleTextColor"
android:textSize="14sp" />
android:paddingBottom="8dp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/most_streamed_song_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="16dp"
android:paddingTop="20dp"
android:paddingEnd="16dp"
android:text="Albums"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/albums_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:paddingBottom="8dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -3,8 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading_progress_bar"
@ -20,14 +19,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
android:visibility="gone"
android:paddingTop="8dp">
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:paddingBottom="@dimen/global_padding_bottom">
<LinearLayout
android:layout_width="match_parent"

View file

@ -3,8 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading_progress_bar"
@ -26,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:paddingBottom="@dimen/global_padding_bottom">
<!-- Label and button -->
<LinearLayout

View file

@ -9,14 +9,13 @@
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
android:paddingTop="20dp">
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:paddingBottom="@dimen/global_padding_bottom">
<!-- Discover music -->
<LinearLayout
@ -40,7 +39,7 @@
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/discover_song_view_pager"
android:layout_width="match_parent"
android:layout_height="188dp"
android:layout_height="212dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
@ -297,7 +296,7 @@
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:paddingBottom="24dp" />
android:paddingBottom="8dp" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -4,13 +4,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
android:paddingTop="20dp">
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:paddingBottom="@dimen/global_padding_bottom">
<LinearLayout
android:layout_width="match_parent"

View file

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/player_nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/cardColor"
app:elevation="8dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/player_header_layout"
layout="@layout/player_header_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_peek_height"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/player_big_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/collapse_bottom_sheet_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:text="Now playing"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/player_song_cover_view_pager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/collapse_bottom_sheet_button" />
<ProgressBar
android:id="@+id/player_big_progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="28dp"
android:layout_marginTop="18dp"
android:layout_marginEnd="28dp"
android:progress="50"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_song_cover_view_pager" />
<TextView
android:id="@+id/player_song_title_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:layout_marginTop="18dp"
android:text="@string/label_placeholder"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
<TextView
android:id="@+id/player_artist_name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:text="@string/label_placeholder"
android:textColor="@color/subtitleTextColor"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_song_title_label" />
<ToggleButton
android:id="@+id/button_favorite"
android:layout_width="26dp"
android:layout_height="26dp"
android:background="@drawable/button_favorite_selector"
android:checked="false"
android:gravity="center_vertical"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text=""
android:textOff=""
android:textOn=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
<View style="@style/Divider"
android:id="@+id/player_divider"
android:layout_marginTop="24dp"
android:layout_marginStart="18dp"
android:layout_marginEnd="18dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_artist_name_label"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/player_queue_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="18dp"
android:paddingBottom="@dimen/global_padding_bottom"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_divider"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -2,8 +2,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:layout_height="match_parent">
<com.paulrybitskyi.persistentsearchview.PersistentSearchView
android:id="@+id/persistentSearchView"
@ -100,7 +99,8 @@
android:id="@+id/search_result_nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
android:visibility="gone"
android:paddingBottom="@dimen/global_padding_bottom">
<!-- Search result -->
<LinearLayout

View file

@ -3,5 +3,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:paddingTop="20dp"
android:paddingBottom="@dimen/global_padding_bottom">
</RelativeLayout>

View file

@ -2,8 +2,7 @@
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp">
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
@ -32,6 +31,6 @@
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
android:paddingBottom="@dimen/global_padding_bottom"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -2,8 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp">
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading_progress_bar"

View file

@ -13,16 +13,16 @@
<ImageView
android:id="@+id/discover_song_cover_image_view"
android:layout_width="match_parent"
android:layout_height="172dp" />
android:layout_height="196dp" />
<View
android:layout_width="match_parent"
android:layout_height="172dp"
android:layout_height="196dp"
android:background="@drawable/gradient_discover_background_image" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="172dp">
android:layout_height="196dp">
<TextView
android:id="@+id/title_discover_song_label"

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingEnd="8dp">

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingEnd="8dp">

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="8dp"
android:backgroundTint="@color/cardColor"
app:cardCornerRadius="4dp">
<ImageView
android:id="@+id/discover_song_cover_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="?attr/selectableItemBackground"/>
</androidx.cardview.widget.CardView>

View file

@ -0,0 +1,80 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="3dp"
android:paddingEnd="24dp"
android:paddingBottom="3dp"
android:background="?attr/selectableItemBackground">
<androidx.cardview.widget.CardView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="2dp"
android:backgroundTint="@color/cardColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/subtitleTextColor"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="2dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="false">
<ImageView
android:id="@+id/queue_song_cover_image_view"
android:layout_width="52dp"
android:layout_height="52dp" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1">
<TextView
android:id="@+id/queue_song_title_text_view"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ellipsize="end"
android:fontFamily="@font/open_sans_font_family"
android:maxLines="1"
android:paddingStart="12dp"
android:paddingTop="10dp"
android:paddingEnd="12dp"
android:text="@string/label_placeholder"
android:textColor="@color/titleTextColor"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/queue_song_artist_text_view"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="12dp"
android:text="@string/label_placeholder"
android:textColor="@color/subtitleTextColor"
android:textSize="12sp" />
</LinearLayout>
<ImageView
android:id="@+id/queue_song_dragger_image"
android:layout_width="36dp"
android:layout_height="match_parent"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:gravity="center_vertical"
android:src="@drawable/ic_drag_handle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/player_big_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/collapse_bottom_sheet_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:paddingStart="20dp"
android:paddingTop="20dp"
android:text="Now playing"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/player_song_cover_view_pager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/collapse_bottom_sheet_button" />
<ProgressBar
android:id="@+id/player_big_progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="20dp"
android:layout_marginTop="18dp"
android:layout_marginEnd="20dp"
android:progress="50"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_song_cover_view_pager" />
<TextView
android:id="@+id/player_song_title_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:layout_marginTop="18dp"
android:text="@string/label_placeholder"
android:textColor="@color/titleTextColor"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
<TextView
android:id="@+id/player_artist_name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:text="@string/label_placeholder"
android:textColor="@color/subtitleTextColor"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_song_title_label" />
<ToggleButton
android:id="@+id/button_favorite"
android:layout_width="26dp"
android:layout_height="26dp"
android:background="@drawable/button_favorite_selector"
android:checked="false"
android:gravity="center_vertical"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:text=""
android:textOff=""
android:textOn=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_peek_height"
android:elevation="2dp"
android:background="@color/almostCardColor">
<ImageView
android:id="@+id/player_header_button"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="20dp"
android:src="@drawable/ic_play"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/player_header_song_title_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintStart_toEndOf="@+id/player_header_button"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/label_placeholder"
android:paddingStart="12dp"
android:textColor="@color/titleTextColor"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_header_song_artist_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_font_family"
android:paddingStart="12dp"
android:textColor="@color/subtitleTextColor"
android:textSize="12sp"
android:text="@string/label_placeholder"
app:layout_constraintStart_toEndOf="@+id/player_header_button"
app:layout_constraintTop_toBottomOf="@+id/player_header_song_title_label" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/landingFragment">
<fragment
android:id="@+id/landingFragment"
android:name="com.cappielloantonio.play.ui.fragment.LandingFragment"
android:label="fragment_landing"
tools:layout="@layout/fragment_landing" >
<action
android:id="@+id/action_landingFragment_to_loginFragment"
app:destination="@id/loginFragment"
app:popUpTo="@id/landingFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_landingFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@id/landingFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_landingFragment_to_syncFragment"
app:destination="@id/syncFragment"
app:popUpTo="@id/landingFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/loginFragment"
android:name="com.cappielloantonio.play.ui.fragment.LoginFragment"
android:label="LoginFragment"
tools:layout="@layout/fragment_login">
<action
android:id="@+id/action_loginFragment_to_syncFragment"
app:destination="@id/syncFragment"
app:popUpTo="@id/loginFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_loginFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@id/loginFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/syncFragment"
android:name="com.cappielloantonio.play.ui.fragment.SyncFragment"
android:label="SyncFragment"
tools:layout="@layout/fragment_sync">
<action
android:id="@+id/action_syncFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@id/syncFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/homeFragment"
android:name="com.cappielloantonio.play.ui.fragment.HomeFragment"
android:label="HomeFragment"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/action_homeFragment_to_syncFragment"
app:destination="@id/syncFragment" />
<action
android:id="@+id/action_homeFragment_to_songListPageFragment"
app:destination="@id/songListPageFragment" />
</fragment>
<fragment
android:id="@+id/songListPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.SongListPageFragment"
android:label="SongListPageFragment"
tools:layout="@layout/fragment_song_list_page"/>
</navigation>

View file

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph">
<fragment
android:id="@+id/libraryFragment"
android:name="com.cappielloantonio.play.ui.fragment.LibraryFragment"
android:label="LibraryFragment"
tools:layout="@layout/fragment_library">
<action
android:id="@+id/action_libraryFragment_to_artistCatalogueFragment"
app:destination="@id/artistCatalogueFragment" />
<action
android:id="@+id/action_libraryFragment_to_albumCatalogueFragment"
app:destination="@id/albumCatalogueFragment" />
<action
android:id="@+id/action_libraryFragment_to_genreCatalogueFragment"
app:destination="@id/genreCatalogueFragment" />
<action
android:id="@+id/action_libraryFragment_to_artistPageFragment"
app:destination="@id/artistPageFragment"/>
<action
android:id="@+id/action_libraryFragment_to_albumPageFragment"
app:destination="@id/albumPageFragment" />
<action
android:id="@+id/action_libraryFragment_to_songListPageFragment"
app:destination="@id/songListPageFragment" />
</fragment>
<fragment
android:id="@+id/artistCatalogueFragment"
android:name="com.cappielloantonio.play.ui.fragment.ArtistCatalogueFragment"
android:label="ArtistCatalogueFragment"
tools:layout="@layout/fragment_artist_catalogue">
<action
android:id="@+id/action_artistCatalogueFragment_to_artistPageFragment"
app:destination="@id/artistPageFragment"/>
</fragment>
<fragment
android:id="@+id/albumCatalogueFragment"
android:name="com.cappielloantonio.play.ui.fragment.AlbumCatalogueFragment"
android:label="AlbumCatalogueFragment"
tools:layout="@layout/fragment_album_catalogue">
<action
android:id="@+id/action_albumCatalogueFragment_to_albumPageFragment"
app:destination="@id/albumPageFragment" />
</fragment>
<fragment
android:id="@+id/genreCatalogueFragment"
android:name="com.cappielloantonio.play.ui.fragment.GenreCatalogueFragment"
android:label="GenreCatalogueFragment"
tools:layout="@layout/fragment_genre_catalogue">
<action
android:id="@+id/action_genreCatalogueFragment_to_songListPageFragment"
app:destination="@id/songListPageFragment" />
</fragment>
<fragment
android:id="@+id/artistPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.ArtistPageFragment"
android:label="ArtistPageFragment"
tools:layout="@layout/fragment_artist_page">
<action
android:id="@+id/action_artistPageFragment_to_albumPageFragment"
app:destination="@id/albumPageFragment" />
<action
android:id="@+id/action_artistPageFragment_to_songListPageFragment"
app:destination="@id/songListPageFragment" />
</fragment>
<fragment
android:id="@+id/albumPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.AlbumPageFragment"
android:label="AlbumPageFragment"
tools:layout="@layout/fragment_album_page"/>
<fragment
android:id="@+id/songListPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.SongListPageFragment"
android:label="SongListPageFragment"
tools:layout="@layout/fragment_song_list_page"/>
</navigation>

View file

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph">
<fragment
android:id="@+id/searchFragment"
android:name="com.cappielloantonio.play.ui.fragment.SearchFragment"
android:label="SearchFragment"
tools:layout="@layout/fragment_search">
<action
android:id="@+id/action_searchFragment_to_filterFragment"
app:destination="@id/filterFragment" />
<action
android:id="@+id/action_searchFragment_to_artistPageFragment"
app:destination="@id/artistPageFragment"/>
<action
android:id="@+id/action_searchFragment_to_albumPageFragment"
app:destination="@id/albumPageFragment" />
</fragment>
<fragment
android:id="@+id/filterFragment"
android:name="com.cappielloantonio.play.ui.fragment.FilterFragment"
android:label="FilterFragment"
tools:layout="@layout/fragment_filter" />
<fragment
android:id="@+id/artistPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.ArtistPageFragment"
android:label="ArtistPageFragment"
tools:layout="@layout/fragment_artist_page">
<action
android:id="@+id/action_artistPageFragment_to_albumPageFragment"
app:destination="@id/albumPageFragment" />
<action
android:id="@+id/action_artistPageFragment_to_songListPageFragment"
app:destination="@id/songListPageFragment" />
</fragment>
<fragment
android:id="@+id/albumPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.AlbumPageFragment"
android:label="AlbumPageFragment"
tools:layout="@layout/fragment_album_page"/>
<fragment
android:id="@+id/songListPageFragment"
android:name="com.cappielloantonio.play.ui.fragment.SongListPageFragment"
android:label="SongListPageFragment"
tools:layout="@layout/fragment_song_list_page"/>
</navigation>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph">
<fragment
android:id="@+id/settingsFragment"
android:name="com.cappielloantonio.play.ui.fragment.SettingsFragment"
android:label="SettingsFragment"
tools:layout="@layout/fragment_settings"/>
</navigation>

View file

@ -11,6 +11,7 @@
<color name="navigationDrawerColor">#121211</color>
<color name="cardColor">#1D1D1D</color>
<color name="almostCardColor">#1D1D1C</color>
<color name="titleTextColor">#DADADA</color>
<color name="subtitleTextColor">#9B9B9B</color>

View file

@ -22,4 +22,10 @@
<item name="android:windowMinWidthMajor">82%</item>
<item name="android:windowMinWidthMinor">82%</item>
</style>
<style name="Divider">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item>
<item name="android:background">@color/dividerColor</item>
</style>
</resources>

View file

@ -14,6 +14,7 @@
<color name="navigationDrawerColor">#FFFFFF</color>
<color name="cardColor">#FFFFFF</color>
<color name="almostCardColor">#FFFFFE</color>
<color name="titleTextColor">#252525</color>
<color name="subtitleTextColor">#646464</color>
@ -41,4 +42,6 @@
<color name="chipBorderColor">#AFAFAF</color>
<color name="chipSelectedBackgroundColor">#EBEBEB</color>
<color name="chipUnelectedBackgroundColor">#FFFFFF</color>
<color name="white">#FFFFFF</color>
</resources>

View file

@ -5,4 +5,11 @@
<dimen name="nav_header_vertical_spacing">8dp</dimen>
<dimen name="nav_header_height">176dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="appbar_header_height">384dp</dimen>
<dimen name="activity_margin_content">24dp</dimen>
<dimen name="bottom_sheet_peek_height">56dp</dimen>
<dimen name="global_padding_bottom">64dp</dimen>
</resources>

View file

@ -21,4 +21,10 @@
<item name="android:windowMinWidthMajor">82%</item>
<item name="android:windowMinWidthMinor">82%</item>
</style>
<style name="Divider">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item>
<item name="android:background">@color/dividerColor</item>
</style>
</resources>