package de.danoeh.antennapod.dialog; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.chip.Chip; import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.view.ItemOffsetDecoration; import de.danoeh.antennapod.view.PlaybackSpeedSeekBar; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; public class VariableSpeedDialog extends DialogFragment { private SpeedSelectionAdapter adapter; private final DecimalFormat speedFormat; private PlaybackController controller; private final List selectedSpeeds; private PlaybackSpeedSeekBar speedSeekBar; private Chip addCurrentSpeedChip; public VariableSpeedDialog() { DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US); format.setDecimalSeparator('.'); speedFormat = new DecimalFormat("0.00", format); selectedSpeeds = new ArrayList<>(UserPreferences.getPlaybackSpeedArray()); } public static void showGetPluginDialog(final Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(R.string.no_playback_plugin_title); builder.setMessage(R.string.no_playback_plugin_or_sonic_msg); builder.setPositiveButton(R.string.enable_sonic, (dialog, which) -> { UserPreferences.enableSonic(); }); builder.setNeutralButton(R.string.close_label, null); builder.show(); } @Override public void onStart() { super.onStart(); controller = new PlaybackController(getActivity()) { @Override public void setupGUI() { updateSpeed(); } @Override public void onPlaybackSpeedChange() { updateSpeed(); } }; controller.init(); speedSeekBar.setController(controller); } private void updateSpeed() { speedSeekBar.updateSpeed(); addCurrentSpeedChip.setText(speedFormat.format(controller.getCurrentPlaybackSpeedMultiplier())); } @Override public void onStop() { super.onStop(); controller.release(); controller = null; } @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setPositiveButton(R.string.close_label, null); View root = View.inflate(getContext(), R.layout.speed_select_dialog, null); speedSeekBar = root.findViewById(R.id.speed_seek_bar); RecyclerView selectedSpeedsGrid = root.findViewById(R.id.selected_speeds_grid); selectedSpeedsGrid.setLayoutManager(new GridLayoutManager(getContext(), 3)); selectedSpeedsGrid.addItemDecoration(new ItemOffsetDecoration(getContext(), 4)); adapter = new SpeedSelectionAdapter(); adapter.setHasStableIds(true); selectedSpeedsGrid.setAdapter(adapter); addCurrentSpeedChip = root.findViewById(R.id.add_current_speed_chip); addCurrentSpeedChip.setCloseIconVisible(true); addCurrentSpeedChip.setCloseIconResource(R.drawable.ic_add_black); addCurrentSpeedChip.setOnCloseIconClickListener(v -> addCurrentSpeed()); addCurrentSpeedChip.setOnClickListener(v -> addCurrentSpeed()); builder.setView(root); return builder.create(); } private void addCurrentSpeed() { float newSpeed = controller.getCurrentPlaybackSpeedMultiplier(); if (selectedSpeeds.contains(newSpeed)) { Snackbar.make(addCurrentSpeedChip, getString(R.string.preset_already_exists, newSpeed), Snackbar.LENGTH_LONG).show(); } else { selectedSpeeds.add(newSpeed); Collections.sort(selectedSpeeds); UserPreferences.setPlaybackSpeedArray(selectedSpeeds); adapter.notifyDataSetChanged(); } } public class SpeedSelectionAdapter extends RecyclerView.Adapter { @Override @NonNull public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { Chip chip = new Chip(getContext()); chip.setCloseIconVisible(true); chip.setCloseIconResource(R.drawable.ic_delete_black); return new ViewHolder(chip); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { float speed = selectedSpeeds.get(position); holder.chip.setText(speedFormat.format(speed)); holder.chip.setOnCloseIconClickListener(v -> { selectedSpeeds.remove(speed); UserPreferences.setPlaybackSpeedArray(selectedSpeeds); notifyDataSetChanged(); }); holder.chip.setOnClickListener(v -> { if (controller != null) { controller.setPlaybackSpeed(speed); notifyDataSetChanged(); } }); } @Override public int getItemCount() { return selectedSpeeds.size(); } @Override public long getItemId(int position) { return selectedSpeeds.get(position).hashCode(); } public class ViewHolder extends RecyclerView.ViewHolder { Chip chip; ViewHolder(Chip itemView) { super(itemView); chip = itemView; } } } }