diff --git a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/MediathekShow.java b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/MediathekShow.java index 3a1eb8c9..d350ed14 100644 --- a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/MediathekShow.java +++ b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/MediathekShow.java @@ -17,6 +17,8 @@ import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatterBuilder; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; @SuppressWarnings("unused") @@ -195,6 +197,18 @@ public class MediathekShow implements Serializable { } } + public List getSupportedDownloadQualities() { + List qualities = new ArrayList<>(); + + for (Quality quality : Quality.values()) { + if (hasDownloadQuality(quality)) { + qualities.add(quality); + } + } + + return qualities; + } + public String getHighestPossibleStreamingUrl() { String highVideoUrl = getVideoUrl(Quality.High); String mediumVideoUrl = getVideoUrl(Quality.Medium); diff --git a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/Quality.java b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/Quality.java index 9e31c055..5bb4b671 100644 --- a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/Quality.java +++ b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/model/Quality.java @@ -1,7 +1,19 @@ package de.christinecoenen.code.zapp.app.mediathek.model; +import de.christinecoenen.code.zapp.R; + public enum Quality { - Low, - Medium, - High + Low(R.string.fragment_mediathek_qualities_low), + Medium(R.string.fragment_mediathek_qualities_medium), + High(R.string.fragment_mediathek_qualities_high); + + private int labelResId; + + Quality(int labelResId) { + this.labelResId = labelResId; + } + + public int getLabelResId() { + return labelResId; + } } diff --git a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/MediathekDetailFragment.java b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/MediathekDetailFragment.java index 5e3bb3dc..2545a833 100644 --- a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/MediathekDetailFragment.java +++ b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/MediathekDetailFragment.java @@ -30,7 +30,9 @@ import de.christinecoenen.code.zapp.databinding.FragmentMediathekDetailBinding; import de.christinecoenen.code.zapp.utils.system.IntentHelper; -public class MediathekDetailFragment extends Fragment implements ISingleDownloadListener, ConfirmFileDeletionDialog.Listener { +public class MediathekDetailFragment extends Fragment implements ISingleDownloadListener, + ConfirmFileDeletionDialog.Listener, + SelectQualityDialog.Listener { private static final String ARG_SHOW = "ARG_SHOW"; @@ -127,6 +129,11 @@ public class MediathekDetailFragment extends Fragment implements ISingleDownload downloadController.deleteDownload(show.getId()); } + @Override + public void onQualitySelected(Quality quality) { + download(quality); + } + private void onPlayClick(View view) { startActivity(MediathekPlayerActivity.getStartIntent(getContext(), show)); } @@ -139,7 +146,7 @@ public class MediathekDetailFragment extends Fragment implements ISingleDownload case PAUSED: case REMOVED: case FAILED: - download(); + showSelectDownloadQualityDialog(); break; case ADDED: case QUEUED: @@ -166,6 +173,12 @@ public class MediathekDetailFragment extends Fragment implements ISingleDownload newFragment.show(getParentFragmentManager(), null); } + private void showSelectDownloadQualityDialog() { + DialogFragment newFragment = SelectQualityDialog.newInstance(show); + newFragment.setTargetFragment(this, 0); + newFragment.show(getParentFragmentManager(), null); + } + private void adjustDownloadButton(Status status) { switch (status) { case NONE: @@ -210,9 +223,7 @@ public class MediathekDetailFragment extends Fragment implements ISingleDownload startActivity(Intent.createChooser(videoIntent, getString(R.string.action_share))); } - private void download() { - Quality downloadQuality = show.getHighestPossibleDownloadQuality(); - + private void download(Quality downloadQuality) { try { downloadController.startDownload(show, downloadQuality); } catch (WrongNetworkConditionException e) { diff --git a/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/SelectQualityDialog.java b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/SelectQualityDialog.java new file mode 100644 index 00000000..c1d46f67 --- /dev/null +++ b/app/src/main/java/de/christinecoenen/code/zapp/app/mediathek/ui/detail/SelectQualityDialog.java @@ -0,0 +1,77 @@ +package de.christinecoenen.code.zapp.app.mediathek.ui.detail; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatDialogFragment; + +import java.util.List; +import java.util.Objects; + +import de.christinecoenen.code.zapp.R; +import de.christinecoenen.code.zapp.app.mediathek.model.MediathekShow; +import de.christinecoenen.code.zapp.app.mediathek.model.Quality; + + +public class SelectQualityDialog extends AppCompatDialogFragment { + + private static final String ARGUMENT_MEDIATHEK_SHOW = "ARGUMENT_MEDIATHEK_SHOW"; + + static SelectQualityDialog newInstance(MediathekShow mediathekShow) { + SelectQualityDialog fragment = new SelectQualityDialog(); + + Bundle args = new Bundle(); + args.putSerializable(ARGUMENT_MEDIATHEK_SHOW, mediathekShow); + fragment.setArguments(args); + + return fragment; + } + + private String[] qualities; + private Listener listener; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + assert getArguments() != null; + + MediathekShow show = (MediathekShow) getArguments().getSerializable(ARGUMENT_MEDIATHEK_SHOW); + List supportedQualities = Objects.requireNonNull(show).getSupportedDownloadQualities(); + + qualities = new String[supportedQualities.size()]; + + for (int i = 0; i < supportedQualities.size(); i++) { + qualities[i] = getString(supportedQualities.get(i).getLabelResId()); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + if (getTargetFragment() instanceof Listener) { + listener = (Listener) getTargetFragment(); + } else { + throw new IllegalArgumentException("Parent fragment must implement ConfirmFileDeletionDialog.Listener interface."); + } + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + return new AlertDialog.Builder(requireActivity()) + .setTitle(R.string.fragment_mediathek_qualities_title) + .setItems(qualities, (dialogInterface, i) -> listener.onQualitySelected(Quality.values()[i])) + .setNegativeButton(android.R.string.cancel, null) + .create(); + } + + interface Listener { + void onQualitySelected(Quality quality); + } +}