diff --git a/app/src/main/java/com/cappielloantonio/play/interfaces/RadioCallback.java b/app/src/main/java/com/cappielloantonio/play/interfaces/RadioCallback.java new file mode 100644 index 00000000..21d9b758 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/interfaces/RadioCallback.java @@ -0,0 +1,6 @@ +package com.cappielloantonio.play.interfaces; + +public interface RadioCallback { + + void onDismiss(); +} diff --git a/app/src/main/java/com/cappielloantonio/play/repository/RadioRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/RadioRepository.java index 2654efbf..872cb5c7 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/RadioRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/RadioRepository.java @@ -36,4 +36,55 @@ public class RadioRepository { return radioStation; } + + public void createInternetRadioStation(String name, String streamURL, String homepageURL) { + App.getSubsonicClientInstance(false) + .getInternetRadioClient() + .createInternetRadioStation(streamURL, name, homepageURL) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + } + }); + } + + public void updateInternetRadioStation(String id, String name, String streamURL, String homepageURL) { + App.getSubsonicClientInstance(false) + .getInternetRadioClient() + .updateInternetRadioStation(id, streamURL, name, homepageURL) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + } + }); + } + + public void deleteInternetRadioStation(String id) { + App.getSubsonicClientInstance(false) + .getInternetRadioClient() + .deleteInternetRadioStation(id) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + } + }); + } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/dialog/RadioEditorDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/dialog/RadioEditorDialog.java new file mode 100644 index 00000000..74df8bcb --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/ui/dialog/RadioEditorDialog.java @@ -0,0 +1,119 @@ +package com.cappielloantonio.play.ui.dialog; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProvider; + +import com.cappielloantonio.play.R; +import com.cappielloantonio.play.databinding.DialogRadioEditorBinding; +import com.cappielloantonio.play.interfaces.RadioCallback; +import com.cappielloantonio.play.subsonic.models.InternetRadioStation; +import com.cappielloantonio.play.util.Constants; +import com.cappielloantonio.play.viewmodel.RadioEditorViewModel; + +import java.util.Objects; + +public class RadioEditorDialog extends DialogFragment { + private DialogRadioEditorBinding bind; + private RadioEditorViewModel radioEditorViewModel; + private RadioCallback radioCallback; + + private String radioName; + private String radioStreamURL; + private String radioHomepageURL; + + public RadioEditorDialog(RadioCallback radioCallback) { + this.radioCallback = radioCallback; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + bind = DialogRadioEditorBinding.inflate(getLayoutInflater()); + radioEditorViewModel = new ViewModelProvider(requireActivity()).get(RadioEditorViewModel.class); + + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + builder.setView(bind.getRoot()) + .setTitle(R.string.radio_editor_dialog_title) + .setPositiveButton(R.string.radio_editor_dialog_positive_button, (dialog, id) -> { + }) + .setNeutralButton(R.string.radio_editor_dialog_neutral_button, (dialog, id) -> dialog.cancel()) + .setNegativeButton(R.string.radio_editor_dialog_negative_button, (dialog, id) -> dialog.cancel()); + + return builder.create(); + } + + @Override + public void onStart() { + super.onStart(); + + setParameterInfo(); + setButtonAction(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind = null; + } + + private void setParameterInfo() { + if (getArguments() != null && getArguments().getParcelable(Constants.INTERNET_RADIO_STATION_OBJECT) != null) { + InternetRadioStation toEdit = requireArguments().getParcelable(Constants.INTERNET_RADIO_STATION_OBJECT); + + radioEditorViewModel.setRadioToEdit(toEdit); + + bind.internetRadioStationNameTextView.setText(toEdit.getName()); + bind.internetRadioStationStreamUrlTextView.setText(toEdit.getStreamUrl()); + bind.internetRadioStationHomepageUrlTextView.setText(toEdit.getHomePageUrl()); + } + } + + private void setButtonAction() { + ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> { + if (validateInput()) { + if (radioEditorViewModel.getRadioToEdit() == null) { + radioEditorViewModel.createRadio(radioName, radioStreamURL, radioHomepageURL); + } else { + radioEditorViewModel.updateRadio(radioName, radioStreamURL, radioHomepageURL); + } + + dismissDialog(); + } + }); + + ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v -> { + radioEditorViewModel.deleteRadio(); + dismissDialog(); + }); + } + + private boolean validateInput() { + radioName = Objects.requireNonNull(bind.internetRadioStationNameTextView.getText()).toString().trim(); + radioStreamURL = Objects.requireNonNull(bind.internetRadioStationStreamUrlTextView.getText()).toString().trim(); + radioHomepageURL = Objects.requireNonNull(bind.internetRadioStationHomepageUrlTextView.getText()).toString().trim(); + + if (TextUtils.isEmpty(radioName)) { + bind.internetRadioStationNameTextView.setError(getString(R.string.error_required)); + return false; + } + + if (TextUtils.isEmpty(radioStreamURL)) { + bind.internetRadioStationStreamUrlTextView.setError(getString(R.string.error_required)); + return false; + } + + return true; + } + + private void dismissDialog() { + radioCallback.onDismiss(); + Objects.requireNonNull(getDialog()).dismiss(); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioEditorViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioEditorViewModel.java new file mode 100644 index 00000000..a4307377 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioEditorViewModel.java @@ -0,0 +1,43 @@ +package com.cappielloantonio.play.viewmodel; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; + +import com.cappielloantonio.play.repository.RadioRepository; +import com.cappielloantonio.play.subsonic.models.InternetRadioStation; + +public class RadioEditorViewModel extends AndroidViewModel { + private static final String TAG = "RadioEditorViewModel"; + + private final RadioRepository radioRepository; + + private InternetRadioStation toEdit; + + public RadioEditorViewModel(@NonNull Application application) { + super(application); + + radioRepository = new RadioRepository(); + } + + public InternetRadioStation getRadioToEdit() { + return toEdit; + } + + public void setRadioToEdit(InternetRadioStation internetRadioStation) { + this.toEdit = internetRadioStation; + } + + public void createRadio(String name, String streamURL, String homepageURL) { + radioRepository.createInternetRadioStation(name, streamURL, homepageURL); + } + + public void updateRadio(String name, String streamURL, String homepageURL) { + if (toEdit != null) radioRepository.updateInternetRadioStation(toEdit.getId(), name, streamURL, homepageURL); + } + + public void deleteRadio() { + if (toEdit != null) radioRepository.deleteInternetRadioStation(toEdit.getId()); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioViewModel.java index f32af92c..f4ce7c51 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/RadioViewModel.java @@ -4,7 +4,9 @@ import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; import com.cappielloantonio.play.repository.RadioRepository; import com.cappielloantonio.play.subsonic.models.InternetRadioStation; @@ -14,13 +16,16 @@ import java.util.List; public class RadioViewModel extends AndroidViewModel { private final RadioRepository radioRepository; + private final MutableLiveData> internetRadioStations = new MutableLiveData<>(null); + public RadioViewModel(@NonNull Application application) { super(application); radioRepository = new RadioRepository(); } - public LiveData> getInternetRadioStations() { - return radioRepository.getInternetRadioStations(); + public LiveData> getInternetRadioStations(LifecycleOwner owner) { + radioRepository.getInternetRadioStations().observe(owner, internetRadioStations::postValue); + return internetRadioStations; } } diff --git a/app/src/main/res/layout/dialog_radio_editor.xml b/app/src/main/res/layout/dialog_radio_editor.xml new file mode 100644 index 00000000..6f5a2fe6 --- /dev/null +++ b/app/src/main/res/layout/dialog_radio_editor.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 50de3811..ab7f802e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -58,6 +58,7 @@ Filter Genres Genre Catalogue Browse Genres + Add a new radio Start mix from a song you liked Looks like there are some starred tracks to sync Downloading these tracks may involve significant data usage @@ -118,6 +119,13 @@ Shuffle Playlist • %1$d songs %1$s • %2$s + Radio Name + Radio Stream URL + Radio Homepage URL + Cancel + Delete + Save + Internet Radio Station Cancel Save Rate