feat: prévisualisation depuis la corbeille + suppression doublon nav

- Route /trash/preview/<path> : réutilise preview_image/text/other.html
  avec from_trash=True (← Corbeille, pas de rename ni de resize)
- Nom de fichier cliquable dans la liste corbeille → aperçu
- Suppression du lien "Tableau de bord" du header (doublon avec le logo)
- Ferme #25

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Alpinux 2026-05-06 10:53:07 +02:00
parent b85056a2fb
commit 937433c0e5
6 changed files with 62 additions and 11 deletions

View file

@ -741,6 +741,41 @@ def trash_restore():
return redirect(url_for("browse", subpath=parent) if parent != "." else url_for("browse")) return redirect(url_for("browse", subpath=parent) if parent != "." else url_for("browse"))
@app.route("/trash/preview/<path:subpath>")
def trash_preview(subpath):
redir = _require_admin()
if redir:
return redir
target = (TRASH_ROOT / subpath).resolve()
if not str(target).startswith(str(TRASH_ROOT)):
abort(400)
if not target.is_file():
abort(404)
stat = target.stat()
ext = target.suffix.lower()
ctx = dict(
subpath = subpath,
filename = target.name,
filesize = _humansize(stat.st_size),
mtime = datetime.fromtimestamp(stat.st_mtime),
raw_url = url_for("trash_raw", subpath=subpath),
parent_path= None,
prev_path = None,
next_path = None,
sibling_pos= "",
ext = ext,
from_trash = True,
)
if ext in IMAGE_EXT:
ctx["meta"] = _image_meta(target)
return render_template("preview_image.html", **ctx)
if ext in TEXT_EXT:
return render_template("preview_text.html",
content=target.read_text(errors="replace"),
lang=ext.lstrip("."), **ctx)
return render_template("preview_other.html", **ctx)
@app.route("/trash/empty", methods=["POST"]) @app.route("/trash/empty", methods=["POST"])
def trash_empty(): def trash_empty():
redir = _require_admin() redir = _require_admin()

View file

@ -61,7 +61,7 @@
alt="{{ e.name }}" loading="lazy"> alt="{{ e.name }}" loading="lazy">
{% endif %} {% endif %}
{% if mode == 'trash' %} {% if mode == 'trash' %}
<span class="trash-filename">{{ e.name }}</span> <a href="{{ url_for('trash_preview', subpath=e.path) }}" class="trash-filename">{{ e.name }}</a>
{% else %} {% else %}
<a href="{{ url_for('browse', subpath=e.path) }}"> <a href="{{ url_for('browse', subpath=e.path) }}">
{{ e.name }}{% if e.is_dir %}/{% endif %} {{ e.name }}{% if e.is_dir %}/{% endif %}

View file

@ -16,8 +16,6 @@
<span>A<strong>l</strong>p<strong>inux</strong> <span class="brand-sub">Static</span></span> <span>A<strong>l</strong>p<strong>inux</strong> <span class="brand-sub">Static</span></span>
</a> </a>
<nav class="header-nav"> <nav class="header-nav">
<a href="{{ url_for('dashboard') }}"
{% if request.endpoint == 'dashboard' %}class="active"{% endif %}>Tableau de bord</a>
<a href="{{ url_for('browse') }}" <a href="{{ url_for('browse') }}"
{% if request.endpoint == 'browse' %}class="active"{% endif %}>Parcourir</a> {% if request.endpoint == 'browse' %}class="active"{% endif %}>Parcourir</a>
<a href="{{ url_for('stats') }}" <a href="{{ url_for('stats') }}"

View file

@ -5,18 +5,26 @@
<section class="card"> <section class="card">
<div class="preview-header"> <div class="preview-header">
{% if from_trash %}
<a href="{{ url_for('trash_list') }}" class="back-link">← Corbeille</a>
{% else %}
<a href="{{ url_for('browse', subpath=parent_path) if parent_path else url_for('browse') }}" <a href="{{ url_for('browse', subpath=parent_path) if parent_path else url_for('browse') }}"
class="back-link">← Retour</a> class="back-link">← Retour</a>
{% endif %}
<h1 id="preview-title">{{ filename }}</h1> <h1 id="preview-title">{{ filename }}</h1>
{% if not from_trash %}
<button type="button" id="rename-toggle" class="btn-icon" title="Renommer ce fichier">✏️</button> <button type="button" id="rename-toggle" class="btn-icon" title="Renommer ce fichier">✏️</button>
{% include '_preview_nav.html' %} {% include '_preview_nav.html' %}
{% endif %}
</div> </div>
{% if not from_trash %}
<div id="rename-inline" class="rename-inline" style="display:none"> <div id="rename-inline" class="rename-inline" style="display:none">
<input type="text" id="rename-input" class="rename-input" value="{{ filename }}"> <input type="text" id="rename-input" class="rename-input" value="{{ filename }}">
<button type="button" id="rename-save" class="btn-rename-ok" title="Valider"></button> <button type="button" id="rename-save" class="btn-rename-ok" title="Valider"></button>
<button type="button" id="rename-cancel" class="btn-rename-cancel" title="Annuler"></button> <button type="button" id="rename-cancel" class="btn-rename-cancel" title="Annuler"></button>
<span id="rename-error" class="rename-error"></span> <span id="rename-error" class="rename-error"></span>
</div> </div>
{% endif %}
<div class="preview-meta"> <div class="preview-meta">
<span>Taille : <strong>{{ filesize }}</strong></span> <span>Taille : <strong>{{ filesize }}</strong></span>
<span>Modifié : <strong>{{ mtime.strftime('%d/%m/%Y %H:%M') }}</strong></span> <span>Modifié : <strong>{{ mtime.strftime('%d/%m/%Y %H:%M') }}</strong></span>
@ -88,6 +96,7 @@
<img src="{{ raw_url }}" alt="{{ filename }}"> <img src="{{ raw_url }}" alt="{{ filename }}">
</div> </div>
{% if not from_trash %}
<section class="card resize-card"> <section class="card resize-card">
<h2>Créer des copies redimensionnées</h2> <h2>Créer des copies redimensionnées</h2>
<div class="resize-body"> <div class="resize-body">
@ -365,5 +374,6 @@
}); });
})(); })();
</script> </script>
{% endif %}{# from_trash #}
{% endblock %} {% endblock %}

View file

@ -5,10 +5,14 @@
<section class="card"> <section class="card">
<div class="preview-header"> <div class="preview-header">
{% if from_trash %}
<a href="{{ url_for('trash_list') }}" class="back-link">← Corbeille</a>
{% else %}
<a href="{{ url_for('browse', subpath=parent_path) if parent_path else url_for('browse') }}" <a href="{{ url_for('browse', subpath=parent_path) if parent_path else url_for('browse') }}"
class="back-link">← Retour</a> class="back-link">← Retour</a>
{% endif %}
<h1>{{ filename }}</h1> <h1>{{ filename }}</h1>
{% include '_preview_nav.html' %} {% if not from_trash %}{% include '_preview_nav.html' %}{% endif %}
</div> </div>
<div class="preview-meta"> <div class="preview-meta">
<span>Taille : <strong>{{ filesize }}</strong></span> <span>Taille : <strong>{{ filesize }}</strong></span>

View file

@ -5,10 +5,14 @@
<section class="card"> <section class="card">
<div class="preview-header"> <div class="preview-header">
{% if from_trash %}
<a href="{{ url_for('trash_list') }}" class="back-link">← Corbeille</a>
{% else %}
<a href="{{ url_for('browse', subpath=parent_path) if parent_path else url_for('browse') }}" <a href="{{ url_for('browse', subpath=parent_path) if parent_path else url_for('browse') }}"
class="back-link">← Retour</a> class="back-link">← Retour</a>
{% endif %}
<h1>{{ filename }}</h1> <h1>{{ filename }}</h1>
{% include '_preview_nav.html' %} {% if not from_trash %}{% include '_preview_nav.html' %}{% endif %}
</div> </div>
<div class="preview-meta"> <div class="preview-meta">
<span>Taille : <strong>{{ filesize }}</strong></span> <span>Taille : <strong>{{ filesize }}</strong></span>