add delete button & fix it error handel with toast
This commit is contained in:
parent
afb97f51bb
commit
095e0a05e7
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -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();
|
||||
|
|
@ -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);
|
||||
});
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="wrap audio-diary-admin-list-page">
|
||||
<h1><?php _e('Recorded Audios', 'audio-diary'); ?></h1>
|
||||
<button id="delete-selected"><?php _e('Delete Selected', 'audio-diary'); ?></button>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Select', 'audio-diary'); ?></th>
|
||||
<th><?php _e('Date', 'audio-diary'); ?></th>
|
||||
<th><?php _e('Time', 'audio-diary'); ?></th>
|
||||
<th><?php _e('Audio', 'audio-diary'); ?></th>
|
||||
<th><?php _e('Delete', 'audio-diary'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -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);
|
||||
?>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="select-audio" value="<?php echo $file_name; ?>"></td>
|
||||
<td><?php echo $file_date; ?></td>
|
||||
<td><?php echo $file_time; ?></td>
|
||||
<td>
|
||||
<audio controls src="<?php echo $file_url; ?>"></audio>
|
||||
</td>
|
||||
<td>
|
||||
<button class="delete-audio"
|
||||
data-file="<?php echo $file_name; ?>"><?php _e('Delete', 'audio-diary'); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
|
|
|||
Loading…
Reference in New Issue