diff --git a/frontend/src/api.js b/frontend/src/api.js index 3a745896..31963452 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -610,11 +610,19 @@ export default class API { } } - static async deleteChannel(id) { + static async deleteChannel(id, { stopStream = false } = {}) { try { - await request(`${host}/api/channels/channels/${id}/`, { - method: 'DELETE', - }); + const params = new URLSearchParams(); + if (stopStream) { + params.set('stop_stream', 'true'); + } + const query = params.toString(); + await request( + `${host}/api/channels/channels/${id}/${query ? `?${query}` : ''}`, + { + method: 'DELETE', + } + ); useChannelsStore.getState().removeChannels([id]); await API.requeryStreams(); @@ -624,11 +632,11 @@ export default class API { } // @TODO: the bulk delete endpoint is currently broken - static async deleteChannels(channel_ids) { + static async deleteChannels(channel_ids, { stopStream = false } = {}) { try { await request(`${host}/api/channels/channels/bulk-delete/`, { method: 'DELETE', - body: { channel_ids }, + body: { channel_ids, stop_stream: Boolean(stopStream) }, }); useChannelsStore.getState().removeChannels(channel_ids); diff --git a/frontend/src/components/ConfirmationDialog.jsx b/frontend/src/components/ConfirmationDialog.jsx index 86e7d7af..e9a6f433 100644 --- a/frontend/src/components/ConfirmationDialog.jsx +++ b/frontend/src/components/ConfirmationDialog.jsx @@ -1,5 +1,5 @@ import { Modal, Group, Button, Checkbox, Box } from '@mantine/core'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import useWarningsStore from '../store/warnings'; /** @@ -17,6 +17,10 @@ import useWarningsStore from '../store/warnings'; * @param {Function} props.onSuppressChange - Called when "don't show again" option changes * @param {string} [props.size='md'] - Size of the modal * @param {boolean} [props.loading=false] - Whether the confirm button should show loading state + * @param {boolean} [props.showDeleteFileOption=false] - Show "also delete files" checkbox + * @param {string} [props.deleteFileLabel] - Label for delete-files checkbox + * @param {boolean} [props.showStopStreamOption=false] - Show "also stop stream" checkbox + * @param {string} [props.stopStreamLabel] - Label for stop-stream checkbox */ const ConfirmationDialog = ({ opened, @@ -32,14 +36,38 @@ const ConfirmationDialog = ({ zIndex = 1000, showDeleteFileOption = false, deleteFileLabel = 'Also delete files from disk', + showStopStreamOption = false, + stopStreamLabel = 'Also stop active stream if playing', loading = false, }) => { const suppressWarning = useWarningsStore((s) => s.suppressWarning); const isWarningSuppressed = useWarningsStore((s) => s.isWarningSuppressed); + const setActionPreference = useWarningsStore((s) => s.setActionPreference); + const getActionPreference = useWarningsStore((s) => s.getActionPreference); const [suppressChecked, setSuppressChecked] = useState( isWarningSuppressed(actionKey) ); const [deleteFiles, setDeleteFiles] = useState(false); + const [stopStream, setStopStream] = useState(false); + + useEffect(() => { + if (!opened) { + return; + } + setSuppressChecked(isWarningSuppressed(actionKey)); + setDeleteFiles(false); + if (showStopStreamOption && actionKey) { + setStopStream(getActionPreference(actionKey, 'stopStream', false)); + } else { + setStopStream(false); + } + }, [ + opened, + actionKey, + showStopStreamOption, + isWarningSuppressed, + getActionPreference, + ]); const handleToggleSuppress = (e) => { setSuppressChecked(e.currentTarget.checked); @@ -49,19 +77,25 @@ const ConfirmationDialog = ({ }; const handleConfirm = () => { + if (showStopStreamOption && actionKey) { + setActionPreference(actionKey, { stopStream }); + } if (suppressChecked) { suppressWarning(actionKey); } - if (showDeleteFileOption) { + if (showStopStreamOption) { + onConfirm(stopStream); + } else if (showDeleteFileOption) { onConfirm(deleteFiles); } else { onConfirm(); } - setDeleteFiles(false); // Reset for next time + setDeleteFiles(false); }; const handleClose = () => { - setDeleteFiles(false); // Reset for next time + setDeleteFiles(false); + setStopStream(false); onClose(); }; @@ -76,15 +110,6 @@ const ConfirmationDialog = ({ > {message} - {actionKey && ( - - )} - {showDeleteFileOption && ( )} + {showStopStreamOption && ( + setStopStream(event.currentTarget.checked)} + label={stopStreamLabel} + mb="md" + /> + )} + + {actionKey && ( + + )} +