Added all-songs feature
This commit is contained in:
@@ -789,7 +789,7 @@ public class AutomotiveRepository {
|
||||
|
||||
App.getSubsonicClientInstance(false)
|
||||
.getSearchingClient()
|
||||
.search3(query, 20, 20, 20)
|
||||
.search3(query, 20, 0, 20, 0, 20, 0)
|
||||
.enqueue(new Callback<ApiResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package com.cappielloantonio.tempo.repository;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
|
||||
import com.cappielloantonio.tempo.App;
|
||||
import com.cappielloantonio.tempo.R;
|
||||
import com.cappielloantonio.tempo.database.AppDatabase;
|
||||
import com.cappielloantonio.tempo.database.dao.RecentSearchDao;
|
||||
import com.cappielloantonio.tempo.model.RecentSearch;
|
||||
@@ -11,13 +16,18 @@ import com.cappielloantonio.tempo.subsonic.base.ApiResponse;
|
||||
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
|
||||
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Playlist;
|
||||
import com.cappielloantonio.tempo.subsonic.models.PlaylistWithSongs;
|
||||
import com.cappielloantonio.tempo.subsonic.models.SearchResult2;
|
||||
import com.cappielloantonio.tempo.subsonic.models.SearchResult3;
|
||||
import com.cappielloantonio.tempo.util.Preferences;
|
||||
import com.cappielloantonio.tempo.ui.fragment.SearchFragment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
@@ -31,7 +41,7 @@ public class SearchingRepository {
|
||||
|
||||
App.getSubsonicClientInstance(false)
|
||||
.getSearchingClient()
|
||||
.search3(query, 20, 20, 20)
|
||||
.search3(query, 20, 0, 20, 0, 20, 0)
|
||||
.enqueue(new Callback<ApiResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||
@@ -49,12 +59,63 @@ public class SearchingRepository {
|
||||
return result;
|
||||
}
|
||||
|
||||
public MutableLiveData<SearchResult3> search3(String query) {
|
||||
@UnstableApi
|
||||
public MutableLiveData<SearchResult3> search3(SearchFragment sf, String query) {
|
||||
MutableLiveData<SearchResult3> result = new MutableLiveData<>();
|
||||
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
List<Child> allSongs = new ArrayList<>();
|
||||
int offset = 0;
|
||||
int limit = 1000;
|
||||
boolean hasMore = true;
|
||||
|
||||
while (hasMore) {
|
||||
try {
|
||||
Response<ApiResponse> response = App.getSubsonicClientInstance(false)
|
||||
.getSearchingClient()
|
||||
.search3(query, limit, offset, 0, 0, 0, 0)
|
||||
.execute();
|
||||
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
SearchResult3 tmp = response.body().getSubsonicResponse().getSearchResult3();
|
||||
if (tmp != null && tmp.getSongs() != null && !tmp.getSongs().isEmpty()) {
|
||||
List<Child> fetchedSongs = tmp.getSongs();
|
||||
allSongs.addAll(fetchedSongs);
|
||||
|
||||
offset += fetchedSongs.size();
|
||||
hasMore = fetchedSongs.size() == limit;
|
||||
} else {
|
||||
hasMore = false;
|
||||
}
|
||||
} else {
|
||||
hasMore = false;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
PlaylistWithSongs pws = new PlaylistWithSongs("allsongs", allSongs);
|
||||
pws.setName(sf.getView().getContext().getString(R.string.search_all_songs, String.valueOf(allSongs.size())));
|
||||
pws.setSongCount(allSongs.size());
|
||||
List<Playlist> lpws = new ArrayList<>();
|
||||
lpws.add(pws);
|
||||
long duration = 0;
|
||||
for (Child song: allSongs) {
|
||||
if (song != null && song.getDuration() != null) {
|
||||
duration += song.getDuration();
|
||||
}
|
||||
}
|
||||
pws.setDuration(duration);
|
||||
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
sf.updateUI(lpws);
|
||||
});
|
||||
});
|
||||
|
||||
App.getSubsonicClientInstance(false)
|
||||
.getSearchingClient()
|
||||
.search3(query, 20, 20, 20)
|
||||
.search3(query, 20, 0, 20, 0, 20, 0)
|
||||
.enqueue(new Callback<ApiResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||
@@ -77,7 +138,7 @@ public class SearchingRepository {
|
||||
|
||||
App.getSubsonicClientInstance(false)
|
||||
.getSearchingClient()
|
||||
.search3(query, 5, 5, 5)
|
||||
.search3(query, 5, 0, 5, 0, 5, 0)
|
||||
.enqueue(new Callback<ApiResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||
|
||||
@@ -24,8 +24,8 @@ public class SearchingClient {
|
||||
return searchingService.search2(subsonic.getParams(), query, songCount, albumCount, artistCount);
|
||||
}
|
||||
|
||||
public Call<ApiResponse> search3(String query, int songCount, int albumCount, int artistCount) {
|
||||
public Call<ApiResponse> search3(String query, int songCount, int songOffset, int albumCount, int albumOffset, int artistCount, int artistOffset) {
|
||||
Log.d(TAG, "search3()");
|
||||
return searchingService.search3(subsonic.getParams(), query, songCount, albumCount, artistCount);
|
||||
return searchingService.search3(subsonic.getParams(), query, songCount, songOffset, albumCount, albumOffset, artistCount, artistOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,5 +14,5 @@ public interface SearchingService {
|
||||
Call<ApiResponse> search2(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("albumCount") int albumCount, @Query("artistCount") int artistCount);
|
||||
|
||||
@GET("search3")
|
||||
Call<ApiResponse> search3(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("albumCount") int albumCount, @Query("artistCount") int artistCount);
|
||||
Call<ApiResponse> search3(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("songOffset") int songOffset, @Query("albumCount") int albumCount, @Query("albumOffset") int albumOffset, @Query("artistCount") int artistCount, @Query("artistOffset") int artistOffset);
|
||||
}
|
||||
|
||||
@@ -26,16 +26,20 @@ import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper;
|
||||
import com.cappielloantonio.tempo.interfaces.ClickCallback;
|
||||
import com.cappielloantonio.tempo.service.MediaManager;
|
||||
import com.cappielloantonio.tempo.service.MediaService;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Playlist;
|
||||
import com.cappielloantonio.tempo.ui.activity.MainActivity;
|
||||
import com.cappielloantonio.tempo.ui.adapter.AlbumAdapter;
|
||||
import com.cappielloantonio.tempo.ui.adapter.ArtistAdapter;
|
||||
import com.cappielloantonio.tempo.ui.adapter.SongHorizontalAdapter;
|
||||
import com.cappielloantonio.tempo.ui.adapter.PlaylistHorizontalAdapter;
|
||||
import com.cappielloantonio.tempo.util.Constants;
|
||||
import com.cappielloantonio.tempo.viewmodel.PlaybackViewModel;
|
||||
import com.cappielloantonio.tempo.viewmodel.SearchViewModel;
|
||||
import com.cappielloantonio.tempo.subsonic.models.PlaylistWithSongs;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@UnstableApi
|
||||
public class SearchFragment extends Fragment implements ClickCallback {
|
||||
@@ -49,6 +53,7 @@ public class SearchFragment extends Fragment implements ClickCallback {
|
||||
private ArtistAdapter artistAdapter;
|
||||
private AlbumAdapter albumAdapter;
|
||||
private SongHorizontalAdapter songHorizontalAdapter;
|
||||
private PlaylistHorizontalAdapter playlistHorizontalAdapter;
|
||||
|
||||
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
|
||||
|
||||
@@ -126,6 +131,12 @@ public class SearchFragment extends Fragment implements ClickCallback {
|
||||
reapplyPlayback();
|
||||
|
||||
bind.searchResultTracksRecyclerView.setAdapter(songHorizontalAdapter);
|
||||
|
||||
bind.allsongsview.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.allsongsview.setHasFixedSize(true);
|
||||
|
||||
playlistHorizontalAdapter = new PlaylistHorizontalAdapter(this);
|
||||
bind.allsongsview.setAdapter(playlistHorizontalAdapter);
|
||||
}
|
||||
|
||||
private void initSearchView() {
|
||||
@@ -216,13 +227,23 @@ public class SearchFragment extends Fragment implements ClickCallback {
|
||||
|
||||
public void search(String query) {
|
||||
searchViewModel.setQuery(query);
|
||||
bind.allSongs.setText(this.getView().getContext().getString(R.string.search_all_songs_loading));
|
||||
playlistHorizontalAdapter.setItems(Collections.emptyList());
|
||||
bind.searchBar.setText(query);
|
||||
bind.searchView.hide();
|
||||
performSearch(query);
|
||||
}
|
||||
|
||||
public void updateUI(List<Playlist> allSongs) {
|
||||
if (!allSongs.isEmpty()) {
|
||||
playlistHorizontalAdapter.setItems(allSongs);
|
||||
} else {
|
||||
playlistHorizontalAdapter.setItems(Collections.emptyList());
|
||||
}
|
||||
bind.allSongs.setText(this.getView().getContext().getString(R.string.search_all_songs_play,String.valueOf(allSongs.getFirst().getName())));
|
||||
}
|
||||
private void performSearch(String query) {
|
||||
searchViewModel.search3(query).observe(getViewLifecycleOwner(), result -> {
|
||||
searchViewModel.search3(this, query).observe(getViewLifecycleOwner(), result -> {
|
||||
if (bind != null) {
|
||||
if (result.getArtists() != null) {
|
||||
bind.searchArtistSector.setVisibility(!result.getArtists().isEmpty() ? View.VISIBLE : View.GONE);
|
||||
@@ -281,6 +302,19 @@ public class SearchFragment extends Fragment implements ClickCallback {
|
||||
Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaylistClick(Bundle bundle) {
|
||||
PlaylistWithSongs playlistWithSongs = bundle.getParcelable(Constants.PLAYLIST_OBJECT);
|
||||
if (playlistWithSongs != null) {
|
||||
MediaManager.startQueue(mediaBrowserListenableFuture, playlistWithSongs.getEntries(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaylistLongClick(Bundle bundle) {
|
||||
Navigation.findNavController(requireView()).navigate(R.id.playlistBottomSheetDialog, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAlbumClick(Bundle bundle) {
|
||||
Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle);
|
||||
|
||||
@@ -299,4 +299,4 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||
homeViewModel.refreshShares(requireActivity());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.cappielloantonio.tempo.ui.fragment.bottomsheetdialog;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.session.MediaBrowser;
|
||||
import androidx.media3.session.SessionToken;
|
||||
|
||||
import com.cappielloantonio.tempo.R;
|
||||
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.tempo.service.MediaManager;
|
||||
import com.cappielloantonio.tempo.service.MediaService;
|
||||
import com.cappielloantonio.tempo.subsonic.models.PlaylistWithSongs;
|
||||
import com.cappielloantonio.tempo.ui.activity.MainActivity;
|
||||
import com.cappielloantonio.tempo.util.Constants;
|
||||
import com.cappielloantonio.tempo.util.MusicUtil;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
@UnstableApi
|
||||
public class PlaylistBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
|
||||
private PlaylistWithSongs playlist;
|
||||
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
|
||||
private static final String TAG = "PlaylistBottomSheetDialog";
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.bottom_sheet_playlist_dialog, container, false);
|
||||
|
||||
playlist = requireArguments().getParcelable(Constants.PLAYLIST_OBJECT);
|
||||
|
||||
init(view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
initializeMediaBrowser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
releaseMediaBrowser();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
private void init(View view) {
|
||||
ImageView coverPlaylist = view.findViewById(R.id.playlist_cover_image_view);
|
||||
|
||||
CustomGlideRequest.Builder
|
||||
.from(view.getContext(), playlist.getCoverArtId(), CustomGlideRequest.ResourceType.Playlist)
|
||||
.build()
|
||||
.into(coverPlaylist);
|
||||
|
||||
TextView titlePlaylist = view.findViewById(R.id.playlist_title_text_view);
|
||||
titlePlaylist.setText(playlist.getName());
|
||||
|
||||
titlePlaylist.setSelected(true);
|
||||
|
||||
TextView countPlaylist = view.findViewById(R.id.playlist_count_text_view);
|
||||
countPlaylist.setText(view.getContext().getString(R.string.playlist_counted_tracks, playlist.getSongCount(), MusicUtil.getReadableDurationString(playlist.getDuration(), false)));
|
||||
|
||||
TextView playNext = view.findViewById(R.id.play_next_text_view);
|
||||
playNext.setOnClickListener(v -> {
|
||||
MediaManager.enqueue(mediaBrowserListenableFuture, playlist.getEntries(), true);
|
||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
||||
dismissBottomSheet();
|
||||
});
|
||||
|
||||
TextView addToQueue = view.findViewById(R.id.add_to_queue_text_view);
|
||||
addToQueue.setOnClickListener(v -> {
|
||||
MediaManager.enqueue(mediaBrowserListenableFuture, playlist.getEntries(), false);
|
||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
||||
dismissBottomSheet();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismissBottomSheet();
|
||||
}
|
||||
|
||||
private void dismissBottomSheet() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void initializeMediaBrowser() {
|
||||
mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync();
|
||||
}
|
||||
|
||||
private void releaseMediaBrowser() {
|
||||
MediaBrowser.releaseFuture(mediaBrowserListenableFuture);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,11 +5,13 @@ import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
|
||||
import com.cappielloantonio.tempo.model.RecentSearch;
|
||||
import com.cappielloantonio.tempo.repository.SearchingRepository;
|
||||
import com.cappielloantonio.tempo.subsonic.models.SearchResult2;
|
||||
import com.cappielloantonio.tempo.subsonic.models.SearchResult3;
|
||||
import com.cappielloantonio.tempo.ui.fragment.SearchFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -43,8 +45,9 @@ public class SearchViewModel extends AndroidViewModel {
|
||||
return searchingRepository.search2(title);
|
||||
}
|
||||
|
||||
public LiveData<SearchResult3> search3(String title) {
|
||||
return searchingRepository.search3(title);
|
||||
@UnstableApi
|
||||
public LiveData<SearchResult3> search3(SearchFragment sf, String title) {
|
||||
return searchingRepository.search3(sf, title);
|
||||
}
|
||||
|
||||
public void insertNewSearch(String search) {
|
||||
|
||||
@@ -200,4 +200,4 @@
|
||||
android:text="@string/album_bottom_sheet_share"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -92,4 +92,4 @@
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/artist_bottom_sheet_shuffle" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
130
app/src/main/res/layout/bottom_sheet_playlist_dialog.xml
Normal file
130
app/src/main/res/layout/bottom_sheet_playlist_dialog.xml
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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:orientation="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:clipChildren="false">
|
||||
|
||||
<!-- Header -->
|
||||
<ImageView
|
||||
android:id="@+id/playlist_cover_image_view"
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="54dp"
|
||||
android:layout_margin="2dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/button_favorite"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/button_favorite_selector"
|
||||
android:checked="false"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center_vertical"
|
||||
android:text=""
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/playlist_title_text_view"
|
||||
style="@style/LabelMedium"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:ellipsize="marquee"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/label_placeholder"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_favorite"
|
||||
app:layout_constraintStart_toEndOf="@+id/playlist_cover_image_view"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/playlist_count_text_view"
|
||||
style="@style/LabelSmall"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/label_placeholder"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_favorite"
|
||||
app:layout_constraintStart_toEndOf="@+id/playlist_cover_image_view"
|
||||
app:layout_constraintTop_toBottomOf="@+id/playlist_title_text_view" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/song_asset_link_row"
|
||||
layout="@layout/view_asset_link_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="12dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/option_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="12dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/play_next_text_view"
|
||||
style="@style/LabelMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/song_bottom_sheet_play_next" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add_to_queue_text_view"
|
||||
style="@style/LabelMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/song_bottom_sheet_add_to_queue" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/share_text_view"
|
||||
style="@style/LabelMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/song_bottom_sheet_share"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -108,6 +108,22 @@
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/allSongs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="16dp"
|
||||
android:text="@string/search_all_songs_loading"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/allsongsview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
@@ -146,4 +162,4 @@
|
||||
android:orientation="vertical"/>
|
||||
</ScrollView>
|
||||
</com.google.android.material.search.SearchView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
@@ -225,4 +225,4 @@
|
||||
android:background="@drawable/ic_more_vert"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless" />
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -329,6 +329,11 @@
|
||||
android:name="com.cappielloantonio.tempo.ui.fragment.bottomsheetdialog.SongBottomSheetDialog"
|
||||
android:label="SongBottomSheetDialog"
|
||||
tools:layout="@layout/bottom_sheet_song_dialog" />
|
||||
<dialog
|
||||
android:id="@+id/playlistBottomSheetDialog"
|
||||
android:name="com.cappielloantonio.tempo.ui.fragment.bottomsheetdialog.PlaylistBottomSheetDialog"
|
||||
android:label="PlaylistBottomSheetDialog"
|
||||
tools:layout="@layout/bottom_sheet_playlist_dialog" />
|
||||
<dialog
|
||||
android:id="@+id/artistBottomSheetDialog"
|
||||
android:name="com.cappielloantonio.tempo.ui.fragment.bottomsheetdialog.ArtistBottomSheetDialog"
|
||||
|
||||
@@ -603,4 +603,7 @@
|
||||
|
||||
<string name="search_sort_title">Sort recent searches chronologically</string>
|
||||
<string name="search_sort_summary">If enabled, sort searches chronologically. Sort by name if disabled.</string>
|
||||
<string name="search_all_songs_loading">Getting all songs ...</string>
|
||||
<string name="search_all_songs">all %1$s songs</string>
|
||||
<string name="search_all_songs_play">Play %1$s</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user