add delete button & fix it error handel with toast

This commit is contained in:
haakel 2024-06-19 14:24:57 +03:30
parent afb97f51bb
commit 095e0a05e7
4 changed files with 250 additions and 55 deletions

View File

@ -9,7 +9,6 @@
color: #fff; color: #fff;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
} }
.audio-diary-admin-page #recording-button { .audio-diary-admin-page #recording-button {
background-color: red; background-color: red;
color: white; color: white;
@ -56,25 +55,26 @@
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* سایه برای دادن عمق */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* سایه برای دادن عمق */
} }
#visualizer { .audio-diary-admin-list-page #visualizer {
background-color: #f9f9f9; /* پس‌زمینه ملایم */ background-color: #f9f9f9; /* پس‌زمینه ملایم */
border-radius: 8px; border-radius: 8px;
border: 1px solid #ccc; border: 1px solid #ccc;
} }
.audio-diary-admin-list-page table {
.wrap table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
} }
.wrap th, .wrap td { .audio-diary-admin-list-page th,
.audio-diary-admin-list-page td {
border: 1px solid #ddd; border: 1px solid #ddd;
padding: 8px; padding: 8px;
} }
.wrap th { .audio-diary-admin-list-page th {
background-color: #f2f2f2; background-color: #f2f2f2;
text-align: left; text-align: left;
} }

View File

@ -20,20 +20,18 @@ jQuery(document).ready(function($) {
requestAnimationFrame(draw); requestAnimationFrame(draw);
analyser.getByteTimeDomainData(dataArray); analyser.getByteTimeDomainData(dataArray);
canvasCtx.clearRect(0, 0, canvas.width, canvas.height); // حذف پس‌زمینه سیاه canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
// تنظیمات خط وسط
const centerY = canvas.height / 2; const centerY = canvas.height / 2;
canvasCtx.beginPath(); canvasCtx.beginPath();
canvasCtx.moveTo(0, centerY); canvasCtx.moveTo(0, centerY);
canvasCtx.lineTo(canvas.width, 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.lineWidth = 1;
canvasCtx.stroke(); canvasCtx.stroke();
// تنظیمات خط موج صدا
canvasCtx.lineWidth = 2; canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = 'rgb(0, 0, 0)'; // خط موج صدا مشکی canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
canvasCtx.beginPath(); canvasCtx.beginPath();
let sliceWidth = canvas.width * 1.0 / bufferLength; let sliceWidth = canvas.width * 1.0 / bufferLength;
@ -90,31 +88,31 @@ jQuery(document).ready(function($) {
success: function(response) { success: function(response) {
if (response.success) { if (response.success) {
$.toast({ $.toast({
text: "Audio saved successfully", // Text that is to be shown in the toast text: "Audio saved successfully",
heading: 'Note', // Optional heading to be shown on the toast heading: 'Note',
icon: 'success', // Type of toast icon icon: 'success',
showHideTransition: 'fade', // fade, slide or plain showHideTransition: 'fade',
allowToastClose: true, // Boolean value true or false allowToastClose: true,
hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden hideAfter: 3000,
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 stack: 3,
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 position: 'bottom-center',
textAlign: 'left', // Text alignment i.e. left, right or center textAlign: 'left',
loader: true, // Whether to show loader or not. True by default loader: true,
loaderBg: '#9EC600', // Background color of the toast loader loaderBg: '#9EC600',
}); });
} else { } else {
$.toast({ $.toast({
text: "Failed to save audio", // Text that is to be shown in the toast text: "Failed to save audio",
heading: 'Note', // Optional heading to be shown on the toast heading: 'Note',
icon: 'error', // Type of toast icon icon: 'error',
showHideTransition: 'fade', // fade, slide or plain showHideTransition: 'fade',
allowToastClose: true, // Boolean value true or false allowToastClose: true,
hideAfter: 3000, // false to make it sticky or number representing the miliseconds as time after which toast needs to be hidden hideAfter: 3000,
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 stack: 3,
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 position: 'top-center',
textAlign: 'left', // Text alignment i.e. left, right or center textAlign: 'left',
loader: true, // Whether to show loader or not. True by default loader: true,
loaderBg: '#9EC600', // Background color of the toast loader loaderBg: '#9EC600',
}); });
} }
} }
@ -123,13 +121,154 @@ jQuery(document).ready(function($) {
$('#visualizer').show(); $('#visualizer').show();
isRecording = true; isRecording = true;
$('#recording-button').css('background-color', 'green'); // تغییر رنگ دکمه به سبز برای نشان دادن حالت ضبط $('#recording-button').css('background-color', 'green');
}); });
} else { } else {
mediaRecorder.stop(); mediaRecorder.stop();
$('#visualizer').hide(); $('#visualizer').hide();
isRecording = false; 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',
});
}
});
} }
}); });
}); });

View File

@ -30,33 +30,70 @@ class Audio_Diary_Admin_Page {
add_action('admin_menu', array($this, 'add_menu_item')); add_action('admin_menu', array($this, 'add_menu_item'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts')); add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('wp_ajax_save_audio', array($this, 'save_audio')); 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(); $this->create_audio_folder();
} }
function delete_audio_files() { function delete_audio() {
check_ajax_referer('audio-diary-nonce', '_ajax_nonce'); if (!current_user_can('manage_options')) {
wp_send_json_error('Unauthorized');
return;
}
if (!isset($_POST['files']) || !is_array($_POST['files'])) { if (empty($_POST['file_name'])) {
wp_send_json_error('Invalid request'); 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(); $uploads = wp_upload_dir();
$audio_dir = $uploads['basedir'] . '/audio-diary/'; $base_path = $uploads['basedir'] . '/audio-diary/';
$deleted = []; $errors = [];
foreach ($_POST['files'] as $file) { foreach ($_POST['files'] as $file_name) {
$file_path = $audio_dir . basename($file); $file_name = sanitize_file_name($file_name);
if (file_exists($file_path) && unlink($file_path)) { $file_path = $base_path . $file_name;
$deleted[] = $file;
if (file_exists($file_path)) {
if (!unlink($file_path)) {
$errors[] = $file_name;
}
} else {
$errors[] = $file_name;
} }
} }
if (empty($deleted)) { if (empty($errors)) {
wp_send_json_error('No files deleted'); 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() { public function add_menu_item() {
add_menu_page( add_menu_page(
@ -103,7 +140,7 @@ class Audio_Diary_Admin_Page {
wp_mkdir_p($audio_dir); wp_mkdir_p($audio_dir);
} }
} }
public function save_audio() { public function save_audio() {
if (!current_user_can('manage_options')) { if (!current_user_can('manage_options')) {
wp_send_json_error('Unauthorized'); wp_send_json_error('Unauthorized');
return; return;
@ -118,9 +155,15 @@ class Audio_Diary_Admin_Page {
$uploads = wp_upload_dir(); $uploads = wp_upload_dir();
$upload_path = $uploads['basedir'] . '/audio-diary/'; $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_name = 'audio-' . time() . '.wav';
$file_path = $upload_path . $file_name; $file_path = $upload_path . $file_name;
// Move the uploaded file to the audio-diary directory
if (move_uploaded_file($file['tmp_name'], $file_path)) { if (move_uploaded_file($file['tmp_name'], $file_path)) {
wp_send_json_success('File uploaded'); wp_send_json_success('File uploaded');
} else { } else {
@ -128,5 +171,6 @@ class Audio_Diary_Admin_Page {
} }
} }
} }
Audio_Diary_Admin_Page::get_instance(); Audio_Diary_Admin_Page::get_instance();

View File

@ -2,19 +2,25 @@
$uploads = wp_upload_dir(); $uploads = wp_upload_dir();
$audio_files = glob($uploads['basedir'] . '/audio-diary/*.wav'); $audio_files = glob($uploads['basedir'] . '/audio-diary/*.wav');
if (!is_array($audio_files)) {
$audio_files = [];
}
usort($audio_files, function($a, $b) { usort($audio_files, function($a, $b) {
return filemtime($b) - filemtime($a); return filemtime($b) - filemtime($a);
}); });
?> ?>
<div class="wrap"> <div class="wrap audio-diary-admin-list-page">
<h1><?php _e('Recorded Audios', 'audio-diary'); ?></h1> <h1><?php _e('Recorded Audios', 'audio-diary'); ?></h1>
<button id="delete-selected"><?php _e('Delete Selected', 'audio-diary'); ?></button>
<table> <table>
<thead> <thead>
<tr> <tr>
<th><?php _e('Select', 'audio-diary'); ?></th>
<th><?php _e('Date', 'audio-diary'); ?></th> <th><?php _e('Date', 'audio-diary'); ?></th>
<th><?php _e('Time', 'audio-diary'); ?></th> <th><?php _e('Time', 'audio-diary'); ?></th>
<th><?php _e('Audio', 'audio-diary'); ?></th> <th><?php _e('Audio', 'audio-diary'); ?></th>
<th><?php _e('Delete', 'audio-diary'); ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -22,13 +28,19 @@ usort($audio_files, function($a, $b) {
$file_date = date("Y-m-d", filemtime($file)); $file_date = date("Y-m-d", filemtime($file));
$file_time = date("H:i:s", filemtime($file)); $file_time = date("H:i:s", filemtime($file));
$file_url = $uploads['baseurl'] . '/audio-diary/' . basename($file); $file_url = $uploads['baseurl'] . '/audio-diary/' . basename($file);
$file_name = basename($file);
?> ?>
<tr> <tr>
<td><input type="checkbox" class="select-audio" value="<?php echo $file_name; ?>"></td>
<td><?php echo $file_date; ?></td> <td><?php echo $file_date; ?></td>
<td><?php echo $file_time; ?></td> <td><?php echo $file_time; ?></td>
<td> <td>
<audio controls src="<?php echo $file_url; ?>"></audio> <audio controls src="<?php echo $file_url; ?>"></audio>
</td> </td>
<td>
<button class="delete-audio"
data-file="<?php echo $file_name; ?>"><?php _e('Delete', 'audio-diary'); ?></button>
</td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>