mirror of
https://github.com/antebudimir/tempus.git
synced 2026-01-02 02:13:33 +00:00
feat: edited the interface of top songs divided by week, month, and year
This commit is contained in:
parent
477331da6f
commit
f94e5892cd
7 changed files with 117 additions and 48 deletions
|
|
@ -15,7 +15,7 @@ public interface ChronologyDao {
|
||||||
@Query("SELECT * FROM chronology WHERE server == :server GROUP BY id ORDER BY timestamp DESC LIMIT :count")
|
@Query("SELECT * FROM chronology WHERE server == :server GROUP BY id ORDER BY timestamp DESC LIMIT :count")
|
||||||
LiveData<List<Chronology>> getLastPlayed(String server, int count);
|
LiveData<List<Chronology>> getLastPlayed(String server, int count);
|
||||||
|
|
||||||
@Query("SELECT * FROM chronology WHERE timestamp >= :startDate AND timestamp < :endDate AND server == :server GROUP BY id ORDER BY COUNT(id) DESC LIMIT 9")
|
@Query("SELECT * FROM chronology WHERE timestamp >= :endDate AND timestamp < :startDate AND server == :server GROUP BY id ORDER BY COUNT(id) DESC LIMIT 20")
|
||||||
LiveData<List<Chronology>> getAllFrom(long startDate, long endDate, String server);
|
LiveData<List<Chronology>> getAllFrom(long startDate, long endDate, String server);
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
|
|
||||||
|
|
@ -12,28 +12,8 @@ import java.util.List;
|
||||||
public class ChronologyRepository {
|
public class ChronologyRepository {
|
||||||
private final ChronologyDao chronologyDao = AppDatabase.getInstance().chronologyDao();
|
private final ChronologyDao chronologyDao = AppDatabase.getInstance().chronologyDao();
|
||||||
|
|
||||||
public LiveData<List<Chronology>> getThisWeek(String server) {
|
public LiveData<List<Chronology>> getChronology(String server, long start, long end) {
|
||||||
Calendar calendar = Calendar.getInstance();
|
return chronologyDao.getAllFrom(start, end, server);
|
||||||
|
|
||||||
Calendar first = (Calendar) calendar.clone();
|
|
||||||
first.add(Calendar.DAY_OF_WEEK, first.getFirstDayOfWeek() - first.get(Calendar.DAY_OF_WEEK));
|
|
||||||
|
|
||||||
Calendar last = (Calendar) first.clone();
|
|
||||||
last.add(Calendar.DAY_OF_YEAR, 6);
|
|
||||||
|
|
||||||
return chronologyDao.getAllFrom(first.getTime().getTime(), last.getTime().getTime(), server);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<Chronology>> getLastWeek(String server) {
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
|
|
||||||
Calendar first = (Calendar) calendar.clone();
|
|
||||||
first.add(Calendar.DAY_OF_WEEK, first.getFirstDayOfWeek() - first.get(Calendar.DAY_OF_WEEK) - 6);
|
|
||||||
|
|
||||||
Calendar last = (Calendar) first.clone();
|
|
||||||
last.add(Calendar.DAY_OF_YEAR, 6);
|
|
||||||
|
|
||||||
return chronologyDao.getAllFrom(first.getTime().getTime(), last.getTime().getTime(), server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert(Chronology item) {
|
public void insert(Chronology item) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import android.os.Handler;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.PopupMenu;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -29,7 +30,6 @@ import com.cappielloantonio.tempo.R;
|
||||||
import com.cappielloantonio.tempo.databinding.FragmentHomeTabMusicBinding;
|
import com.cappielloantonio.tempo.databinding.FragmentHomeTabMusicBinding;
|
||||||
import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper;
|
import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper;
|
||||||
import com.cappielloantonio.tempo.helper.recyclerview.DotsIndicatorDecoration;
|
import com.cappielloantonio.tempo.helper.recyclerview.DotsIndicatorDecoration;
|
||||||
import com.cappielloantonio.tempo.helper.recyclerview.GridItemDecoration;
|
|
||||||
import com.cappielloantonio.tempo.interfaces.ClickCallback;
|
import com.cappielloantonio.tempo.interfaces.ClickCallback;
|
||||||
import com.cappielloantonio.tempo.model.Download;
|
import com.cappielloantonio.tempo.model.Download;
|
||||||
import com.cappielloantonio.tempo.model.HomeSector;
|
import com.cappielloantonio.tempo.model.HomeSector;
|
||||||
|
|
@ -62,6 +62,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
|
|
@ -76,6 +77,7 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
private ArtistAdapter radioArtistAdapter;
|
private ArtistAdapter radioArtistAdapter;
|
||||||
private ArtistAdapter bestOfArtistAdapter;
|
private ArtistAdapter bestOfArtistAdapter;
|
||||||
private SongHorizontalAdapter starredSongAdapter;
|
private SongHorizontalAdapter starredSongAdapter;
|
||||||
|
private SongHorizontalAdapter topSongAdapter;
|
||||||
private AlbumHorizontalAdapter starredAlbumAdapter;
|
private AlbumHorizontalAdapter starredAlbumAdapter;
|
||||||
private ArtistHorizontalAdapter starredArtistAdapter;
|
private ArtistHorizontalAdapter starredArtistAdapter;
|
||||||
private AlbumAdapter recentlyAddedAlbumAdapter;
|
private AlbumAdapter recentlyAddedAlbumAdapter;
|
||||||
|
|
@ -119,7 +121,7 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
initNewReleasesView();
|
initNewReleasesView();
|
||||||
initYearSongView();
|
initYearSongView();
|
||||||
initRecentAddedAlbumView();
|
initRecentAddedAlbumView();
|
||||||
initGridView();
|
initTopSongsView();
|
||||||
initSharesView();
|
initSharesView();
|
||||||
initHomeReorganizer();
|
initHomeReorganizer();
|
||||||
|
|
||||||
|
|
@ -253,6 +255,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
homeViewModel.refreshShares(getViewLifecycleOwner());
|
homeViewModel.refreshShares(getViewLifecycleOwner());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bind.gridTracksPreTextView.setOnClickListener(view -> showPopupMenu(view, R.menu.filter_top_songs_popup_menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSyncStarredView() {
|
private void initSyncStarredView() {
|
||||||
|
|
@ -404,30 +408,41 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
artistRadioSnapHelper.attachToRecyclerView(bind.radioArtistRecyclerView);
|
artistRadioSnapHelper.attachToRecyclerView(bind.radioArtistRecyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initGridView() {
|
private void initTopSongsView() {
|
||||||
if (homeViewModel.checkHomeSectorVisibility(Constants.HOME_SECTOR_TOP_SONGS)) return;
|
if (homeViewModel.checkHomeSectorVisibility(Constants.HOME_SECTOR_TOP_SONGS)) return;
|
||||||
|
|
||||||
bind.gridTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3));
|
bind.topSongsRecyclerView.setHasFixedSize(true);
|
||||||
bind.gridTracksRecyclerView.addItemDecoration(new GridItemDecoration(3, 8, false));
|
|
||||||
bind.gridTracksRecyclerView.setHasFixedSize(true);
|
|
||||||
|
|
||||||
gridTrackAdapter = new GridTrackAdapter(this);
|
topSongAdapter = new SongHorizontalAdapter(this, true, false, null);
|
||||||
bind.gridTracksRecyclerView.setAdapter(gridTrackAdapter);
|
bind.topSongsRecyclerView.setAdapter(topSongAdapter);
|
||||||
|
homeViewModel.getChronologySample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), chronologies -> {
|
||||||
|
if (chronologies == null || chronologies.isEmpty()) {
|
||||||
|
if (bind != null) bind.homeGridTracksSector.setVisibility(View.GONE);
|
||||||
|
if (bind != null) bind.afterGridDivider.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
if (bind != null) bind.homeGridTracksSector.setVisibility(View.VISIBLE);
|
||||||
|
if (bind != null) bind.afterGridDivider.setVisibility(View.VISIBLE);
|
||||||
|
if (bind != null) bind.topSongsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(chronologies.size(), 5), GridLayoutManager.HORIZONTAL, false));
|
||||||
|
|
||||||
homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), music -> {
|
List<Child> topSongs = chronologies.stream()
|
||||||
if (music != null) {
|
.map(cronologia -> (Child) cronologia)
|
||||||
homeViewModel.getGridSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), chronologies -> {
|
.collect(Collectors.toList());
|
||||||
if (chronologies == null || chronologies.isEmpty()) {
|
|
||||||
if (bind != null) bind.homeGridTracksSector.setVisibility(View.GONE);
|
topSongAdapter.setItems(topSongs);
|
||||||
if (bind != null) bind.afterGridDivider.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
if (bind != null) bind.homeGridTracksSector.setVisibility(View.VISIBLE);
|
|
||||||
if (bind != null) bind.afterGridDivider.setVisibility(View.VISIBLE);
|
|
||||||
gridTrackAdapter.setItems(chronologies);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
SnapHelper topTrackSnapHelper = new PagerSnapHelper();
|
||||||
|
topTrackSnapHelper.attachToRecyclerView(bind.topSongsRecyclerView);
|
||||||
|
|
||||||
|
bind.topSongsRecyclerView.addItemDecoration(
|
||||||
|
new DotsIndicatorDecoration(
|
||||||
|
getResources().getDimensionPixelSize(R.dimen.radius),
|
||||||
|
getResources().getDimensionPixelSize(R.dimen.radius) * 4,
|
||||||
|
getResources().getDimensionPixelSize(R.dimen.dots_height),
|
||||||
|
requireContext().getResources().getColor(R.color.titleTextColor, null),
|
||||||
|
requireContext().getResources().getColor(R.color.titleTextColor, null))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initStarredTracksView() {
|
private void initStarredTracksView() {
|
||||||
|
|
@ -784,6 +799,31 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPopupMenu(View view, int menuResource) {
|
||||||
|
PopupMenu popup = new PopupMenu(requireContext(), view);
|
||||||
|
popup.getMenuInflater().inflate(menuResource, popup.getMenu());
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener(menuItem -> {
|
||||||
|
if (menuItem.getItemId() == R.id.menu_last_week_name) {
|
||||||
|
homeViewModel.changeChronologyPeriod(getViewLifecycleOwner(), 0);
|
||||||
|
bind.gridTracksPreTextView.setText(getString(R.string.home_title_last_week));
|
||||||
|
return true;
|
||||||
|
} else if (menuItem.getItemId() == R.id.menu_last_month_name) {
|
||||||
|
homeViewModel.changeChronologyPeriod(getViewLifecycleOwner(), 1);
|
||||||
|
bind.gridTracksPreTextView.setText(getString(R.string.home_title_last_month));
|
||||||
|
return true;
|
||||||
|
} else if (menuItem.getItemId() == R.id.menu_last_year_name) {
|
||||||
|
homeViewModel.changeChronologyPeriod(getViewLifecycleOwner(), 2);
|
||||||
|
bind.gridTracksPreTextView.setText(getString(R.string.home_title_last_year));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
popup.show();
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeMediaBrowser() {
|
private void initializeMediaBrowser() {
|
||||||
mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync();
|
mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,9 +91,17 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
return songRepository.getRandomSample(100, null, null);
|
return songRepository.getRandomSample(100, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Chronology>> getGridSongSample(LifecycleOwner owner) {
|
public LiveData<List<Chronology>> getChronologySample(LifecycleOwner owner) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
String server = Preferences.getServerId();
|
String server = Preferences.getServerId();
|
||||||
chronologyRepository.getLastWeek(server).observe(owner, thisGridTopSong::postValue);
|
|
||||||
|
int currentWeek = cal.get(Calendar.WEEK_OF_YEAR);
|
||||||
|
long start = cal.getTimeInMillis();
|
||||||
|
|
||||||
|
cal.set(Calendar.WEEK_OF_YEAR, currentWeek - 1);
|
||||||
|
long end = cal.getTimeInMillis();
|
||||||
|
|
||||||
|
chronologyRepository.getChronology(server, start, end).observe(owner, thisGridTopSong::postValue);
|
||||||
return thisGridTopSong;
|
return thisGridTopSong;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,6 +236,31 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
return songRepository.getStarredSongs(false, -1);
|
return songRepository.getStarredSongs(false, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changeChronologyPeriod(LifecycleOwner owner, int period) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
String server = Preferences.getServerId();
|
||||||
|
int currentWeek = cal.get(Calendar.WEEK_OF_YEAR);
|
||||||
|
|
||||||
|
long start = 0;
|
||||||
|
long end = 0;
|
||||||
|
|
||||||
|
if (period == 0) {
|
||||||
|
start = cal.getTimeInMillis();
|
||||||
|
cal.set(Calendar.WEEK_OF_YEAR, currentWeek - 1);
|
||||||
|
end = cal.getTimeInMillis();
|
||||||
|
} else if (period == 1) {
|
||||||
|
start = cal.getTimeInMillis();
|
||||||
|
cal.set(Calendar.WEEK_OF_YEAR, currentWeek - 4);
|
||||||
|
end = cal.getTimeInMillis();
|
||||||
|
} else if (period == 2) {
|
||||||
|
start = cal.getTimeInMillis();
|
||||||
|
cal.set(Calendar.WEEK_OF_YEAR, currentWeek - 52);
|
||||||
|
end = cal.getTimeInMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
chronologyRepository.getChronology(server, start, end).observe(owner, thisGridTopSong::postValue);
|
||||||
|
}
|
||||||
|
|
||||||
public void refreshDiscoverySongSample(LifecycleOwner owner) {
|
public void refreshDiscoverySongSample(LifecycleOwner owner) {
|
||||||
songRepository.getRandomSample(10, null, null).observe(owner, dicoverSongSample::postValue);
|
songRepository.getRandomSample(10, null, null).observe(owner, dicoverSongSample::postValue);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,16 +311,15 @@
|
||||||
android:text="@string/home_title_top_songs" />
|
android:text="@string/home_title_top_songs" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/grid_tracks_recycler_view"
|
android:id="@+id/top_songs_recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingBottom="8dp" />
|
android:paddingBottom="8dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|
|
||||||
12
app/src/main/res/menu/filter_top_songs_popup_menu.xml
Normal file
12
app/src/main/res/menu/filter_top_songs_popup_menu.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_last_week_name"
|
||||||
|
android:title="@string/menu_last_week_name" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_last_month_name"
|
||||||
|
android:title="@string/menu_last_month_name" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_last_year_name"
|
||||||
|
android:title="@string/menu_last_year_name" />
|
||||||
|
</menu>
|
||||||
|
|
@ -110,6 +110,8 @@
|
||||||
<string name="home_title_last_played">Last played</string>
|
<string name="home_title_last_played">Last played</string>
|
||||||
<string name="home_title_last_played_see_all_button">See all</string>
|
<string name="home_title_last_played_see_all_button">See all</string>
|
||||||
<string name="home_title_last_week">Last week</string>
|
<string name="home_title_last_week">Last week</string>
|
||||||
|
<string name="home_title_last_month">Last month</string>
|
||||||
|
<string name="home_title_last_year">Last year</string>
|
||||||
<string name="home_title_made_for_you">Made for you</string>
|
<string name="home_title_made_for_you">Made for you</string>
|
||||||
<string name="home_title_most_played">Most played</string>
|
<string name="home_title_most_played">Most played</string>
|
||||||
<string name="home_title_most_played_see_all_button">See all</string>
|
<string name="home_title_most_played_see_all_button">See all</string>
|
||||||
|
|
@ -155,6 +157,9 @@
|
||||||
<string name="menu_group_by_track">Track</string>
|
<string name="menu_group_by_track">Track</string>
|
||||||
<string name="menu_group_by_year">Year</string>
|
<string name="menu_group_by_year">Year</string>
|
||||||
<string name="menu_home_label">Home</string>
|
<string name="menu_home_label">Home</string>
|
||||||
|
<string name="menu_last_week_name">Last week</string>
|
||||||
|
<string name="menu_last_month_name">Last month</string>
|
||||||
|
<string name="menu_last_year_name">Last year</string>
|
||||||
<string name="menu_library_label">Library</string>
|
<string name="menu_library_label">Library</string>
|
||||||
<string name="menu_search_button">Search</string>
|
<string name="menu_search_button">Search</string>
|
||||||
<string name="menu_settings_button">Settings</string>
|
<string name="menu_settings_button">Settings</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue