From 095e0a05e7be22c163aa1cdcf4d02cf8c5fdf101 Mon Sep 17 00:00:00 2001 From: haakel Date: Wed, 19 Jun 2024 14:24:57 +0330 Subject: [PATCH] add delete button & fix it error handel with toast --- assets/css/style.css | 12 +- assets/js/audio-diary.js | 201 ++++++++++++++++++++---- classes/class_admin_page.php | 76 +++++++-- modules/audio-diary-admin-list-page.php | 16 +- 4 files changed, 250 insertions(+), 55 deletions(-) diff --git a/assets/css/style.css b/assets/css/style.css index 5c04636..b7585d9 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -9,7 +9,6 @@ color: #fff; font-family: Arial, sans-serif; } - .audio-diary-admin-page #recording-button { background-color: red; color: white; @@ -56,25 +55,26 @@ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* سایه برای دادن عمق */ } -#visualizer { +.audio-diary-admin-list-page #visualizer { background-color: #f9f9f9; /* پس‌زمینه ملایم */ border-radius: 8px; border: 1px solid #ccc; } - -.wrap table { +.audio-diary-admin-list-page table { width: 100%; border-collapse: collapse; } -.wrap th, .wrap td { +.audio-diary-admin-list-page th, +.audio-diary-admin-list-page td { border: 1px solid #ddd; padding: 8px; } -.wrap th { +.audio-diary-admin-list-page th { background-color: #f2f2f2; text-align: left; } + diff --git a/assets/js/audio-diary.js b/assets/js/audio-diary.js index 86d07c5..9944562 100644 --- a/assets/js/audio-diary.js +++ b/assets/js/audio-diary.js @@ -16,24 +16,22 @@ jQuery(document).ready(function($) { const canvas = document.getElementById('visualizer'); const canvasCtx = canvas.getContext('2d'); - function draw() { + function draw() { requestAnimationFrame(draw); analyser.getByteTimeDomainData(dataArray); - canvasCtx.clearRect(0, 0, canvas.width, canvas.height); // حذف پس‌زمینه سیاه + canvasCtx.clearRect(0, 0, canvas.width, canvas.height); - // تنظیمات خط وسط const centerY = canvas.height / 2; canvasCtx.beginPath(); canvasCtx.moveTo(0, centerY); canvasCtx.lineTo(canvas.width, centerY); - canvasCtx.strokeStyle = 'rgba(0, 0, 0, 0.2)'; // خط وسط نیمه شفاف + canvasCtx.strokeStyle = 'rgba(0, 0, 0, 0.2)'; canvasCtx.lineWidth = 1; canvasCtx.stroke(); - // تنظیمات خط موج صدا canvasCtx.lineWidth = 2; - canvasCtx.strokeStyle = 'rgb(0, 0, 0)'; // خط موج صدا مشکی + canvasCtx.strokeStyle = 'rgb(0, 0, 0)'; canvasCtx.beginPath(); let sliceWidth = canvas.width * 1.0 / bufferLength; @@ -90,31 +88,31 @@ jQuery(document).ready(function($) { success: function(response) { if (response.success) { $.toast({ - text: "Audio saved successfully", // Text that is to be shown in the toast - heading: 'Note', // Optional heading to be shown on the toast - icon: 'success', // Type of toast icon - showHideTransition: 'fade', // fade, slide or plain - allowToastClose: true, // Boolean value true or false - hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden - stack: 3, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time - position: 'bottom-center', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values - textAlign: 'left', // Text alignment i.e. left, right or center - loader: true, // Whether to show loader or not. True by default - loaderBg: '#9EC600', // Background color of the toast loader + text: "Audio saved successfully", + heading: 'Note', + icon: 'success', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'bottom-center', + textAlign: 'left', + loader: true, + loaderBg: '#9EC600', }); } else { $.toast({ - text: "Failed to save audio", // Text that is to be shown in the toast - heading: 'Note', // Optional heading to be shown on the toast - icon: 'error', // Type of toast icon - showHideTransition: 'fade', // fade, slide or plain - allowToastClose: true, // Boolean value true or false - hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden - stack: 3, // false if there should be only one toast at a time or a number representing the maximum number of toasts to be shown at a time - position: 'top-center', // bottom-left or bottom-right or bottom-center or top-left or top-right or top-center or mid-center or an object representing the left, right, top, bottom values - textAlign: 'left', // Text alignment i.e. left, right or center - loader: true, // Whether to show loader or not. True by default - loaderBg: '#9EC600', // Background color of the toast loader + text: "Failed to save audio", + heading: 'Note', + icon: 'error', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'top-center', + textAlign: 'left', + loader: true, + loaderBg: '#9EC600', }); } } @@ -123,13 +121,154 @@ jQuery(document).ready(function($) { $('#visualizer').show(); isRecording = true; - $('#recording-button').css('background-color', 'green'); // تغییر رنگ دکمه به سبز برای نشان دادن حالت ضبط + $('#recording-button').css('background-color', 'green'); }); } else { mediaRecorder.stop(); $('#visualizer').hide(); isRecording = false; - $('#recording-button').css('background-color', 'red'); // بازگشت به رنگ قرمز + $('#recording-button').css('background-color', 'red'); } }); -}); + + $('.delete-audio').on('click', function() { + let fileName = $(this).data('file'); + let $audioRow = $(this).closest('tr'); // یافتن ردیف حاوی فایل صوتی برای حذف آن + + if (confirm("Are you sure you want to delete this audio file?")) { + $.ajax({ + url: ajaxurl, + type: 'POST', + data: { + action: 'delete_audio', + file_name: fileName + }, + success: function(response) { + if (response.success) { + $.toast({ + text: "Audio file deleted successfully", + heading: 'Note', + icon: 'success', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'bottom-center', + textAlign: 'left', + loader: true, + loaderBg: '#9EC600', + }); + + // پس از حذف موفق فایل، ردیف مربوطه را از لیست حذف کنید + $audioRow.fadeOut(400, function() { + $(this).remove(); + }); + } else { + $.toast({ + text: "Failed to delete audio file: " + response.data, + heading: 'Error', + icon: 'error', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'top-center', + textAlign: 'left', + loader: true, + loaderBg: '#FF0000', + }); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log('AJAX Error: ' + textStatus + ': ' + errorThrown); + $.toast({ + text: "AJAX Error: " + textStatus + ": " + errorThrown, + heading: 'Error', + icon: 'error', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'top-center', + textAlign: 'left', + loader: true, + loaderBg: '#FF0000', + }); + } + }); + } + }); + + // حذف فایل‌های انتخاب‌شده + $('#delete-selected').on('click', function() { + let selectedFiles = []; + $('.select-audio:checked').each(function() { + selectedFiles.push($(this).val()); + }); + + if (selectedFiles.length > 0 && confirm("Are you sure you want to delete selected audio files?")) { + $.ajax({ + url: ajaxurl, + type: 'POST', + data: { + action: 'delete_selected_audios', + files: selectedFiles + }, + success: function(response) { + if (response.success) { + $.toast({ + text: "Selected audio files deleted successfully", + heading: 'Note', + icon: 'success', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'bottom-center', + textAlign: 'left', + loader: true, + loaderBg: '#9EC600', + }); + + // پس از حذف موفق فایل‌ها، لیست را به‌روزرسانی کنید + selectedFiles.forEach(function(fileName) { + $('.delete-audio[data-file="' + fileName + '"]').closest('tr').fadeOut(400, function() { + $(this).remove(); + }); + }); + } else { + $.toast({ + text: "Failed to delete selected audio files: " + response.data, + heading: 'Error', + icon: 'error', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'top-center', + textAlign: 'left', + loader: true, + loaderBg: '#FF0000', + }); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log('AJAX Error: ' + textStatus + ': ' + errorThrown); + $.toast({ + text: "AJAX Error: " + textStatus + ": " + errorThrown, + heading: 'Error', + icon: 'error', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + stack: 3, + position: 'top-center', + textAlign: 'left', + loader: true, + loaderBg: '#FF0000', + }); + } + }); + } + }); +}); \ No newline at end of file diff --git a/classes/class_admin_page.php b/classes/class_admin_page.php index b465c23..5bfd8b7 100644 --- a/classes/class_admin_page.php +++ b/classes/class_admin_page.php @@ -30,33 +30,70 @@ class Audio_Diary_Admin_Page { add_action('admin_menu', array($this, 'add_menu_item')); add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts')); add_action('wp_ajax_save_audio', array($this, 'save_audio')); - add_action('wp_ajax_delete_audio_files', 'delete_audio_files'); + add_action('wp_ajax_delete_audio', array($this, 'delete_audio')); + add_action('wp_ajax_delete_selected_audios', array($this, 'delete_selected_audios')); + + + $this->create_audio_folder(); } - function delete_audio_files() { - check_ajax_referer('audio-diary-nonce', '_ajax_nonce'); + function delete_audio() { + if (!current_user_can('manage_options')) { + wp_send_json_error('Unauthorized'); + return; + } - if (!isset($_POST['files']) || !is_array($_POST['files'])) { - wp_send_json_error('Invalid request'); + if (empty($_POST['file_name'])) { + wp_send_json_error('No file specified'); + return; + } + + $file_name = sanitize_file_name($_POST['file_name']); + $uploads = wp_upload_dir(); + $file_path = $uploads['basedir'] . '/audio-diary/' . $file_name; + + if (file_exists($file_path) && unlink($file_path)) { + wp_send_json_success('File deleted'); + } else { + $error = file_exists($file_path) ? 'Failed to delete file' : 'File does not exist'; + wp_send_json_error($error); + } + } + + function delete_selected_audios() { + if (!current_user_can('manage_options')) { + wp_send_json_error('Unauthorized'); + return; + } + + if (empty($_POST['files']) || !is_array($_POST['files'])) { + wp_send_json_error('No files specified'); + return; } $uploads = wp_upload_dir(); - $audio_dir = $uploads['basedir'] . '/audio-diary/'; - $deleted = []; + $base_path = $uploads['basedir'] . '/audio-diary/'; + $errors = []; - foreach ($_POST['files'] as $file) { - $file_path = $audio_dir . basename($file); - if (file_exists($file_path) && unlink($file_path)) { - $deleted[] = $file; + foreach ($_POST['files'] as $file_name) { + $file_name = sanitize_file_name($file_name); + $file_path = $base_path . $file_name; + + if (file_exists($file_path)) { + if (!unlink($file_path)) { + $errors[] = $file_name; + } + } else { + $errors[] = $file_name; } } - if (empty($deleted)) { - wp_send_json_error('No files deleted'); + if (empty($errors)) { + wp_send_json_success('All files deleted'); + } else { + wp_send_json_error('Failed to delete files: ' . implode(', ', $errors)); } - - wp_send_json_success($deleted); } public function add_menu_item() { add_menu_page( @@ -103,7 +140,7 @@ class Audio_Diary_Admin_Page { wp_mkdir_p($audio_dir); } } - public function save_audio() { +public function save_audio() { if (!current_user_can('manage_options')) { wp_send_json_error('Unauthorized'); return; @@ -118,9 +155,15 @@ class Audio_Diary_Admin_Page { $uploads = wp_upload_dir(); $upload_path = $uploads['basedir'] . '/audio-diary/'; + // Check if the directory exists, if not create it + if (!file_exists($upload_path)) { + wp_mkdir_p($upload_path); + } + $file_name = 'audio-' . time() . '.wav'; $file_path = $upload_path . $file_name; + // Move the uploaded file to the audio-diary directory if (move_uploaded_file($file['tmp_name'], $file_path)) { wp_send_json_success('File uploaded'); } else { @@ -128,5 +171,6 @@ class Audio_Diary_Admin_Page { } } + } Audio_Diary_Admin_Page::get_instance(); \ No newline at end of file diff --git a/modules/audio-diary-admin-list-page.php b/modules/audio-diary-admin-list-page.php index 5c79548..cb5fcde 100644 --- a/modules/audio-diary-admin-list-page.php +++ b/modules/audio-diary-admin-list-page.php @@ -2,19 +2,25 @@ $uploads = wp_upload_dir(); $audio_files = glob($uploads['basedir'] . '/audio-diary/*.wav'); +if (!is_array($audio_files)) { + $audio_files = []; +} + usort($audio_files, function($a, $b) { return filemtime($b) - filemtime($a); }); - ?> -
+

+ + + @@ -22,13 +28,19 @@ usort($audio_files, function($a, $b) { $file_date = date("Y-m-d", filemtime($file)); $file_time = date("H:i:s", filemtime($file)); $file_url = $uploads['baseurl'] . '/audio-diary/' . basename($file); + $file_name = basename($file); ?> + +
+ +