Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
dd2913337f | |||
6ec572ef0c | |||
d5754b0277 | |||
a625ee63d3 |
@ -82,7 +82,8 @@ class AboutImageUploadHandler {
|
|||||||
// Retourner le chemin relatif pour l'éditeur
|
// Retourner le chemin relatif pour l'éditeur
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'url' => 'assets/images/about/' . $filename,
|
'url' => $filename,
|
||||||
|
'storage_url' => 'assets/images/about/' . $filename,
|
||||||
'width' => $needsResize ? $newWidth : $width,
|
'width' => $needsResize ? $newWidth : $width,
|
||||||
'height' => $needsResize ? $newHeight : $height
|
'height' => $needsResize ? $newHeight : $height
|
||||||
];
|
];
|
||||||
|
125
admin/api/clean-media.php
Normal file
125
admin/api/clean-media.php
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../../includes/config.php';
|
||||||
|
require_once '../../includes/auth.php';
|
||||||
|
require_once '../../includes/stories.php';
|
||||||
|
|
||||||
|
// Vérification de l'authentification
|
||||||
|
if (!Auth::check()) {
|
||||||
|
http_response_code(401);
|
||||||
|
exit(json_encode(['error' => 'Non autorisé']));
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractImagePaths($content) {
|
||||||
|
$paths = [];
|
||||||
|
|
||||||
|
// Si le contenu est du JSON (format Delta de Quill)
|
||||||
|
if (is_string($content) && isJson($content)) {
|
||||||
|
$delta = json_decode($content, true);
|
||||||
|
if (isset($delta['ops'])) {
|
||||||
|
foreach ($delta['ops'] as $op) {
|
||||||
|
if (isset($op['insert']['image'])) {
|
||||||
|
$paths[] = normalizeImagePath($op['insert']['image']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Si le contenu est du HTML
|
||||||
|
preg_match_all('/src=["\']([^"\']+)["\']/', $content, $matches);
|
||||||
|
if (!empty($matches[1])) {
|
||||||
|
foreach ($matches[1] as $path) {
|
||||||
|
$paths[] = normalizeImagePath($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeImagePath($path) {
|
||||||
|
// Supprimer les "../" au début du chemin
|
||||||
|
$path = preg_replace('/^(?:\.\.\/)+/', '', $path);
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isJson($string) {
|
||||||
|
json_decode($string);
|
||||||
|
return json_last_error() === JSON_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$unusedFiles = [];
|
||||||
|
$usedFiles = [];
|
||||||
|
$totalSpace = 0;
|
||||||
|
$freedSpace = 0;
|
||||||
|
|
||||||
|
// Collecter tous les fichiers dans le dossier chapters
|
||||||
|
$chaptersDir = __DIR__ . '/../../assets/images/chapters/';
|
||||||
|
$allFiles = [];
|
||||||
|
|
||||||
|
foreach (glob($chaptersDir . '*', GLOB_ONLYDIR) as $storyDir) {
|
||||||
|
$storyId = basename($storyDir);
|
||||||
|
foreach (glob($storyDir . '/*') as $file) {
|
||||||
|
if (is_file($file)) {
|
||||||
|
$relativePath = 'assets/images/chapters/' . $storyId . '/' . basename($file);
|
||||||
|
$allFiles[$relativePath] = $file;
|
||||||
|
$totalSpace += filesize($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parcourir tous les romans et leurs chapitres
|
||||||
|
$stories = Stories::getAll();
|
||||||
|
foreach ($stories as $story) {
|
||||||
|
// Vérifier la description du roman
|
||||||
|
if (!empty($story['description'])) {
|
||||||
|
$usedFiles = array_merge($usedFiles, extractImagePaths($story['description']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier les chapitres
|
||||||
|
if (!empty($story['chapters'])) {
|
||||||
|
foreach ($story['chapters'] as $chapter) {
|
||||||
|
if (!empty($chapter['content'])) {
|
||||||
|
$usedFiles = array_merge($usedFiles, extractImagePaths($chapter['content']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identifier les fichiers non utilisés
|
||||||
|
foreach ($allFiles as $relativePath => $fullPath) {
|
||||||
|
if (!in_array($relativePath, $usedFiles)) {
|
||||||
|
$unusedFiles[] = [
|
||||||
|
'path' => $relativePath,
|
||||||
|
'size' => filesize($fullPath)
|
||||||
|
];
|
||||||
|
$freedSpace += filesize($fullPath);
|
||||||
|
|
||||||
|
// Supprimer le fichier
|
||||||
|
unlink($fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nettoyer les dossiers vides
|
||||||
|
foreach (glob($chaptersDir . '*', GLOB_ONLYDIR) as $storyDir) {
|
||||||
|
if (count(glob("$storyDir/*")) === 0) {
|
||||||
|
rmdir($storyDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'stats' => [
|
||||||
|
'filesRemoved' => count($unusedFiles),
|
||||||
|
'totalSpace' => $totalSpace,
|
||||||
|
'freedSpace' => $freedSpace,
|
||||||
|
'details' => $unusedFiles
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
@ -212,8 +212,14 @@ $config = Config::load();
|
|||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" id="addLink" class="button">Ajouter un lien</button>
|
<button type="button" id="addLink" class="button">Ajouter un lien</button>
|
||||||
|
<br />
|
||||||
<button type="submit" class="button submit-button">Enregistrer les modifications</button>
|
<button type="submit" class="button submit-button">Enregistrer les modifications</button>
|
||||||
|
<!-- Section Nettoyage des médias -->
|
||||||
|
<h2>Maintenance</h2>
|
||||||
|
<div class="maintenance-actions">
|
||||||
|
<button type="button" id="cleanMedia" class="button">Nettoyer les médias inutilisés</button>
|
||||||
|
<small>Supprime les images qui ne sont plus utilisées dans les romans et chapitres.</small>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
/* Conteneur principal du contenu */
|
/* Conteneur principal du contenu */
|
||||||
.chapter-content,
|
.chapter-content,
|
||||||
.novel-description {
|
.novel-description,
|
||||||
|
.about-description {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
@ -24,34 +25,47 @@
|
|||||||
.novel-description h3,
|
.novel-description h3,
|
||||||
.novel-description h4,
|
.novel-description h4,
|
||||||
.novel-description h5,
|
.novel-description h5,
|
||||||
.novel-description h6 {
|
.novel-description h6,
|
||||||
|
.about-description h1,
|
||||||
|
.about-description h2,
|
||||||
|
.about-description h3,
|
||||||
|
.about-description h4,
|
||||||
|
.about-description h5,
|
||||||
|
.about-description h6 {
|
||||||
margin: 1.5em 0 0.8em;
|
margin: 1.5em 0 0.8em;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter-content h1,
|
.chapter-content h1,
|
||||||
.novel-description h1 { font-size: 2em; }
|
.novel-description h1,
|
||||||
|
.about-description h1 { font-size: 2em; }
|
||||||
|
|
||||||
.chapter-content h2,
|
.chapter-content h2,
|
||||||
.novel-description h2 { font-size: 1.75em; }
|
.novel-description h2,
|
||||||
|
.about-description h2 { font-size: 1.75em; }
|
||||||
|
|
||||||
.chapter-content h3,
|
.chapter-content h3,
|
||||||
.novel-description h3 { font-size: 1.5em; }
|
.novel-description h3,
|
||||||
|
.about-description h3 { font-size: 1.5em; }
|
||||||
|
|
||||||
.chapter-content h4,
|
.chapter-content h4,
|
||||||
.novel-description h4 { font-size: 1.25em; }
|
.novel-description h4,
|
||||||
|
.about-description h4 { font-size: 1.25em; }
|
||||||
|
|
||||||
.chapter-content h5,
|
.chapter-content h5,
|
||||||
.novel-description h5 { font-size: 1.1em; }
|
.novel-description h5,
|
||||||
|
.about-description h5 { font-size: 1.1em; }
|
||||||
|
|
||||||
.chapter-content h6,
|
.chapter-content h6,
|
||||||
.novel-description h6 { font-size: 1em; }
|
.novel-description h6,
|
||||||
|
.about-description h6 { font-size: 1em; }
|
||||||
|
|
||||||
/* Paragraphes et espacement */
|
/* Paragraphes et espacement */
|
||||||
.chapter-content p,
|
.chapter-content p,
|
||||||
.novel-description p {
|
.novel-description p,
|
||||||
margin: 0 0 0em 0;
|
.about-description p {
|
||||||
|
margin: 0em 0;
|
||||||
min-height: 1.5em;
|
min-height: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,21 +73,25 @@
|
|||||||
.chapter-content ul,
|
.chapter-content ul,
|
||||||
.chapter-content ol,
|
.chapter-content ol,
|
||||||
.novel-description ul,
|
.novel-description ul,
|
||||||
.novel-description ol {
|
.novel-description ol,
|
||||||
|
.about-description ul,
|
||||||
|
.about-description ol {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
list-style-position: outside;
|
list-style-position: outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter-content li,
|
.chapter-content li,
|
||||||
.novel-description li {
|
.novel-description li,
|
||||||
|
.about-description li {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
padding-left: 0.5em;
|
padding-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Citations */
|
/* Citations */
|
||||||
.chapter-content blockquote,
|
.chapter-content blockquote,
|
||||||
.novel-description blockquote {
|
.novel-description blockquote,
|
||||||
|
.about-description blockquote {
|
||||||
margin: 1.5em 0;
|
margin: 1.5em 0;
|
||||||
padding: 1em 1.5em;
|
padding: 1em 1.5em;
|
||||||
border-left: 4px solid var(--accent-primary);
|
border-left: 4px solid var(--accent-primary);
|
||||||
@ -85,7 +103,8 @@
|
|||||||
|
|
||||||
/* Blocs de code */
|
/* Blocs de code */
|
||||||
.chapter-content pre,
|
.chapter-content pre,
|
||||||
.novel-description pre {
|
.novel-description pre,
|
||||||
|
.about-description pre {
|
||||||
margin: 1.5em 0;
|
margin: 1.5em 0;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: var(--bg-secondary);
|
background-color: var(--bg-secondary);
|
||||||
@ -97,7 +116,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chapter-content code,
|
.chapter-content code,
|
||||||
.novel-description code {
|
.novel-description code,
|
||||||
|
.about-description code {
|
||||||
font-family: "Consolas", "Monaco", monospace;
|
font-family: "Consolas", "Monaco", monospace;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.4em;
|
||||||
@ -106,28 +126,109 @@
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Images et alignements */
|
||||||
|
.chapter-content .ql-align-left,
|
||||||
|
.novel-description .ql-align-left,
|
||||||
|
.about-description .ql-align-left {
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-content .ql-align-center,
|
||||||
|
.novel-description .ql-align-center,
|
||||||
|
.about-description .ql-align-center {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-content .ql-align-right,
|
||||||
|
.novel-description .ql-align-right,
|
||||||
|
.about-description .ql-align-right {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-content .ql-align-justify,
|
||||||
|
.novel-description .ql-align-justify,
|
||||||
|
.about-description .ql-align-justify {
|
||||||
|
text-align: justify !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Images */
|
/* Images */
|
||||||
.chapter-content img,
|
.chapter-content p img,
|
||||||
.novel-description img {
|
.novel-description p img,
|
||||||
|
.about-description p img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
margin: 1.5em 0;
|
margin: 1.5em auto;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajustements spécifiques pour les images selon l'alignement */
|
||||||
|
.ql-align-left p img {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-align-center p img {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alignements */
|
.ql-align-right p img {
|
||||||
.chapter-content [style*="text-align"],
|
margin-left: auto;
|
||||||
.novel-description [style*="text-align"],
|
margin-right: 0;
|
||||||
.novel-description p[style*="text-align"] {
|
display: block;
|
||||||
display: block !important;
|
|
||||||
margin: 1em 0 !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.novel-description .font-serif,
|
/* Support des tailles d'images */
|
||||||
.novel-description .font-sans,
|
.ql-size-small img {
|
||||||
.novel-description .font-mono {
|
max-width: 50% !important;
|
||||||
display: inline-block !important;
|
}
|
||||||
|
|
||||||
|
.ql-size-large img {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles pour les liens */
|
||||||
|
.chapter-content a,
|
||||||
|
.novel-description a,
|
||||||
|
.about-description a {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-content a:hover,
|
||||||
|
.novel-description a:hover,
|
||||||
|
.about-description a:hover {
|
||||||
|
color: var(--accent-secondary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles pour les indices et exposants */
|
||||||
|
.chapter-content sub,
|
||||||
|
.novel-description sub,
|
||||||
|
.about-description sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-content sup,
|
||||||
|
.novel-description sup,
|
||||||
|
.about-description sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Barre de séparation */
|
||||||
|
.chapter-divider {
|
||||||
|
margin: 2em auto;
|
||||||
|
border: none;
|
||||||
|
border-top: 2px solid var(--accent-primary);
|
||||||
|
opacity: 0.5;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Polices */
|
/* Polices */
|
||||||
@ -143,68 +244,37 @@
|
|||||||
font-family: "Consolas", "Monaco", monospace !important;
|
font-family: "Consolas", "Monaco", monospace !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Barre de séparation */
|
|
||||||
.chapter-divider {
|
|
||||||
margin: 2em auto;
|
|
||||||
border: none;
|
|
||||||
border-top: 2px solid var(--accent-primary);
|
|
||||||
opacity: 0.5;
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles pour les liens */
|
|
||||||
.chapter-content a,
|
|
||||||
.novel-description a {
|
|
||||||
color: var(--accent-primary);
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color var(--transition-fast);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-content a:hover,
|
|
||||||
.novel-description a:hover {
|
|
||||||
color: var(--accent-secondary);
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles pour les indices et exposants */
|
|
||||||
.chapter-content sub,
|
|
||||||
.novel-description sub {
|
|
||||||
vertical-align: sub;
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-content sup,
|
|
||||||
.novel-description sup {
|
|
||||||
vertical-align: super;
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Media queries pour le responsive */
|
/* Media queries pour le responsive */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.chapter-content,
|
.chapter-content,
|
||||||
.novel-description {
|
.novel-description,
|
||||||
|
.about-description {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter-content blockquote,
|
.chapter-content blockquote,
|
||||||
.novel-description blockquote {
|
.novel-description blockquote,
|
||||||
|
.about-description blockquote {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
padding: 0.8em 1em;
|
padding: 0.8em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter-content pre,
|
.chapter-content pre,
|
||||||
.novel-description pre {
|
.novel-description pre,
|
||||||
|
.about-description pre {
|
||||||
padding: 0.8em;
|
padding: 0.8em;
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chapter-content h1,
|
.chapter-content h1,
|
||||||
.novel-description h1 { font-size: 1.75em; }
|
.novel-description h1,
|
||||||
|
.about-description h1 { font-size: 1.75em; }
|
||||||
|
|
||||||
.chapter-content h2,
|
.chapter-content h2,
|
||||||
.novel-description h2 { font-size: 1.5em; }
|
.novel-description h2,
|
||||||
|
.about-description h2 { font-size: 1.5em; }
|
||||||
|
|
||||||
.chapter-content h3,
|
.chapter-content h3,
|
||||||
.novel-description h3 { font-size: 1.25em; }
|
.novel-description h3,
|
||||||
|
.about-description h3 { font-size: 1.25em; }
|
||||||
}
|
}
|
@ -185,8 +185,23 @@
|
|||||||
/* Bouton de soumission */
|
/* Bouton de soumission */
|
||||||
.submit-button {
|
.submit-button {
|
||||||
margin-top: var(--spacing-xl);
|
margin-top: var(--spacing-xl);
|
||||||
width: 100%;
|
}
|
||||||
|
|
||||||
|
/* Nettoyage des médias */
|
||||||
|
.maintenance-actions {
|
||||||
|
margin: var(--spacing-lg) 0;
|
||||||
padding: var(--spacing-md);
|
padding: var(--spacing-md);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.maintenance-actions button {
|
||||||
|
margin-bottom: var(--spacing-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.maintenance-actions small {
|
||||||
|
display: block;
|
||||||
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Responsive */
|
/* Responsive */
|
||||||
|
@ -24,25 +24,36 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
input.setAttribute('type', 'file');
|
input.setAttribute('type', 'file');
|
||||||
input.setAttribute('accept', 'image/*');
|
input.setAttribute('accept', 'image/*');
|
||||||
input.click();
|
input.click();
|
||||||
|
|
||||||
input.onchange = async () => {
|
input.onchange = async () => {
|
||||||
const file = input.files[0];
|
const file = input.files[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('image', file);
|
formData.append('image', file);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('api/about-image-upload.php', {
|
const response = await fetch('api/about-image-upload.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) throw new Error('Upload failed');
|
if (!response.ok) throw new Error('Upload failed');
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
const range = aboutEditor.getSelection(true);
|
const range = aboutEditor.getSelection(true);
|
||||||
aboutEditor.insertEmbed(range.index, 'image', result.url);
|
// Utiliser le chemin complet pour l'affichage
|
||||||
|
aboutEditor.insertEmbed(range.index, 'image', '../' + result.storage_url);
|
||||||
|
|
||||||
|
// Mettre à jour le contenu Delta si nécessaire
|
||||||
|
const insertOp = aboutEditor.getContents().ops.find(op =>
|
||||||
|
op.insert && op.insert.image === '../' + result.storage_url
|
||||||
|
);
|
||||||
|
if (insertOp) {
|
||||||
|
// Stocker le chemin relatif
|
||||||
|
insertOp.insert.image = result.storage_url;
|
||||||
|
}
|
||||||
|
|
||||||
aboutEditor.setSelection(range.index + 1);
|
aboutEditor.setSelection(range.index + 1);
|
||||||
} else {
|
} else {
|
||||||
showNotification(result.error || 'Erreur lors de l\'upload', 'error');
|
showNotification(result.error || 'Erreur lors de l\'upload', 'error');
|
||||||
@ -181,4 +192,36 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
setTimeout(() => notification.remove(), 300);
|
setTimeout(() => notification.remove(), 300);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gestion du nettoyage des médias
|
||||||
|
const cleanMediaBtn = document.getElementById('cleanMedia');
|
||||||
|
if (cleanMediaBtn) {
|
||||||
|
cleanMediaBtn.addEventListener('click', async () => {
|
||||||
|
confirmDialog.show({
|
||||||
|
title: 'Nettoyage des médias',
|
||||||
|
message: 'Voulez-vous vraiment supprimer toutes les images qui ne sont plus utilisées ? Cette action est irréversible.',
|
||||||
|
confirmText: 'Nettoyer',
|
||||||
|
confirmClass: 'danger',
|
||||||
|
onConfirm: async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('api/clean-media.php');
|
||||||
|
if (!response.ok) throw new Error('Erreur réseau');
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success) {
|
||||||
|
const stats = result.stats;
|
||||||
|
const mbFreed = (stats.freedSpace / (1024 * 1024)).toFixed(2);
|
||||||
|
const message = `${stats.filesRemoved} fichier(s) supprimé(s).\n${mbFreed} Mo d'espace libéré.`;
|
||||||
|
showNotification(message);
|
||||||
|
} else {
|
||||||
|
throw new Error(result.error || 'Une erreur est survenue');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur:', error);
|
||||||
|
showNotification(error.message, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
@ -1 +1 @@
|
|||||||
1.1.5
|
1.1.7
|
Loading…
x
Reference in New Issue
Block a user