style(cyberfeed): Amber & green CRT color scheme for timeline
- Amber (#ffb000) for titles, borders, hover effects - Green (#33ff33) for dates, sources, navigation - Gradient timeline line (amber → green → amber) - Glow effects on text and borders - Audio items highlighted in green - Status bar with item count and sync time - Emojified content from AWK parser preserved Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d04c0c6355
commit
814a85754d
@ -231,7 +231,7 @@ parse_rss() {
|
|||||||
'
|
'
|
||||||
}
|
}
|
||||||
|
|
||||||
# === TIMELINE HTML GENERATOR (1/3 CRT + 2/3 Standard) ===
|
# === TIMELINE HTML GENERATOR (Amber & Green CRT Colors) ===
|
||||||
generate_timeline() {
|
generate_timeline() {
|
||||||
local json_file="$1"
|
local json_file="$1"
|
||||||
local output_file="${OUTPUT_DIR}/timeline.html"
|
local output_file="${OUTPUT_DIR}/timeline.html"
|
||||||
@ -244,386 +244,254 @@ generate_timeline() {
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>⚡ CYBERFEED TIMELINE ⚡</title>
|
<title>⚡ CYBERFEED TIMELINE ⚡</title>
|
||||||
<style>
|
<style>
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&family=VT323&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&display=swap');
|
||||||
:root {
|
:root {
|
||||||
--neon-cyan: #0ff;
|
--amber: #ffb000;
|
||||||
--neon-magenta: #f0f;
|
--amber-dim: #cc8800;
|
||||||
--neon-green: #0f0;
|
--amber-glow: rgba(255,176,0,0.4);
|
||||||
--dark-bg: #0a0a0f;
|
--green: #33ff33;
|
||||||
--text-primary: #e0e0e0;
|
--green-dim: #22aa22;
|
||||||
--text-dim: #606080;
|
--green-glow: rgba(51,255,51,0.4);
|
||||||
--crt-glow: #33ff33;
|
--dark-bg: #0a0a0a;
|
||||||
|
--darker-bg: #050505;
|
||||||
|
--text-dim: #555;
|
||||||
}
|
}
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
body {
|
body {
|
||||||
font-family: 'Share Tech Mono', monospace;
|
font-family: 'Share Tech Mono', monospace;
|
||||||
background: var(--dark-bg);
|
background: var(--dark-bg);
|
||||||
color: var(--text-primary);
|
color: var(--amber);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
|
||||||
|
|
||||||
/* === SPLIT LAYOUT === */
|
|
||||||
.split-container {
|
|
||||||
display: flex;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* === CRT MONITOR (1/3) === */
|
|
||||||
.crt-section {
|
|
||||||
width: 33.33%;
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: #111;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border-right: 2px solid #333;
|
|
||||||
}
|
|
||||||
.crt-monitor {
|
|
||||||
flex: 1;
|
|
||||||
background: #1a1a1a;
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 15px;
|
|
||||||
position: relative;
|
|
||||||
box-shadow:
|
|
||||||
inset 0 0 50px rgba(0,0,0,0.5),
|
|
||||||
0 0 20px rgba(0,255,0,0.1);
|
|
||||||
}
|
|
||||||
/* CRT Bezel */
|
|
||||||
.crt-monitor::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
border-radius: 20px;
|
|
||||||
border: 8px solid #2a2a2a;
|
|
||||||
background: linear-gradient(135deg, #3a3a3a 0%, #1a1a1a 50%, #2a2a2a 100%);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
/* Corner screws */
|
|
||||||
.crt-monitor::after {
|
|
||||||
content: '⊕';
|
|
||||||
position: absolute;
|
|
||||||
top: 8px; left: 12px;
|
|
||||||
color: #555;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
.crt-screen {
|
|
||||||
background: #001a00;
|
|
||||||
border-radius: 10px;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
border: 3px solid #333;
|
|
||||||
}
|
|
||||||
/* Scanlines */
|
|
||||||
.crt-screen::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background: repeating-linear-gradient(
|
|
||||||
0deg,
|
|
||||||
rgba(0,0,0,0.15) 0px,
|
|
||||||
rgba(0,0,0,0.15) 1px,
|
|
||||||
transparent 1px,
|
|
||||||
transparent 2px
|
|
||||||
);
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
/* Screen curvature */
|
|
||||||
.crt-screen::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.4) 100%);
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 11;
|
|
||||||
}
|
|
||||||
/* Phosphor glow effect */
|
|
||||||
.crt-content {
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 15px;
|
|
||||||
font-family: 'VT323', monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--crt-glow);
|
|
||||||
text-shadow: 0 0 5px var(--crt-glow), 0 0 10px rgba(0,255,0,0.5);
|
|
||||||
animation: flicker 0.15s infinite;
|
|
||||||
}
|
|
||||||
@keyframes flicker {
|
|
||||||
0%, 100% { opacity: 0.98; }
|
|
||||||
50% { opacity: 1; }
|
|
||||||
}
|
|
||||||
.crt-content::-webkit-scrollbar { width: 6px; }
|
|
||||||
.crt-content::-webkit-scrollbar-track { background: #001a00; }
|
|
||||||
.crt-content::-webkit-scrollbar-thumb { background: #0f0; border-radius: 3px; }
|
|
||||||
|
|
||||||
.crt-item {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
border-bottom: 1px dashed rgba(0,255,0,0.3);
|
|
||||||
}
|
|
||||||
.crt-item .time {
|
|
||||||
color: #0a0;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
.crt-item .title {
|
|
||||||
color: var(--crt-glow);
|
|
||||||
font-size: 13px;
|
|
||||||
margin: 4px 0;
|
|
||||||
}
|
|
||||||
.crt-item .title a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.crt-item .title a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.crt-item .source {
|
|
||||||
color: #0a0;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
/* Power LED */
|
|
||||||
.crt-power {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 15px;
|
|
||||||
right: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
.crt-led {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
background: #0f0;
|
|
||||||
border-radius: 50%;
|
|
||||||
box-shadow: 0 0 8px #0f0, 0 0 15px #0f0;
|
|
||||||
animation: led-pulse 2s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
@keyframes led-pulse {
|
|
||||||
0%, 100% { opacity: 1; }
|
|
||||||
50% { opacity: 0.6; }
|
|
||||||
}
|
|
||||||
.crt-label {
|
|
||||||
font-family: 'Orbitron', sans-serif;
|
|
||||||
font-size: 8px;
|
|
||||||
color: #666;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* === STANDARD TIMELINE (2/3) === */
|
|
||||||
.timeline-section {
|
|
||||||
width: 66.66%;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-y: auto;
|
|
||||||
max-height: 100vh;
|
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 30px;
|
||||||
border-bottom: 1px solid var(--neon-cyan);
|
border-bottom: 2px solid var(--amber);
|
||||||
|
box-shadow: 0 2px 20px var(--amber-glow);
|
||||||
}
|
}
|
||||||
.header h1 {
|
.header h1 {
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
font-size: 1.8rem;
|
font-size: 2rem;
|
||||||
color: var(--neon-cyan);
|
color: var(--amber);
|
||||||
text-shadow: 0 0 10px var(--neon-cyan);
|
text-shadow: 0 0 10px var(--amber), 0 0 20px var(--amber-glow);
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
.header .subtitle {
|
||||||
|
color: var(--green);
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
text-shadow: 0 0 8px var(--green-glow);
|
||||||
}
|
}
|
||||||
.nav-links {
|
.nav-links {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
.nav-links a {
|
.nav-links a {
|
||||||
color: var(--neon-cyan);
|
color: var(--green);
|
||||||
margin: 0 15px;
|
margin: 0 15px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.9rem;
|
padding: 8px 16px;
|
||||||
|
border: 1px solid var(--green-dim);
|
||||||
|
transition: all 0.3s;
|
||||||
}
|
}
|
||||||
.nav-links a:hover {
|
.nav-links a:hover {
|
||||||
text-shadow: 0 0 10px var(--neon-cyan);
|
background: var(--green);
|
||||||
|
color: var(--dark-bg);
|
||||||
|
box-shadow: 0 0 15px var(--green-glow);
|
||||||
}
|
}
|
||||||
.timeline {
|
.timeline {
|
||||||
max-width: 700px;
|
max-width: 800px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 35px;
|
padding-left: 40px;
|
||||||
}
|
}
|
||||||
.timeline::before {
|
.timeline::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 15px;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 2px;
|
width: 3px;
|
||||||
background: linear-gradient(180deg, var(--neon-cyan), var(--neon-magenta));
|
background: linear-gradient(180deg, var(--amber), var(--green), var(--amber));
|
||||||
box-shadow: 0 0 10px var(--neon-cyan);
|
box-shadow: 0 0 15px var(--amber-glow);
|
||||||
}
|
}
|
||||||
.timeline-date {
|
.timeline-date {
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1.1rem;
|
||||||
color: var(--neon-magenta);
|
color: var(--green);
|
||||||
margin: 25px 0 12px -35px;
|
margin: 30px 0 15px -40px;
|
||||||
padding-left: 35px;
|
padding-left: 40px;
|
||||||
text-shadow: 0 0 5px var(--neon-magenta);
|
text-shadow: 0 0 8px var(--green-glow);
|
||||||
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
.timeline-item {
|
.timeline-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 20px;
|
||||||
padding: 12px;
|
padding: 15px;
|
||||||
background: rgba(0,255,255,0.05);
|
background: rgba(255,176,0,0.03);
|
||||||
border: 1px solid rgba(0,255,255,0.2);
|
border: 1px solid rgba(255,176,0,0.2);
|
||||||
border-radius: 6px;
|
border-left: 3px solid var(--amber);
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
.timeline-item:hover {
|
||||||
|
background: rgba(255,176,0,0.08);
|
||||||
|
border-color: var(--amber);
|
||||||
|
box-shadow: 0 0 20px var(--amber-glow);
|
||||||
}
|
}
|
||||||
.timeline-item::before {
|
.timeline-item::before {
|
||||||
content: '◆';
|
content: '●';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -28px;
|
left: -32px;
|
||||||
top: 14px;
|
top: 18px;
|
||||||
color: var(--neon-cyan);
|
color: var(--amber);
|
||||||
font-size: 10px;
|
font-size: 12px;
|
||||||
text-shadow: 0 0 10px var(--neon-cyan);
|
text-shadow: 0 0 10px var(--amber);
|
||||||
|
}
|
||||||
|
.timeline-item.has-audio {
|
||||||
|
border-left-color: var(--green);
|
||||||
|
}
|
||||||
|
.timeline-item.has-audio::before {
|
||||||
|
content: '♪';
|
||||||
|
color: var(--green);
|
||||||
|
text-shadow: 0 0 10px var(--green);
|
||||||
|
}
|
||||||
|
.timeline-item.has-video::before {
|
||||||
|
content: '▶';
|
||||||
|
color: var(--green);
|
||||||
|
text-shadow: 0 0 10px var(--green);
|
||||||
}
|
}
|
||||||
.timeline-item.has-audio::before { content: '🎧'; font-size: 12px; }
|
|
||||||
.timeline-item.has-video::before { content: '📺'; font-size: 12px; }
|
|
||||||
.item-time {
|
.item-time {
|
||||||
font-size: 0.7rem;
|
font-size: 0.75rem;
|
||||||
color: var(--neon-magenta);
|
color: var(--green-dim);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 6px;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
.item-title {
|
.item-title {
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
font-size: 0.9rem;
|
font-size: 1rem;
|
||||||
color: var(--neon-cyan);
|
color: var(--amber);
|
||||||
margin-bottom: 6px;
|
margin-bottom: 8px;
|
||||||
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
.item-title a {
|
.item-title a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
transition: text-shadow 0.3s;
|
||||||
}
|
}
|
||||||
.item-title a:hover {
|
.item-title a:hover {
|
||||||
text-shadow: 0 0 10px var(--neon-cyan);
|
text-shadow: 0 0 15px var(--amber);
|
||||||
}
|
}
|
||||||
.item-desc {
|
.item-desc {
|
||||||
font-size: 0.8rem;
|
font-size: 0.85rem;
|
||||||
color: var(--text-primary);
|
color: var(--amber-dim);
|
||||||
opacity: 0.8;
|
opacity: 0.85;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 10px;
|
||||||
line-height: 1.4;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
.item-source {
|
.item-source {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: rgba(255,0,255,0.2);
|
background: rgba(51,255,51,0.1);
|
||||||
border: 1px solid var(--neon-magenta);
|
border: 1px solid var(--green-dim);
|
||||||
padding: 2px 6px;
|
color: var(--green);
|
||||||
font-size: 0.6rem;
|
padding: 3px 10px;
|
||||||
|
font-size: 0.65rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
.item-source.duration {
|
||||||
|
background: rgba(255,176,0,0.1);
|
||||||
|
border-color: var(--amber-dim);
|
||||||
|
color: var(--amber);
|
||||||
|
}
|
||||||
|
.audio-player {
|
||||||
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
.audio-player { margin-top: 8px; }
|
|
||||||
.audio-player audio {
|
.audio-player audio {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 35px;
|
height: 40px;
|
||||||
border-radius: 18px;
|
border-radius: 20px;
|
||||||
|
filter: sepia(100%) hue-rotate(-10deg) saturate(200%);
|
||||||
}
|
}
|
||||||
|
.status-bar {
|
||||||
/* Responsive */
|
text-align: center;
|
||||||
@media (max-width: 900px) {
|
padding: 15px;
|
||||||
.split-container { flex-direction: column; }
|
margin-top: 30px;
|
||||||
.crt-section { width: 100%; height: 40vh; border-right: none; border-bottom: 2px solid #333; }
|
border-top: 1px solid var(--green-dim);
|
||||||
.timeline-section { width: 100%; max-height: none; }
|
font-size: 0.7rem;
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.status-bar span {
|
||||||
|
color: var(--green);
|
||||||
|
margin: 0 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="split-container">
|
<header class="header">
|
||||||
<!-- CRT Monitor Section (1/3) -->
|
<h1>⚡ TIMELINE ⚡</h1>
|
||||||
<div class="crt-section">
|
<p class="subtitle">[ NEURAL FEED MATRIX ]</p>
|
||||||
<div class="crt-monitor">
|
</header>
|
||||||
<div class="crt-screen">
|
<nav class="nav-links">
|
||||||
<div class="crt-content" id="crt-feed">
|
<a href="/cyberfeed/">← DASHBOARD</a>
|
||||||
<p>> INITIALIZING FEED MATRIX...</p>
|
<a href="/cyberfeed/timeline.html">↻ REFRESH</a>
|
||||||
<p>> AWAITING DATA STREAM...</p>
|
</nav>
|
||||||
</div>
|
<div class="timeline" id="timeline">
|
||||||
</div>
|
<p style="text-align:center; color: var(--amber-dim);">LOADING DATA STREAM...</p>
|
||||||
<div class="crt-power">
|
</div>
|
||||||
<div class="crt-led"></div>
|
<div class="status-bar">
|
||||||
<span class="crt-label">POWER</span>
|
<span id="item-count">-- ITEMS</span> |
|
||||||
</div>
|
<span id="last-update">SYNCING...</span> |
|
||||||
</div>
|
CYBERFEED v0.2
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Standard Timeline Section (2/3) -->
|
|
||||||
<div class="timeline-section">
|
|
||||||
<header class="header">
|
|
||||||
<h1>⚡ TIMELINE ⚡</h1>
|
|
||||||
<p style="color: var(--text-dim); margin-top: 8px; font-size: 0.8rem;">Chronological Feed History</p>
|
|
||||||
</header>
|
|
||||||
<nav class="nav-links">
|
|
||||||
<a href="/cyberfeed/">← Dashboard</a>
|
|
||||||
<a href="/cyberfeed/timeline.html">🔄 Refresh</a>
|
|
||||||
</nav>
|
|
||||||
<div class="timeline" id="timeline">
|
|
||||||
<p style="text-align:center; color: var(--text-dim);">Loading timeline...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function loadFeed() {
|
async function loadTimeline() {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/cyberfeed/feeds.json?' + Date.now());
|
const resp = await fetch('/cyberfeed/feeds.json?' + Date.now());
|
||||||
const items = await resp.json();
|
const items = await resp.json();
|
||||||
|
|
||||||
// Sort by date
|
document.getElementById('item-count').textContent = items.length + ' ITEMS';
|
||||||
items.sort((a, b) => new Date(b.date || 0) - new Date(a.date || 0));
|
document.getElementById('last-update').textContent = new Date().toLocaleTimeString('fr-FR', {hour12: false});
|
||||||
|
|
||||||
// CRT Feed (scrolling latest)
|
// Group by date
|
||||||
let crtHtml = '> CYBERFEED NEURAL MATRIX v0.2\\n> ' + items.length + ' TRANSMISSIONS RECEIVED\\n> ════════════════════════════\\n\\n';
|
|
||||||
items.slice(0, 15).forEach(item => {
|
|
||||||
crtHtml += '<div class="crt-item">';
|
|
||||||
crtHtml += '<div class="time">> ' + (item.date || 'Unknown') + '</div>';
|
|
||||||
crtHtml += '<div class="title"><a href="' + item.link + '" target="_blank">' + (item.title || 'Untitled') + '</a></div>';
|
|
||||||
crtHtml += '<div class="source">[' + (item.source || 'RSS') + ']</div>';
|
|
||||||
crtHtml += '</div>';
|
|
||||||
});
|
|
||||||
document.getElementById('crt-feed').innerHTML = crtHtml;
|
|
||||||
|
|
||||||
// Standard Timeline
|
|
||||||
const grouped = {};
|
const grouped = {};
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
const dateStr = item.date ? new Date(item.date).toLocaleDateString('fr-FR', {
|
const dateStr = item.date ? new Date(item.date).toLocaleDateString('fr-FR', {
|
||||||
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
|
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
|
||||||
}) : 'Date inconnue';
|
}).toUpperCase() : 'DATE INCONNUE';
|
||||||
if (!grouped[dateStr]) grouped[dateStr] = [];
|
if (!grouped[dateStr]) grouped[dateStr] = [];
|
||||||
grouped[dateStr].push(item);
|
grouped[dateStr].push(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
Object.keys(grouped).forEach(date => {
|
Object.keys(grouped).forEach(date => {
|
||||||
html += '<div class="timeline-date">' + date + '</div>';
|
html += '<div class="timeline-date">► ' + date + '</div>';
|
||||||
grouped[date].forEach(item => {
|
grouped[date].forEach(item => {
|
||||||
const hasMedia = item.media_type ? ' has-' + item.media_type : '';
|
const hasMedia = item.media_type ? ' has-' + item.media_type : '';
|
||||||
html += '<div class="timeline-item' + hasMedia + '">';
|
html += '<div class="timeline-item' + hasMedia + '">';
|
||||||
html += '<div class="item-time">⏰ ' + (item.date || '') + '</div>';
|
html += '<div class="item-time">◷ ' + (item.date || '') + '</div>';
|
||||||
html += '<div class="item-title"><a href="' + item.link + '" target="_blank">' + item.title + '</a></div>';
|
html += '<div class="item-title"><a href="' + item.link + '" target="_blank">' + item.title + '</a></div>';
|
||||||
if (item.desc) html += '<div class="item-desc">' + item.desc + '</div>';
|
if (item.desc) html += '<div class="item-desc">' + item.desc + '</div>';
|
||||||
if (item.enclosure && item.media_type === 'audio') {
|
if (item.enclosure && item.media_type === 'audio') {
|
||||||
html += '<div class="audio-player"><audio controls preload="none"><source src="' + item.enclosure + '" type="audio/mpeg"></audio></div>';
|
html += '<div class="audio-player"><audio controls preload="none"><source src="' + item.enclosure + '" type="audio/mpeg"></audio></div>';
|
||||||
}
|
}
|
||||||
html += '<span class="item-source">' + (item.source || 'RSS') + '</span>';
|
html += '<span class="item-source">' + (item.source || 'RSS') + '</span>';
|
||||||
if (item.duration) html += ' <span class="item-source">⏱ ' + item.duration + '</span>';
|
if (item.duration) html += ' <span class="item-source duration">◷ ' + item.duration + '</span>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('timeline').innerHTML = html || '<p style="text-align:center;">Aucun élément</p>';
|
document.getElementById('timeline').innerHTML = html || '<p style="text-align:center; color: var(--amber);">NO DATA</p>';
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
document.getElementById('crt-feed').innerHTML = '> ERROR: FEED CONNECTION LOST\\n> RETRYING...';
|
document.getElementById('timeline').innerHTML = '<p style="text-align:center; color: #ff3333;">ERROR: CONNECTION LOST</p>';
|
||||||
document.getElementById('timeline').innerHTML = '<p style="text-align:center; color: #f00;">Erreur de chargement</p>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFeed();
|
loadTimeline();
|
||||||
setInterval(loadFeed, 180000);
|
setInterval(loadTimeline, 180000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user