0}
- selectedMedia={this.state.selectedMedia}
- onMediaSelection={this.handleMediaSelection}
- onItemsUpdate={this.handleItemsUpdate}
+ hasAnySelection={isSelectMediaMode ? this.state.selectedMedia.size > 0 : this.props.bulkActions.selectedMedia.size > 0}
+ selectedMedia={isSelectMediaMode ? this.state.selectedMedia : this.props.bulkActions.selectedMedia}
+ onMediaSelection={isSelectMediaMode ? this.handleMediaSelection : this.props.bulkActions.handleMediaSelection}
+ onItemsUpdate={!isSelectMediaMode ? this.props.bulkActions.handleItemsUpdate : undefined}
onResponseDataLoaded={this.onResponseDataLoaded}
/>
) : null,
- ,
- ,
- ,
- ,
- ,
- ,
- ,
- this.state.showNotification ? (
-
- {this.state.notificationMessage}
-
+ this.state.author && isMediaAuthor && !isSelectMediaMode ? (
+
) : null,
];
}
@@ -1112,8 +467,17 @@ export class ProfileMediaPage extends Page {
ProfileMediaPage.propTypes = {
title: PropTypes.string.isRequired,
+ bulkActions: PropTypes.object.isRequired,
};
ProfileMediaPage.defaultProps = {
title: 'Uploads',
};
+
+// Export the raw class for subclasses to extend
+export { ProfileMediaPage as ProfileMediaPageBase };
+
+// Export the HOC-wrapped version as the renderable component
+const WrappedProfileMediaPage = withBulkActions(ProfileMediaPage);
+export { WrappedProfileMediaPage as ProfileMediaPage };
+export default WrappedProfileMediaPage;
diff --git a/frontend/src/static/js/pages/ProfilePlaylistsPage.js b/frontend/src/static/js/pages/ProfilePlaylistsPage.js
index 6f5b8d79..9c791462 100755
--- a/frontend/src/static/js/pages/ProfilePlaylistsPage.js
+++ b/frontend/src/static/js/pages/ProfilePlaylistsPage.js
@@ -6,9 +6,9 @@ import { MediaListWrapper } from '../components/MediaListWrapper';
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
import { LazyLoadItemListAsync } from '../components/item-list/LazyLoadItemListAsync.jsx';
-import { ProfileMediaPage } from './ProfileMediaPage';
+import { ProfileMediaPageBase } from './ProfileMediaPage';
-export class ProfilePlaylistsPage extends ProfileMediaPage {
+export class ProfilePlaylistsPage extends ProfileMediaPageBase {
constructor(props) {
super(props, 'author-playlists');
diff --git a/frontend/src/static/js/utils/hooks/useBulkActions.js b/frontend/src/static/js/utils/hooks/useBulkActions.js
index 32dfb4b7..9f082bce 100644
--- a/frontend/src/static/js/utils/hooks/useBulkActions.js
+++ b/frontend/src/static/js/utils/hooks/useBulkActions.js
@@ -111,6 +111,10 @@ export function useBulkActions() {
setShowConfirmModal(true);
setPendingAction(action);
setConfirmMessage(translateString('You are going to disable comments to') + ` ${selectedCount} ` + translateString('media, are you sure?'));
+ } else if (action === 'delete-comments') {
+ setShowConfirmModal(true);
+ setPendingAction(action);
+ setConfirmMessage(translateString('You are going to delete all comments from') + ` ${selectedCount} ` + translateString('media, are you sure?'));
} else if (action === 'enable-download') {
setShowConfirmModal(true);
setPendingAction(action);
@@ -165,6 +169,8 @@ export function useBulkActions() {
executeEnableComments();
} else if (action === 'disable-comments') {
executeDisableComments();
+ } else if (action === 'delete-comments') {
+ executeDeleteComments();
} else if (action === 'enable-download') {
executeEnableDownload();
} else if (action === 'disable-download') {
@@ -271,6 +277,37 @@ export function useBulkActions() {
});
};
+ // Execute delete comments
+ const executeDeleteComments = () => {
+ const selectedIds = Array.from(selectedMedia);
+
+ fetch('/api/v1/media/user/bulk_actions', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-CSRFToken': getCsrfToken(),
+ },
+ body: JSON.stringify({
+ action: 'delete_comments',
+ media_ids: selectedIds,
+ }),
+ })
+ .then((response) => {
+ if (!response.ok) {
+ throw new Error('Failed to delete comments');
+ }
+ return response.json();
+ })
+ .then((data) => {
+ showNotificationMessage(translateString('Successfully deleted comments'));
+ clearSelection();
+ })
+ .catch((error) => {
+ showNotificationMessage(translateString('Failed to delete comments.'), 'error');
+ clearSelection();
+ });
+ };
+
// Execute enable download
const executeEnableDownload = () => {
const selectedIds = Array.from(selectedMedia);