feat: radio stream add/edit dialog

This commit is contained in:
antonio 2023-05-07 19:22:04 +02:00
parent 3ef46a8536
commit 2542b28916
7 changed files with 301 additions and 2 deletions

View file

@ -0,0 +1,6 @@
package com.cappielloantonio.play.interfaces;
public interface RadioCallback {
void onDismiss();
}

View file

@ -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<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<ApiResponse> 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<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
}
public void deleteInternetRadioStation(String id) {
App.getSubsonicClientInstance(false)
.getInternetRadioClient()
.deleteInternetRadioStation(id)
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
}
}

View file

@ -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();
}
}

View file

@ -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());
}
}

View file

@ -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<List<InternetRadioStation>> internetRadioStations = new MutableLiveData<>(null);
public RadioViewModel(@NonNull Application application) {
super(application);
radioRepository = new RadioRepository();
}
public LiveData<List<InternetRadioStation>> getInternetRadioStations() {
return radioRepository.getInternetRadioStations();
public LiveData<List<InternetRadioStation>> getInternetRadioStations(LifecycleOwner owner) {
radioRepository.getInternetRadioStations().observe(owner, internetRadioStations::postValue);
return internetRadioStations;
}
}

View file

@ -0,0 +1,67 @@
<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.Material3.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">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/internet_radio_station_name_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/radio_editor_dialog_hint_name"
android:inputType="textNoSuggestions"
android:textCursorDrawable="@null" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:textColorHint="?android:textColorHint"
app:endIconMode="clear_text"
app:endIconTint="?android:textColorSecondary"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/internet_radio_station_stream_url_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/radio_editor_dialog_hint_stream_url"
android:inputType="textNoSuggestions"
android:textCursorDrawable="@null" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:textColorHint="?android:textColorHint"
app:endIconMode="clear_text"
app:endIconTint="?android:textColorSecondary"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/internet_radio_station_homepage_url_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/radio_editor_dialog_hint_homepage_url"
android:inputType="textNoSuggestions"
android:textCursorDrawable="@null" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View file

@ -58,6 +58,7 @@
<string name="filter_title_expanded">Filter Genres</string>
<string name="genre_catalogue_title">Genre Catalogue</string>
<string name="genre_catalogue_title_expanded">Browse Genres</string>
<string name="home_subtitle_new_internet_radio_station">Add a new radio</string>
<string name="home_subtitle_made_for_you">Start mix from a song you liked</string>
<string name="home_sync_starred_title">Looks like there are some starred tracks to sync</string>
<string name="home_sync_starred_subtitle">Downloading these tracks may involve significant data usage</string>
@ -118,6 +119,13 @@
<string name="playlist_page_shuffle_button">Shuffle</string>
<string name="playlist_song_count">Playlist • %1$d songs</string>
<string name="podcast_release_date_duration_formatter">%1$s • %2$s</string>
<string name="radio_editor_dialog_hint_name">Radio Name</string>
<string name="radio_editor_dialog_hint_stream_url">Radio Stream URL</string>
<string name="radio_editor_dialog_hint_homepage_url">Radio Homepage URL</string>
<string name="radio_editor_dialog_negative_button">Cancel</string>
<string name="radio_editor_dialog_neutral_button">Delete</string>
<string name="radio_editor_dialog_positive_button">Save</string>
<string name="radio_editor_dialog_title">Internet Radio Station</string>
<string name="rating_dialog_negative_button">Cancel</string>
<string name="rating_dialog_positive_button">Save</string>
<string name="rating_dialog_title">Rate</string>