Nouvelle version réécrite de zéro : recherche multi-sources (Vostfree, French-Manga), extraction 2 niveaux, proxy vidéo intégré, streaming/téléchargement HLS, métadonnées Kitsu, bibliothèque locale, comptes JWT + administration, découverte fusionnée, indexeur Torznab (Sonarr/Prowlarr).
55 lines
1.8 KiB
HTML
55 lines
1.8 KiB
HTML
{% extends "base.html" %}
|
|
{% set active = 'library' %}
|
|
{% block title %}Bibliothèque — Ohm Stream{% endblock %}
|
|
|
|
{% block content %}
|
|
<h1 class="page-title">Bibliothèque</h1>
|
|
<p class="page-sub">Tes fichiers téléchargés, prêts à être regardés.</p>
|
|
|
|
<div x-data="libraryPage()" x-init="load()">
|
|
<div class="spinner" x-show="loading"></div>
|
|
|
|
<template x-if="!loading && items.length === 0">
|
|
<div class="empty-state"><div class="big">🎞️</div>Rien ici pour l'instant — télécharge des épisodes !</div>
|
|
</template>
|
|
|
|
<div class="episode-list">
|
|
<template x-for="f in items" :key="f.id">
|
|
<a class="episode-row" :href="'/watch/' + f.id">
|
|
<span style="font-size:1.3rem">🎬</span>
|
|
<span class="episode-name" style="font-weight:600" x-text="f.title"></span>
|
|
<span style="font-size:0.8rem;color:var(--text-dim)" x-text="fmtBytes(f.total_bytes)"></span>
|
|
<span x-show="f.position_seconds > 0" class="badge badge-type"
|
|
x-text="'⏵ ' + fmtTime(f.position_seconds)"></span>
|
|
<span class="btn btn-sm">▶</span>
|
|
</a>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
function libraryPage() {
|
|
return {
|
|
items: [], loading: true,
|
|
async load() {
|
|
const res = await fetch('/api/library');
|
|
this.items = await res.json();
|
|
this.loading = false;
|
|
},
|
|
fmtBytes(n) {
|
|
if (n == null) return '';
|
|
const units = ['o', 'Ko', 'Mo', 'Go']; let i = 0;
|
|
while (n >= 1024 && i < units.length - 1) { n /= 1024; i++; }
|
|
return n.toFixed(i ? 1 : 0) + ' ' + units[i];
|
|
},
|
|
fmtTime(s) {
|
|
const h = Math.floor(s / 3600), m = Math.floor((s % 3600) / 60), sec = Math.floor(s % 60);
|
|
return (h ? h + ':' + String(m).padStart(2, '0') : m) + ':' + String(sec).padStart(2, '0');
|
|
},
|
|
};
|
|
}
|
|
</script>
|
|
{% endblock %}
|