Compare commits

...

2 Commits

Author SHA1 Message Date
Tatiana Villa Ema 7211b678fd Audio Player siempre visible. Guarda por donde vas 2026-05-17 23:44:53 +02:00
Tatiana Villa Ema 7efaa919b6 Actualizacion de temario 2026-05-17 23:01:09 +02:00
7 changed files with 224 additions and 39 deletions

View File

@ -17,6 +17,7 @@
--warning: #d7ba7d; --warning: #d7ba7d;
--sidebar-w: 290px; --sidebar-w: 290px;
--topbar-h: 52px; --topbar-h: 52px;
--audio-bar-h: 64px;
} }
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
@ -314,7 +315,7 @@ a:hover { text-decoration: underline; }
PLAYER CURSO PLAYER CURSO
============================================================ */ ============================================================ */
.player-layout { .player-layout {
display: flex; display: block;
margin-top: var(--topbar-h); margin-top: var(--topbar-h);
min-height: calc(100vh - var(--topbar-h)); min-height: calc(100vh - var(--topbar-h));
} }
@ -589,6 +590,63 @@ a:hover { text-decoration: underline; }
accent-color: var(--accent); accent-color: var(--accent);
} }
/* ============================================================
AUDIO BAR barra fija inferior
============================================================ */
.audio-bar-fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
min-height: var(--audio-bar-h);
background: var(--bg-alt);
border-top: 3px solid var(--accent);
box-shadow: 0 -2px 12px rgba(0,0,0,.4);
z-index: 100;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: .6rem 1rem;
padding: .6rem 1.5rem;
transition: transform .3s ease;
}
.audio-bar-fixed.audio-bar-hidden {
transform: translateY(110%);
pointer-events: none;
}
.audio-bar-icon {
color: var(--accent);
font-size: 1rem;
flex-shrink: 0;
}
.audio-bar-title {
font-size: .75rem;
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: .06em;
flex-shrink: 0;
}
.audio-bar-controls {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .5rem;
flex: 1;
}
.audio-bar-item {
display: flex;
align-items: center;
gap: .5rem;
}
.audio-bar-fixed audio {
height: 32px;
accent-color: var(--accent);
}
body.has-audio-bar {
padding-bottom: var(--audio-bar-h);
}
/* ============================================================ /* ============================================================
CUESTIONARIOS CUESTIONARIOS
============================================================ */ ============================================================ */

View File

@ -115,20 +115,6 @@ function renderMarkdown(md, tema, bloque, bloqueId, temaNum) {
const html = marked.parse(md); const html = marked.parse(md);
const audioHtml = (tema.audios && tema.audios.length)
? `<div class="tema-audio-bar">
<i class="fas fa-headphones"></i>
<span class="tema-audio-label">Escuchar este tema</span>
${tema.audios.map(a => `
<div class="tema-audio-item">
${tema.audios.length > 1 ? `<span class="tema-audio-tag">${a.label}</span>` : ''}
<audio controls preload="none">
<source src="${a.src}" type="audio/mpeg">
</audio>
</div>`).join('')}
</div>`
: '';
const leyesHtml = (tema.leyes && tema.leyes.length) const leyesHtml = (tema.leyes && tema.leyes.length)
? `<div class="tema-leyes-bar"> ? `<div class="tema-leyes-bar">
<i class="fas fa-landmark"></i> <i class="fas fa-landmark"></i>
@ -142,7 +128,6 @@ function renderMarkdown(md, tema, bloque, bloqueId, temaNum) {
: ''; : '';
document.getElementById('lesson-content').innerHTML = ` document.getElementById('lesson-content').innerHTML = `
${audioHtml}
${leyesHtml} ${leyesHtml}
<div class="md-body">${html}</div> <div class="md-body">${html}</div>
<nav class="lesson-nav" aria-label="Navegación entre temas"> <nav class="lesson-nav" aria-label="Navegación entre temas">
@ -159,6 +144,65 @@ function renderMarkdown(md, tema, bloque, bloqueId, temaNum) {
// Actualizar progress en topbar // Actualizar progress en topbar
updateTopbarProgress(pos, total); updateTopbarProgress(pos, total);
// Barra de audio fija
updateAudioBar(tema, bloqueId, temaNum);
}
// ── Audio bar fija (bottom) ───────────────────────────────────
function updateAudioBar(tema, bloqueId, temaNum) {
const bar = document.getElementById('audio-bar');
const titleEl = document.getElementById('audio-bar-title');
const controlsEl = document.getElementById('audio-bar-controls');
if (!bar || !titleEl || !controlsEl) return;
// Parar cualquier audio en curso
bar.querySelectorAll('audio').forEach(a => a.pause());
if (!tema.audios || !tema.audios.length) {
bar.classList.add('audio-bar-hidden');
document.body.classList.remove('has-audio-bar');
return;
}
titleEl.textContent = `B${toRoman(bloqueId)} · T${temaNum}`;
controlsEl.innerHTML = tema.audios.map(a => `
<div class="audio-bar-item">
${tema.audios.length > 1 ? `<span class="tema-audio-tag">${a.label}</span>` : ''}
<audio controls preload="none" data-key="audioPos:${a.src}">
<source src="${a.src}" type="audio/mpeg">
</audio>
</div>`).join('');
// Restaurar y guardar posición por audio
controlsEl.querySelectorAll('audio').forEach(audioEl => {
const key = audioEl.dataset.key;
audioEl.addEventListener('loadedmetadata', () => {
const saved = parseFloat(localStorage.getItem(key) || '0');
if (saved > 1 && saved < audioEl.duration - 2) {
audioEl.currentTime = saved;
}
});
let _saveTimer = null;
audioEl.addEventListener('play', () => {
clearInterval(_saveTimer);
_saveTimer = setInterval(() => {
localStorage.setItem(key, audioEl.currentTime.toString());
}, 5000);
});
audioEl.addEventListener('pause', () => {
clearInterval(_saveTimer);
localStorage.setItem(key, audioEl.currentTime.toString());
});
audioEl.addEventListener('ended', () => {
clearInterval(_saveTimer);
localStorage.removeItem(key);
});
});
bar.classList.remove('audio-bar-hidden');
document.body.classList.add('has-audio-bar');
} }
function showError(msg) { function showError(msg) {

View File

@ -17,44 +17,114 @@
<link>https://taiage.tatvil.es</link> <link>https://taiage.tatvil.es</link>
</image> </image>
<item> <item>
<title>TEXTO REFUNDIDO DE LA LEY DEL ESTATUTO BÁSICO DEL EMPLEADO PÚBLICO</title> <title>Null</title>
<description>TEXTO REFUNDIDO DE LA LEY DEL ESTATUTO BÁSICO DEL EMPLEADO PÚBLICO</description> <description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/B1T4-TREBEP.mp3" length="274628844" type="audio/mpeg"/> <enclosure url="https://taiage.tatvil.es/audios/leyes/1-6-firma-electronica-BOE-A-2003-23399-consolidado.mp3" length="141757987" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/B1T4-TREBEP.mp3</guid> <guid>https://taiage.tatvil.es/audios/leyes/1-6-firma-electronica-BOE-A-2003-23399-consolidado.mp3</guid>
<pubDate>Wed, 01 Apr 2026 10:00:00 +0000</pubDate> <pubDate>Wed, 01 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>1</itunes:episode> <itunes:episode>1</itunes:episode>
<itunes:season>1</itunes:season> <itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType> <itunes:episodeType>full</itunes:episodeType>
</item> </item>
<item> <item>
<title>Ley Orgánica 3/2007, de 22 de marzo, para la igualdad efectiva de mujeres y hombres.</title> <title>Null</title>
<description>Ley Orgánica 3/2007, de 22 de marzo, para la igualdad efectiva de mujeres y hombres.</description> <description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/B1T5-igualdad-de-genero.mp3" length="316599900" type="audio/mpeg"/> <enclosure url="https://taiage.tatvil.es/audios/leyes/1-6-Sociedad-de-la-informacion-BOE-A-2002-13758-consolidado.mp3" length="183336576" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/B1T5-igualdad-de-genero.mp3</guid> <guid>https://taiage.tatvil.es/audios/leyes/1-6-Sociedad-de-la-informacion-BOE-A-2002-13758-consolidado.mp3</guid>
<pubDate>Thu, 02 Apr 2026 10:00:00 +0000</pubDate> <pubDate>Thu, 02 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>2</itunes:episode> <itunes:episode>2</itunes:episode>
<itunes:season>1</itunes:season> <itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType> <itunes:episodeType>full</itunes:episodeType>
</item> </item>
<item> <item>
<title>Ley 39/2006, de 14 de diciembre, de Promoción de la Autonomía Personal y Atención a las personas en situación de dependencia.</title> <title>Null</title>
<description>Ley 39/2006, de 14 de diciembre, de Promoción de la Autonomía Personal y Atención a las personas en situación de dependencia.</description> <description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/B1T5-ley-dependencia.mp3" length="135383871" type="audio/mpeg"/> <enclosure url="https://taiage.tatvil.es/audios/leyes/1-7-BOE-A-2018-16673-consolidado.mp3" length="363104973" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/B1T5-ley-dependencia.mp3</guid> <guid>https://taiage.tatvil.es/audios/leyes/1-7-BOE-A-2018-16673-consolidado.mp3</guid>
<pubDate>Fri, 03 Apr 2026 10:00:00 +0000</pubDate> <pubDate>Fri, 03 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>3</itunes:episode> <itunes:episode>3</itunes:episode>
<itunes:season>1</itunes:season> <itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType> <itunes:episodeType>full</itunes:episodeType>
</item> </item>
<item> <item>
<title>Ley 4/2023, de 28 de febrero, para la igualdad real y efectiva de las personas trans y para la garantía de los derechos de las personas LGTBI.</title> <title>Null</title>
<description>Ley 4/2023, de 28 de febrero, para la igualdad real y efectiva de las personas trans y para la garantía de los derechos de las personas LGTBI.</description> <description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/B1T5-ley-trans.mp3" length="302810372" type="audio/mpeg"/> <enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-1978-31229-consolidado.mp3" length="173240950" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/B1T5-ley-trans.mp3</guid> <guid>https://taiage.tatvil.es/audios/leyes/BOE-A-1978-31229-consolidado.mp3</guid>
<pubDate>Sat, 04 Apr 2026 10:00:00 +0000</pubDate> <pubDate>Sat, 04 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>4</itunes:episode> <itunes:episode>4</itunes:episode>
<itunes:season>1</itunes:season> <itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType> <itunes:episodeType>full</itunes:episodeType>
</item> </item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-1981-10325-consolidado-defensor-del-pueblo.mp3" length="39237195" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-1981-10325-consolidado-defensor-del-pueblo.mp3</guid>
<pubDate>Sun, 05 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>5</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-1981-12774-consolidado-estados-alarma-excepcion-sitio.mp3" length="34965245" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-1981-12774-consolidado-estados-alarma-excepcion-sitio.mp3</guid>
<pubDate>Mon, 06 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>6</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-1997-25336-consolidado-gobierno.mp3" length="81233932" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-1997-25336-consolidado-gobierno.mp3</guid>
<pubDate>Tue, 07 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>7</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-2004-21760-consolidado-violencia-genero.mp3" length="232731187" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-2004-21760-consolidado-violencia-genero.mp3</guid>
<pubDate>Wed, 08 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>8</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-2006-21990-consolidado-dependencia.mp3" length="135519309" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-2006-21990-consolidado-dependencia.mp3</guid>
<pubDate>Thu, 09 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>9</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-2007-6115-consolidado igualdad de genero.mp3" length="320203567" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-2007-6115-consolidado igualdad de genero.mp3</guid>
<pubDate>Fri, 10 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>10</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>Null</title>
<description>Null</description>
<enclosure url="https://taiage.tatvil.es/audios/leyes/BOE-A-2022-7191-consolidado.mp3" length="372174891" type="audio/mpeg"/>
<guid>https://taiage.tatvil.es/audios/leyes/BOE-A-2022-7191-consolidado.mp3</guid>
<pubDate>Sat, 11 Apr 2026 10:00:00 +0000</pubDate>
<itunes:episode>11</itunes:episode>
<itunes:season>1</itunes:season>
<itunes:episodeType>full</itunes:episodeType>
</item>
</channel> </channel>
</rss> </rss>

View File

@ -322,9 +322,7 @@ Mayor seguridad frente a ataques.
--- ---
## 8. Gestión de usuarios # 8. Gestión de usuarios
### 8.1. Introducción
La gestión de usuarios consiste en administrar: La gestión de usuarios consiste en administrar:
@ -388,7 +386,6 @@ Cada usuario debe tener:
- Solo los permisos necesarios. - Solo los permisos necesarios.
---
## Tipos de permisos ## Tipos de permisos
@ -408,6 +405,15 @@ Ejecutar programas.
Administración completa. Administración completa.
## Linux/Unix
- rwx (lectura, escritura, ejecución)
- comandos: chmod, chown, chgrp
## Windows
- R (lectura)
- W (escritura)
- X (ejecución)
- gestión mediante ACLs (Access Control Lists)
--- ---
# 11. Políticas de seguridad # 11. Políticas de seguridad

View File

@ -30,7 +30,7 @@
<span class="topbar-progress" id="topbar-progress">1 / 33</span> <span class="topbar-progress" id="topbar-progress">1 / 33</span>
<!-- Usuario / sesión --> <!-- Usuario / sesión -->
<div class="topbar-user"> <div class="topbar-user">
<span sec:authorize="isAuthenticated()" class="user-email" sec:authentication="principal.username"></span> <span sec:authorize="isAuthenticated()" class="user-email" th:text="${#strings.substringBefore(#authentication.name, '@')}"></span>
<a sec:authorize="hasRole('ADMIN')" th:href="@{/admin/usuarios}" class="btn-login" style="margin-right:.5rem">Admin</a> <a sec:authorize="hasRole('ADMIN')" th:href="@{/admin/usuarios}" class="btn-login" style="margin-right:.5rem">Admin</a>
<form sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post" style="margin:0"> <form sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post" style="margin:0">
<button type="submit" class="btn-logout">Salir</button> <button type="submit" class="btn-logout">Salir</button>
@ -56,6 +56,13 @@
</div> </div>
<!-- ── Audio bar (fija, inferior) ──────────────────────── -->
<div id="audio-bar" class="audio-bar-fixed audio-bar-hidden" aria-label="Reproductor de audio">
<i class="fas fa-headphones audio-bar-icon"></i>
<span class="audio-bar-title" id="audio-bar-title"></span>
<div class="audio-bar-controls" id="audio-bar-controls"></div>
</div>
<!-- ── Scripts ────────────────────────────────────────── --> <!-- ── Scripts ────────────────────────────────────────── -->
<!-- marked.js para renderizar Markdown en el cliente --> <!-- marked.js para renderizar Markdown en el cliente -->
<script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js"></script>

View File

@ -24,7 +24,7 @@
</nav> </nav>
<!-- Usuario / sesión --> <!-- Usuario / sesión -->
<div class="topbar-user"> <div class="topbar-user">
<span sec:authorize="isAuthenticated()" class="user-email" sec:authentication="principal.username"></span> <span sec:authorize="isAuthenticated()" class="user-email" th:text="${#strings.substringBefore(#authentication.name, '@')}"></span>
<a sec:authorize="hasRole('ADMIN')" th:href="@{/admin/usuarios}" class="btn-login" style="margin-right:.5rem">Admin</a> <a sec:authorize="hasRole('ADMIN')" th:href="@{/admin/usuarios}" class="btn-login" style="margin-right:.5rem">Admin</a>
<form sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post" style="margin:0"> <form sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post" style="margin:0">
<button type="submit" class="btn-logout">Salir</button> <button type="submit" class="btn-logout">Salir</button>

View File

@ -25,7 +25,7 @@
<a sec:authorize="hasAnyRole('PAGADO','ADMIN')" th:href="@{/flashcards.html}">Flashcards</a> <a sec:authorize="hasAnyRole('PAGADO','ADMIN')" th:href="@{/flashcards.html}">Flashcards</a>
</nav> </nav>
<div class="topbar-user"> <div class="topbar-user">
<span sec:authorize="isAuthenticated()" class="user-email" sec:authentication="principal.username"></span> <span sec:authorize="isAuthenticated()" class="user-email" th:text="${#strings.substringBefore(#authentication.name, '@')}"></span>
<form sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post" style="margin:0"> <form sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post" style="margin:0">
<button type="submit" class="btn-logout">Salir</button> <button type="submit" class="btn-logout">Salir</button>
</form> </form>