home: almost finished bibou oracle

This commit is contained in:
Agahnim 2026-03-23 16:49:00 +01:00
parent db2000640a
commit c0a0225eaa
Signed by: Agahnim
SSH key fingerprint: SHA256:Zj65PJnE0dRYye8Ltk/qDglynyXUxJngQ9qqx/VI+b4
7 changed files with 101 additions and 1 deletions

View file

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
askama = { version = "0.15.4", features = ["std", "derive"] }
askama = { version = "0.15.4", features = ["std", "derive", "serde_json"] }
axum = "0.8.8"
chrono = { version = "0.4.44", features = ["serde"] }
serde = { version = "1.0.228", features = ["derive"] }

17
content/bibou-quotes.json Normal file
View file

@ -0,0 +1,17 @@
[
"The Oracle of the Bibou doth whisper 'neath the moon's pale gaze.",
"He who doth watch in the shadow, seeth all.",
"Verily, even pixels bear a soul, thus speaketh the Bibou.",
"Dread not the error, for 'tis but the path unto the light.",
"Let thy heart guide thy mouse, O child of the web.",
"Each click be a prayer, and the Oracle doth hear.",
"Rise, and partake of a biscuit, for the road be long.",
"This day, thou shalt walk upon the feather of a dove.",
"The owl doth watch thee. Forget not thine duties.",
"A rain of pixels shall fall this very night.",
"The neighbours cat doth conspire. Be wary, O soul.",
"Thy click is not in vain, for the Bibou hath seen thee.",
"Verily, 'tis Monday... and courage thou shalt need.",
"Fear not the dark, for the Bibou lurks there, awaiting food.",
"The Bibou's gaze pierceth the soul..."
]

View file

@ -5,6 +5,7 @@ pub struct AppState {
pub mp_tracks: Vec<Track>,
pub p_tracks: Vec<Track>,
pub website_news: Vec<WebsiteArticle>,
pub bibou_quotes: Vec<String>,
}
impl AppState {
@ -31,6 +32,11 @@ impl AppState {
news
},
bibou_quotes: serde_json::from_str(
&std::fs::read_to_string("content/bibou-quotes.json")
.expect("bibou-quotes.json non trouvé"),
)
.expect("JSON invalide"),
}
}
}

View file

@ -13,12 +13,14 @@ use crate::domain::{AppState, WebsiteArticle};
struct HomeTemplate<'a> {
tracks: &'a Vec<crate::domain::Track>,
news: &'a Vec<WebsiteArticle>,
bibou_quotes: &'a Vec<String>,
}
#[derive(Template)]
#[template(path = "partials/home.html")]
struct HomePartialTemplate<'a> {
news: &'a Vec<WebsiteArticle>,
bibou_quotes: &'a Vec<String>,
}
pub async fn home(headers: HeaderMap, state: State<Arc<AppState>>) -> impl IntoResponse {
@ -26,6 +28,7 @@ pub async fn home(headers: HeaderMap, state: State<Arc<AppState>>) -> impl IntoR
Html(
HomePartialTemplate {
news: &state.website_news,
bibou_quotes: &state.bibou_quotes,
}
.render()
.unwrap(),
@ -35,6 +38,7 @@ pub async fn home(headers: HeaderMap, state: State<Arc<AppState>>) -> impl IntoR
HomeTemplate {
tracks: &state.mp_tracks,
news: &state.website_news,
bibou_quotes: &state.bibou_quotes,
}
.render()
.unwrap(),

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -465,6 +465,45 @@ home-content {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
bibou-oracle {
background-image: url(assets/images/boob_oracle_bg.png);
bibou-container {
position: relative;
display: block;
width: 100px;
margin: 0 auto;
cursor: pointer;
img {
width: 100%;
display: block;
}
&:hover .bibou {
opacity: 1;
}
.bibou {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
&:hover .boubou {
opacity: 0;
}
}
bibou-text {
font-style: italic;
text-align: center;
}
}
}
&#newsbox {

View file

@ -54,6 +54,14 @@
width="30px" alt="Instagram logo" /></a>
</socials>
<img width="200px" src="/static/assets/gifs/divider2.gif" alt="Decorative divider" />
<bibou-oracle>
<bibou-container>
<img class="boubou" src="/static/assets/images/boubou.webp" alt="Bibou endormi" />
<img class="bibou" src="/static/assets/images/bibou.webp" alt="Bibou éveillé" />
</bibou-container>
<bibou-text>
</bibou-text>
</bibou-oracle>
</box>
<box id="newsbox">
<website-news>
@ -81,9 +89,35 @@
<!-- I know I know but I need it for this pretty rainbow flagish animation -->
<script>
<!-- For rainbow text -->
const el = document.querySelector('woopwoop');
const text = el.textContent;
el.innerHTML = text.split('').map((ch, i) =>
`<span style="animation-delay: ${i * 0.08}s">${ch === ' ' ? '&nbsp;' : ch}</span>`
).join('');
const BIBOU_QUOTES = {{bibou_quotes| tojson | safe }};
const txtEl = document.querySelector('bibou-text');
const ctrEl = document.querySelector('bibou-container');
let intervalRef = null;
const ttText = (texte) => {
if (intervalRef) clearInterval(intervalRef);
let accumulated = "";
let index = 0;
intervalRef = setInterval(() => {
if (index < texte.length) {accumulated += texte.charAt(index); txtEl.textContent = accumulated; index++;} else {
clearInterval(intervalRef); intervalRef = null;
}
}, 40);
}; ctrEl.addEventListener('mouseenter', () => {
const quote = BIBOU_QUOTES[Math.floor(Math.random() * BIBOU_QUOTES.length)];
ttText(quote);
});
</script>