mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Added playlist creator and editor
This commit is contained in:
parent
00b85e5bc2
commit
d2092f5239
14 changed files with 589 additions and 1 deletions
6
.idea/misc.xml
generated
6
.idea/misc.xml
generated
|
|
@ -20,10 +20,12 @@
|
||||||
<entry key="app/src/main/res/drawable/ic_star.xml" value="0.2722222222222222" />
|
<entry key="app/src/main/res/drawable/ic_star.xml" value="0.2722222222222222" />
|
||||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/activity_main.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/bottom_sheet_song_dialog.xml" value="0.21666666666666667" />
|
<entry key="app/src/main/res/layout/bottom_sheet_song_dialog.xml" value="0.21666666666666667" />
|
||||||
|
<entry key="app/src/main/res/layout/dialog_playlist_chooser.xml" value="0.3229166666666667" />
|
||||||
|
<entry key="app/src/main/res/layout/dialog_playlist_creator.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/dialog_rating.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/dialog_rating.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/dialog_server_signup.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/dialog_server_signup.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/fragment_album_catalogue.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/fragment_album_catalogue.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/fragment_album_page.xml" value="0.1" />
|
<entry key="app/src/main/res/layout/fragment_album_page.xml" value="0.8" />
|
||||||
<entry key="app/src/main/res/layout/fragment_artist_page.xml" value="0.1" />
|
<entry key="app/src/main/res/layout/fragment_artist_page.xml" value="0.1" />
|
||||||
<entry key="app/src/main/res/layout/fragment_home.xml" value="0.2212962962962963" />
|
<entry key="app/src/main/res/layout/fragment_home.xml" value="0.2212962962962963" />
|
||||||
<entry key="app/src/main/res/layout/fragment_login.xml" value="0.3166496424923391" />
|
<entry key="app/src/main/res/layout/fragment_login.xml" value="0.3166496424923391" />
|
||||||
|
|
@ -31,11 +33,13 @@
|
||||||
<entry key="app/src/main/res/layout/fragment_playlist_page.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/fragment_playlist_page.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/item_home_discover_song.xml" value="0.3166496424923391" />
|
<entry key="app/src/main/res/layout/item_home_discover_song.xml" value="0.3166496424923391" />
|
||||||
<entry key="app/src/main/res/layout/item_horizontal_album.xml" value="0.3166496424923391" />
|
<entry key="app/src/main/res/layout/item_horizontal_album.xml" value="0.3166496424923391" />
|
||||||
|
<entry key="app/src/main/res/layout/item_horizontal_playlist.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/item_horizontal_track.xml" value="4.0" />
|
<entry key="app/src/main/res/layout/item_horizontal_track.xml" value="4.0" />
|
||||||
<entry key="app/src/main/res/layout/item_library_album.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/item_library_album.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/item_login_server.xml" value="0.25" />
|
<entry key="app/src/main/res/layout/item_login_server.xml" value="0.25" />
|
||||||
<entry key="app/src/main/res/layout/item_player_now_playing_song.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/item_player_now_playing_song.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/layout/item_player_queue_song.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/layout/item_player_queue_song.xml" value="0.3229166666666667" />
|
||||||
|
<entry key="app/src/main/res/layout/player_body_bottom_sheet.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/menu/login_page_menu.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/menu/login_page_menu.xml" value="0.3229166666666667" />
|
||||||
<entry key="app/src/main/res/menu/toolbar_menu.xml" value="0.3229166666666667" />
|
<entry key="app/src/main/res/menu/toolbar_menu.xml" value="0.3229166666666667" />
|
||||||
</map>
|
</map>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.cappielloantonio.play.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.cappielloantonio.play.R;
|
||||||
|
import com.cappielloantonio.play.model.Playlist;
|
||||||
|
import com.cappielloantonio.play.ui.fragment.dialog.PlaylistChooserDialog;
|
||||||
|
import com.cappielloantonio.play.util.MusicUtil;
|
||||||
|
import com.cappielloantonio.play.viewmodel.PlaylistChooserViewModel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlaylistHorizontalAdapter extends RecyclerView.Adapter<PlaylistHorizontalAdapter.ViewHolder> {
|
||||||
|
private static final String TAG = "PlaylistHorizontalAdapter";
|
||||||
|
|
||||||
|
private List<Playlist> playlists;
|
||||||
|
private LayoutInflater mInflater;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
private PlaylistChooserViewModel playlistChooserViewModel;
|
||||||
|
private PlaylistChooserDialog playlistChooserDialog;
|
||||||
|
|
||||||
|
public PlaylistHorizontalAdapter(Context context, PlaylistChooserViewModel playlistChooserViewModel, PlaylistChooserDialog playlistChooserDialog) {
|
||||||
|
this.context = context;
|
||||||
|
this.mInflater = LayoutInflater.from(context);
|
||||||
|
this.playlists = new ArrayList<>();
|
||||||
|
|
||||||
|
this.playlistChooserViewModel = playlistChooserViewModel;
|
||||||
|
this.playlistChooserDialog = playlistChooserDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
View view = mInflater.inflate(R.layout.item_horizontal_playlist, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||||
|
Playlist playlist = playlists.get(position);
|
||||||
|
|
||||||
|
holder.playlistTitle.setText(MusicUtil.getReadableString(playlist.getName()));
|
||||||
|
holder.playlistTrackCount.setText(MusicUtil.getReadableString(playlist.getSongCount() + " tracks"));
|
||||||
|
holder.playlistDuration.setText(MusicUtil.getReadableDurationString(playlist.getDuration(), false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return playlists.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(List<Playlist> playlists) {
|
||||||
|
this.playlists = playlists;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Playlist getItem(int id) {
|
||||||
|
return playlists.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||||
|
TextView playlistTitle;
|
||||||
|
TextView playlistTrackCount;
|
||||||
|
TextView playlistDuration;
|
||||||
|
|
||||||
|
ViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
playlistTitle = itemView.findViewById(R.id.playlist_dialog_title_text_view);
|
||||||
|
playlistTrackCount = itemView.findViewById(R.id.playlist_dialog_count_text_view);
|
||||||
|
playlistDuration = itemView.findViewById(R.id.playlist_dialog_duration_text_view);
|
||||||
|
|
||||||
|
itemView.setOnClickListener(this);
|
||||||
|
|
||||||
|
playlistTitle.setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
playlistChooserViewModel.addSongToPlaylist(playlists.get(getBindingAdapterPosition()).getId());
|
||||||
|
playlistChooserDialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -77,4 +77,42 @@ public class PlaylistRepository {
|
||||||
|
|
||||||
return listLivePlaylistSongs;
|
return listLivePlaylistSongs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSongToPlaylist(String playlistId, String songId) {
|
||||||
|
App.getSubsonicClientInstance(application, false)
|
||||||
|
.getPlaylistClient()
|
||||||
|
.updatePlaylist(playlistId, null, true, songId, null)
|
||||||
|
.enqueue(new Callback<SubsonicResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
|
||||||
|
if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createPlaylist(String name, String songId) {
|
||||||
|
App.getSubsonicClientInstance(application, false)
|
||||||
|
.getPlaylistClient()
|
||||||
|
.createPlaylist(null, name, songId)
|
||||||
|
.enqueue(new Callback<SubsonicResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
|
||||||
|
if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,21 @@ public class PlaylistClient {
|
||||||
return playlistService.getPlaylist(subsonic.getParams(), id);
|
return playlistService.getPlaylist(subsonic.getParams(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Call<SubsonicResponse> createPlaylist(String playlistId, String name, String songId) {
|
||||||
|
Log.d(TAG, "createPlaylist()");
|
||||||
|
return playlistService.createPlaylist(subsonic.getParams(), playlistId, name, songId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Call<SubsonicResponse> updatePlaylist(String playlistId, String name, boolean isPublic, String songIdToAdd, String songIndexToRemove) {
|
||||||
|
Log.d(TAG, "updatePlaylist()");
|
||||||
|
return playlistService.updatePlaylist(subsonic.getParams(), playlistId, name, isPublic, songIdToAdd, songIndexToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Call<SubsonicResponse> deletePlaylist(String id) {
|
||||||
|
Log.d(TAG, "deletePlaylist()");
|
||||||
|
return playlistService.deletePlaylist(subsonic.getParams(), id);
|
||||||
|
}
|
||||||
|
|
||||||
private OkHttpClient getOkHttpClient() {
|
private OkHttpClient getOkHttpClient() {
|
||||||
return new OkHttpClient.Builder()
|
return new OkHttpClient.Builder()
|
||||||
.addInterceptor(getHttpLoggingInterceptor())
|
.addInterceptor(getHttpLoggingInterceptor())
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,13 @@ public interface PlaylistService {
|
||||||
|
|
||||||
@GET("getPlaylist")
|
@GET("getPlaylist")
|
||||||
Call<SubsonicResponse> getPlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
|
Call<SubsonicResponse> getPlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
|
||||||
|
|
||||||
|
@GET("createPlaylist")
|
||||||
|
Call<SubsonicResponse> createPlaylist(@QueryMap Map<String, String> params, @Query("playlistId") String playlistId, @Query("name") String name, @Query("songId") String songId);
|
||||||
|
|
||||||
|
@GET("updatePlaylist")
|
||||||
|
Call<SubsonicResponse> updatePlaylist(@QueryMap Map<String, String> params, @Query("playlistId") String playlistId, @Query("name") String name, @Query("public") boolean isPublic, @Query("songIdToAdd") String songIdToAdd, @Query("songIndexToRemove") String songIndexToRemove);
|
||||||
|
|
||||||
|
@GET("deletePlaylist")
|
||||||
|
Call<SubsonicResponse> deletePlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ import com.cappielloantonio.play.repository.QueueRepository;
|
||||||
import com.cappielloantonio.play.repository.SongRepository;
|
import com.cappielloantonio.play.repository.SongRepository;
|
||||||
import com.cappielloantonio.play.service.MusicPlayerRemote;
|
import com.cappielloantonio.play.service.MusicPlayerRemote;
|
||||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||||
|
import com.cappielloantonio.play.ui.fragment.dialog.PlaylistChooserDialog;
|
||||||
|
import com.cappielloantonio.play.ui.fragment.dialog.ServerSignupDialog;
|
||||||
import com.cappielloantonio.play.util.DownloadUtil;
|
import com.cappielloantonio.play.util.DownloadUtil;
|
||||||
import com.cappielloantonio.play.util.MusicUtil;
|
import com.cappielloantonio.play.util.MusicUtil;
|
||||||
import com.cappielloantonio.play.viewmodel.SongBottomSheetViewModel;
|
import com.cappielloantonio.play.viewmodel.SongBottomSheetViewModel;
|
||||||
|
|
@ -49,6 +51,7 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
private TextView playNext;
|
private TextView playNext;
|
||||||
private TextView addToQueue;
|
private TextView addToQueue;
|
||||||
private TextView download;
|
private TextView download;
|
||||||
|
private TextView addToPlaylist;
|
||||||
private TextView goToAlbum;
|
private TextView goToAlbum;
|
||||||
private TextView goToArtist;
|
private TextView goToArtist;
|
||||||
|
|
||||||
|
|
@ -139,6 +142,18 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
dismissBottomSheet();
|
dismissBottomSheet();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addToPlaylist = view.findViewById(R.id.add_to_playlist_text_view);
|
||||||
|
addToPlaylist.setOnClickListener(v -> {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putParcelable("song_object", song);
|
||||||
|
|
||||||
|
PlaylistChooserDialog dialog = new PlaylistChooserDialog();
|
||||||
|
dialog.setArguments(bundle);
|
||||||
|
dialog.show(requireActivity().getSupportFragmentManager(), null);
|
||||||
|
|
||||||
|
dismissBottomSheet();
|
||||||
|
});
|
||||||
|
|
||||||
goToAlbum = view.findViewById(R.id.go_to_album_text_view);
|
goToAlbum = view.findViewById(R.id.go_to_album_text_view);
|
||||||
goToAlbum.setOnClickListener(v -> {
|
goToAlbum.setOnClickListener(v -> {
|
||||||
songBottomSheetViewModel.getAlbum().observe(requireActivity(), album -> {
|
songBottomSheetViewModel.getAlbum().observe(requireActivity(), album -> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.cappielloantonio.play.ui.fragment.dialog;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import com.cappielloantonio.play.R;
|
||||||
|
import com.cappielloantonio.play.adapter.PlaylistHorizontalAdapter;
|
||||||
|
import com.cappielloantonio.play.databinding.DialogPlaylistChooserBinding;
|
||||||
|
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||||
|
import com.cappielloantonio.play.viewmodel.PlaylistChooserViewModel;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class PlaylistChooserDialog extends DialogFragment {
|
||||||
|
private static final String TAG = "ServerSignupDialog";
|
||||||
|
|
||||||
|
private DialogPlaylistChooserBinding bind;
|
||||||
|
private MainActivity activity;
|
||||||
|
private Context context;
|
||||||
|
private PlaylistChooserViewModel playlistChooserViewModel;
|
||||||
|
|
||||||
|
private PlaylistHorizontalAdapter playlistHorizontalAdapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
activity = (MainActivity) getActivity();
|
||||||
|
context = requireContext();
|
||||||
|
|
||||||
|
bind = DialogPlaylistChooserBinding.inflate(LayoutInflater.from(requireContext()));
|
||||||
|
playlistChooserViewModel = new ViewModelProvider(requireActivity()).get(PlaylistChooserViewModel.class);
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog);
|
||||||
|
|
||||||
|
builder.setView(bind.getRoot())
|
||||||
|
.setTitle("Add to a playlist")
|
||||||
|
.setNeutralButton("Create", (dialog, id) -> {
|
||||||
|
})
|
||||||
|
.setNegativeButton("Cancel", (dialog, id) -> dialog.cancel());
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
initPlaylistView();
|
||||||
|
setSongInfo();
|
||||||
|
setButtonAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSongInfo() {
|
||||||
|
if (getArguments() != null) {
|
||||||
|
playlistChooserViewModel.setSongToAdd(getArguments().getParcelable("song_object"));
|
||||||
|
} else {
|
||||||
|
playlistChooserViewModel.setSongToAdd(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButtonAction() {
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||||
|
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v -> {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putParcelable("song_object", playlistChooserViewModel.getSongToAdd());
|
||||||
|
|
||||||
|
PlaylistEditorDialog dialog = new PlaylistEditorDialog();
|
||||||
|
dialog.setArguments(bundle);
|
||||||
|
dialog.show(requireActivity().getSupportFragmentManager(), null);
|
||||||
|
|
||||||
|
Objects.requireNonNull(getDialog()).dismiss();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPlaylistView() {
|
||||||
|
bind.playlistDialogRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||||
|
bind.playlistDialogRecyclerView.setHasFixedSize(true);
|
||||||
|
|
||||||
|
playlistHorizontalAdapter = new PlaylistHorizontalAdapter(requireContext(), playlistChooserViewModel, this);
|
||||||
|
bind.playlistDialogRecyclerView.setAdapter(playlistHorizontalAdapter);
|
||||||
|
|
||||||
|
playlistChooserViewModel.getPlaylistList().observe(requireActivity(), playlists -> {
|
||||||
|
if(playlists.size() > 0) {
|
||||||
|
if (bind != null) bind.noPlaylistsCreatedTextView.setVisibility(View.GONE);
|
||||||
|
if (bind != null) bind.playlistDialogRecyclerView.setVisibility(View.VISIBLE);
|
||||||
|
playlistHorizontalAdapter.setItems(playlists);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (bind != null) bind.noPlaylistsCreatedTextView.setVisibility(View.VISIBLE);
|
||||||
|
if (bind != null) bind.playlistDialogRecyclerView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.cappielloantonio.play.ui.fragment.dialog;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import com.cappielloantonio.play.R;
|
||||||
|
import com.cappielloantonio.play.databinding.DialogPlaylistEditorBinding;
|
||||||
|
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||||
|
import com.cappielloantonio.play.viewmodel.PlaylistEditorViewModel;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class PlaylistEditorDialog extends DialogFragment {
|
||||||
|
private static final String TAG = "ServerSignupDialog";
|
||||||
|
|
||||||
|
private DialogPlaylistEditorBinding bind;
|
||||||
|
private MainActivity activity;
|
||||||
|
private Context context;
|
||||||
|
private PlaylistEditorViewModel playlistEditorViewModel;
|
||||||
|
|
||||||
|
private String playlistName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
activity = (MainActivity) getActivity();
|
||||||
|
context = requireContext();
|
||||||
|
|
||||||
|
bind = DialogPlaylistEditorBinding.inflate(LayoutInflater.from(requireContext()));
|
||||||
|
playlistEditorViewModel = new ViewModelProvider(requireActivity()).get(PlaylistEditorViewModel.class);
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog);
|
||||||
|
|
||||||
|
builder.setView(bind.getRoot())
|
||||||
|
.setTitle("Create playlist")
|
||||||
|
.setPositiveButton("Save", (dialog, id) -> {
|
||||||
|
})
|
||||||
|
.setNegativeButton("Cancel", (dialog, id) -> dialog.cancel());
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
setSongInfo();
|
||||||
|
setButtonAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSongInfo() {
|
||||||
|
if (getArguments() != null) {
|
||||||
|
playlistEditorViewModel.setSongToAdd(getArguments().getParcelable("song_object"));
|
||||||
|
} else {
|
||||||
|
playlistEditorViewModel.setSongToAdd(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButtonAction() {
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||||
|
|
||||||
|
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
|
||||||
|
if (validateInput()) {
|
||||||
|
playlistEditorViewModel.createPlaylist(playlistName);
|
||||||
|
Objects.requireNonNull(getDialog()).dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateInput() {
|
||||||
|
playlistName = bind.playlistNameTextView.getText().toString().trim();
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(playlistName)) {
|
||||||
|
bind.playlistNameTextView.setError("Required");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
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.Playlist;
|
||||||
|
import com.cappielloantonio.play.model.Song;
|
||||||
|
import com.cappielloantonio.play.repository.PlaylistRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlaylistChooserViewModel extends AndroidViewModel {
|
||||||
|
private PlaylistRepository playlistRepository;
|
||||||
|
|
||||||
|
private MutableLiveData<List<Playlist>> playlists;
|
||||||
|
private Song toAdd;
|
||||||
|
|
||||||
|
public PlaylistChooserViewModel(@NonNull Application application) {
|
||||||
|
super(application);
|
||||||
|
|
||||||
|
playlistRepository = new PlaylistRepository(application);
|
||||||
|
|
||||||
|
playlists = playlistRepository.getPlaylists(false, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Playlist>> getPlaylistList() {
|
||||||
|
return playlists;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSongToPlaylist(String playlistId) {
|
||||||
|
playlistRepository.addSongToPlaylist(playlistId, toAdd.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSongToAdd(Song song) {
|
||||||
|
toAdd = song;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Song getSongToAdd() {
|
||||||
|
return toAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.cappielloantonio.play.viewmodel;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
|
import com.cappielloantonio.play.model.Server;
|
||||||
|
import com.cappielloantonio.play.model.Song;
|
||||||
|
import com.cappielloantonio.play.repository.PlaylistRepository;
|
||||||
|
import com.cappielloantonio.play.repository.ServerRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlaylistEditorViewModel extends AndroidViewModel {
|
||||||
|
private PlaylistRepository playlistRepository;
|
||||||
|
|
||||||
|
private Song toAdd;
|
||||||
|
|
||||||
|
public PlaylistEditorViewModel(@NonNull Application application) {
|
||||||
|
super(application);
|
||||||
|
|
||||||
|
playlistRepository = new PlaylistRepository(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createPlaylist(String name) {
|
||||||
|
playlistRepository.createPlaylist(name, toAdd.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePlaylist(String playlistId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSongToAdd(Song song) {
|
||||||
|
toAdd = song;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -152,6 +152,22 @@
|
||||||
android:textFontWeight="700"
|
android:textFontWeight="700"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/add_to_playlist_text_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:fontFamily="@font/opensans"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:text="Aggiungi alla playlist"
|
||||||
|
android:textColor="@color/titleTextColor"
|
||||||
|
android:textFontWeight="700"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/go_to_album_text_view"
|
android:id="@+id/go_to_album_text_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
25
app/src/main/res/layout/dialog_playlist_chooser.xml
Normal file
25
app/src/main/res/layout/dialog_playlist_chooser.xml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/no_playlists_created_text_view"
|
||||||
|
style="@style/SubheadTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="No playlists created"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/playlist_dialog_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layout_marginTop="8dp"/>
|
||||||
|
</LinearLayout>
|
||||||
30
app/src/main/res/layout/dialog_playlist_editor.xml
Normal file
30
app/src/main/res/layout/dialog_playlist_editor.xml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<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">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:textColorHint="?android:textColorHint"
|
||||||
|
app:endIconMode="clear_text"
|
||||||
|
app:endIconTint="?android:textColorSecondary"
|
||||||
|
app:errorEnabled="true"
|
||||||
|
app:hintTextColor="@color/colorAccent"
|
||||||
|
app:boxStrokeColor="@color/colorAccent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/playlist_name_text_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="Playlist Name"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
android:textCursorDrawable="@null" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
</LinearLayout>
|
||||||
71
app/src/main/res/layout/item_horizontal_playlist.xml
Normal file
71
app/src/main/res/layout/item_horizontal_playlist.xml
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<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="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playlist_dialog_title_text_view"
|
||||||
|
style="@style/ItemTitleTextView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:marqueeRepeatLimit="marquee_forever"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:scrollHorizontally="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/label_placeholder"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/playlist_dialog_title_text_view">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playlist_dialog_count_text_view"
|
||||||
|
style="@style/ItemSubtitleTextView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
|
android:text="@string/label_placeholder" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/queue_separator_text_view"
|
||||||
|
style="@style/ItemSubtitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/label_dot_separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playlist_dialog_duration_text_view"
|
||||||
|
style="@style/ItemSubtitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:text="@string/label_placeholder" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue