Compare commits
3 Commits
4d27f4579a
...
be5dbbdbf2
Author | SHA1 | Date | |
---|---|---|---|
be5dbbdbf2 | |||
a2eac6f792 | |||
3afd26333f |
@ -162,7 +162,49 @@ function generateSlug($title) {
|
|||||||
<script src="../assets/js/story-edit.js"></script>
|
<script src="../assets/js/story-edit.js"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Configuration de l'éditeur de description - identique à l'éditeur de chapitres
|
// Configuration de l'éditeur de description
|
||||||
|
// Récupérer le storyId depuis l'input caché ou l'URL
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const currentStoryId = document.querySelector('input[name="id"]')?.value || urlParams.get('id');
|
||||||
|
|
||||||
|
// Configuration des handlers pour les images
|
||||||
|
const imageUploadHandler = (editor) => {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.setAttribute('type', 'file');
|
||||||
|
input.setAttribute('accept', 'image/*');
|
||||||
|
input.click();
|
||||||
|
|
||||||
|
input.onchange = async () => {
|
||||||
|
const file = input.files[0];
|
||||||
|
if (file) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('image', file);
|
||||||
|
formData.append('storyId', currentStoryId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('api/upload-image.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error('Upload failed');
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success) {
|
||||||
|
const range = editor.getSelection(true);
|
||||||
|
editor.insertEmbed(range.index, 'image', result.url);
|
||||||
|
editor.setSelection(range.index + 1);
|
||||||
|
} else {
|
||||||
|
showNotification(result.error || 'Erreur lors de l\'upload', 'error');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
showNotification('Erreur lors de l\'upload de l\'image', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const descriptionEditor = new Quill('#descriptionEditor', {
|
const descriptionEditor = new Quill('#descriptionEditor', {
|
||||||
theme: 'snow',
|
theme: 'snow',
|
||||||
modules: {
|
modules: {
|
||||||
@ -184,40 +226,7 @@ function generateSlug($title) {
|
|||||||
],
|
],
|
||||||
handlers: {
|
handlers: {
|
||||||
image: function() {
|
image: function() {
|
||||||
const input = document.createElement('input');
|
imageUploadHandler(descriptionEditor);
|
||||||
input.setAttribute('type', 'file');
|
|
||||||
input.setAttribute('accept', 'image/*');
|
|
||||||
input.click();
|
|
||||||
|
|
||||||
input.onchange = async () => {
|
|
||||||
const file = input.files[0];
|
|
||||||
if (file) {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('image', file);
|
|
||||||
formData.append('storyId', storyId);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('api/upload-image.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) throw new Error('Upload failed');
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
if (result.success) {
|
|
||||||
const range = descriptionEditor.getSelection(true);
|
|
||||||
descriptionEditor.insertEmbed(range.index, 'image', result.url);
|
|
||||||
descriptionEditor.setSelection(range.index + 1);
|
|
||||||
} else {
|
|
||||||
showNotification(result.error || 'Erreur lors de l\'upload', 'error');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error:', error);
|
|
||||||
showNotification('Erreur lors de l\'upload de l\'image', 'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
14
chapitre.php
14
chapitre.php
@ -79,12 +79,14 @@ function deltaToHtml($content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Gérer les images
|
// Gérer les images
|
||||||
elseif (is_array($op['insert']) && isset($op['insert']['image'])) {
|
elseif (is_array($op['insert']) && isset($op['insert']['image'])) {
|
||||||
$imageUrl = htmlspecialchars($op['insert']['image']);
|
$imageUrl = $op['insert']['image'];
|
||||||
// Retirer le "../" du début de l'URL si présent
|
error_log('URL originale: ' . $imageUrl);
|
||||||
$imageUrl = preg_replace('/^\.\.\//', '', $imageUrl);
|
// Retirer tous les "../" au début de l'URL
|
||||||
$html .= "<img src=\"{$imageUrl}\" alt=\"Image du chapitre\">";
|
$imageUrl = preg_replace('/^(?:\.\.\/)+/', '', $imageUrl);
|
||||||
}
|
error_log('URL nettoyée: ' . $imageUrl);
|
||||||
|
$html .= "<img src=\"{$imageUrl}\" alt=\"Image du chapitre\">";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Envelopper le contenu dans des balises p si nécessaire
|
// Envelopper le contenu dans des balises p si nécessaire
|
||||||
|
76
roman.php
76
roman.php
@ -16,6 +16,80 @@ if (!$story) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction pour convertir le contenu Delta en HTML
|
||||||
|
function deltaToHtml($content) {
|
||||||
|
if (empty($content)) return '';
|
||||||
|
|
||||||
|
// Si le contenu est déjà en HTML (ancien format)
|
||||||
|
if (is_string($content) && !isJson($content)) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convertir la chaîne JSON en tableau si nécessaire
|
||||||
|
if (is_string($content)) {
|
||||||
|
$delta = json_decode($content, true);
|
||||||
|
} else {
|
||||||
|
$delta = $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($delta['ops'])) return '';
|
||||||
|
|
||||||
|
$html = '';
|
||||||
|
foreach ($delta['ops'] as $op) {
|
||||||
|
if (is_string($op['insert'])) {
|
||||||
|
$text = htmlspecialchars($op['insert']);
|
||||||
|
|
||||||
|
// Gérer les styles de texte
|
||||||
|
if (isset($op['attributes'])) {
|
||||||
|
if (!empty($op['attributes']['bold'])) {
|
||||||
|
$text = "<strong>{$text}</strong>";
|
||||||
|
}
|
||||||
|
if (!empty($op['attributes']['italic'])) {
|
||||||
|
$text = "<em>{$text}</em>";
|
||||||
|
}
|
||||||
|
if (!empty($op['attributes']['underline'])) {
|
||||||
|
$text = "<u>{$text}</u>";
|
||||||
|
}
|
||||||
|
// Ajouter d'autres styles si nécessaire
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convertir les retours à la ligne en paragraphes
|
||||||
|
if ($text === "\n") {
|
||||||
|
$html .= "<br>";
|
||||||
|
} else {
|
||||||
|
$html .= $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Gérer les images
|
||||||
|
elseif (is_array($op['insert']) && isset($op['insert']['image'])) {
|
||||||
|
$imageUrl = $op['insert']['image'];
|
||||||
|
error_log('URL originale: ' . $imageUrl);
|
||||||
|
// Retirer tous les "../" au début de l'URL
|
||||||
|
$imageUrl = preg_replace('/^(?:\.\.\/)+/', '', $imageUrl);
|
||||||
|
error_log('URL nettoyée: ' . $imageUrl);
|
||||||
|
$html .= "<img src=\"{$imageUrl}\" alt=\"Image du chapitre\">";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Envelopper le contenu dans des balises p si nécessaire
|
||||||
|
if (!empty($html)) {
|
||||||
|
$paragraphs = explode("\n\n", $html);
|
||||||
|
$html = '';
|
||||||
|
foreach ($paragraphs as $p) {
|
||||||
|
if (trim($p) !== '') {
|
||||||
|
$html .= "<p>{$p}</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isJson($string) {
|
||||||
|
json_decode($string);
|
||||||
|
return json_last_error() === JSON_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
$config = Config::load();
|
$config = Config::load();
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -45,7 +119,7 @@ $config = Config::load();
|
|||||||
<!-- Contenu principal -->
|
<!-- Contenu principal -->
|
||||||
<div class="novel-content">
|
<div class="novel-content">
|
||||||
<div class="novel-description">
|
<div class="novel-description">
|
||||||
<?= $story['description'] ?>
|
<?= deltaToHtml($story['description']) ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<aside class="chapters-menu">
|
<aside class="chapters-menu">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user