From 9979ee9003718919ee9959403c52df54977e6e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Wed, 25 Dec 2024 19:49:50 +0100 Subject: [PATCH] update the theme using webcomponents --- mnmlist/static/js/filtered-list.js | 171 +++++++++++++++++++++++++++ mnmlist/static/js/translated-text.js | 52 ++++++++ mnmlist/templates/base.html | 2 + mnmlist/templates/index.html | 59 +++++---- 4 files changed, 254 insertions(+), 30 deletions(-) create mode 100644 mnmlist/static/js/filtered-list.js create mode 100644 mnmlist/static/js/translated-text.js diff --git a/mnmlist/static/js/filtered-list.js b/mnmlist/static/js/filtered-list.js new file mode 100644 index 0000000..9aacc43 --- /dev/null +++ b/mnmlist/static/js/filtered-list.js @@ -0,0 +1,171 @@ +class FilteredArticles extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + + const style = ` + + `; + + this.shadowRoot.innerHTML = ` + ${style} +
+ Filter by: +
+
+ Search: + +
+
+ + `; + + this.currentCategory = 'all'; + this.searchText = ''; + } + + connectedCallback() { + const slot = this.shadowRoot.querySelector('slot'); + const searchInput = this.shadowRoot.querySelector('.search-input'); + + slot.addEventListener('slotchange', () => { + this.init(slot.assignedElements()); + }); + + searchInput.addEventListener('input', (e) => { + this.searchText = e.target.value.toLowerCase(); + const items = slot.assignedElements(); + this.filterItems(items, this.currentCategory); + }); + } + + init(items) { + const categories = new Map(); + items.forEach(item => { + const categoryClass = [...item.classList].find(cls => cls.startsWith('link-')); + if (categoryClass) { + const category = categoryClass.replace('link-', ''); + const color = getComputedStyle(item).getPropertyValue('--item-color').trim(); + categories.set(category, color); + } + }); + + const categoriesContainer = this.shadowRoot.querySelector('.categories-container'); + categoriesContainer.innerHTML = ''; // Clear existing buttons + + // "All" button with a neutral color + const allBtn = document.createElement('button'); + allBtn.className = 'filter-btn active'; + allBtn.textContent = 'All'; + allBtn.dataset.category = 'all'; + allBtn.style.borderBottomColor = '#666'; + categoriesContainer.appendChild(allBtn); + + // Category buttons with matching colors + categories.forEach((color, category) => { + const btn = document.createElement('button'); + btn.className = 'filter-btn'; + btn.textContent = category.charAt(0).toUpperCase() + category.slice(1); + btn.dataset.category = category; + btn.style.borderBottomColor = color; + categoriesContainer.appendChild(btn); + }); + + this.shadowRoot.querySelectorAll('.filter-btn').forEach(btn => { + btn.addEventListener('click', () => { + this.currentCategory = btn.dataset.category; + this.filterItems(items, this.currentCategory); + }); + }); + + this.filterItems(items, 'all'); + } + + filterItems(items, category) { + this.shadowRoot.querySelectorAll('.filter-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.category === category); + }); + + items.forEach(item => { + const matchesCategory = category === 'all' || item.classList.contains(`link-${category}`); + const matchesSearch = this.searchText === '' || + item.textContent.toLowerCase().includes(this.searchText); + item.classList.toggle('visible', matchesCategory && matchesSearch); + }); + } +} + +customElements.define('filtered-articles', FilteredArticles); diff --git a/mnmlist/static/js/translated-text.js b/mnmlist/static/js/translated-text.js new file mode 100644 index 0000000..0c8c3e5 --- /dev/null +++ b/mnmlist/static/js/translated-text.js @@ -0,0 +1,52 @@ +class TranslatedText extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + + // Détection de la langue du navigateur + const userLang = navigator.language || navigator.userLanguage; + const isFrench = userLang.startsWith('fr'); + + const style = document.createElement('style'); + style.textContent = ` + .controls { + text-align: right; + margin-bottom: 10px; + } + .lang-toggle { display: none; } + .lang-label { + padding: 5px 10px; + cursor: pointer; + } + .content-section { display: none; } + #fr:checked ~ .content .fr-content, + #en:checked ~ .content .en-content { display: block; } + + #fr:checked ~ .controls label[for="fr"], + #en:checked ~ .controls label[for="en"] { + display: none; + } + `; + + const html = ` + + +
+ + +
+
+
+ +
+
+ +
+
+ `; + + this.shadowRoot.innerHTML = `${style.outerHTML}${html}`; + } +} + +customElements.define('translated-text', TranslatedText); diff --git a/mnmlist/templates/base.html b/mnmlist/templates/base.html index f381779..8358b2d 100644 --- a/mnmlist/templates/base.html +++ b/mnmlist/templates/base.html @@ -27,6 +27,8 @@ title="{{ SITENAME }} RSS Feed" /> {% endif %} {% block extra_head %}{% endblock %} + +
diff --git a/mnmlist/templates/index.html b/mnmlist/templates/index.html index 7099b29..e7f7d93 100644 --- a/mnmlist/templates/index.html +++ b/mnmlist/templates/index.html @@ -1,42 +1,41 @@ {% extends "base.html" %} {% block content %} -
-
-

not my ideas

-
-
- -

👋 Welcome here, I'm Alexis,

-

I am a software engineer interested by digital freedom and privacy.

-

I'm also a fellow human, exploring how to participate to healthy collectives via listening and conflict-resolution techniques.

-

I mostly publish here in French, but some stuff is in English. You can find here journal entries (fr), - reading notes (fr) and some stuff related to software engineering (en). Also, some writing (fr)

-
-

👋 Bienvenue par ici, je suis Alexis, un développeur intéressé par les - dynamiques collectives, les libertés numériques et la facilitation.

-

Vous retrouverez sur ce site quelques - billets de blog, des notes de lectures, des bouts - de code et des textes que je veux garder quelque part. Bonne lecture !

-

Pour me contacter, envoyez-moi un email sur alexis@ ce domaine (en enlevant blog.).

- + +
+

👋 Bienvenue par ici, je suis Alexis, un développeur intéressé par les + dynamiques collectives et les libertés numériques.

+

J'aime aussi explorer comment participer à des pratiques collectives, via la résolution de conflit et l'écoute.

+

Vous retrouverez sur ce site quelques + billets de blog, des notes de lectures, des bouts + de code et des textes que je veux garder quelque part. Bonne lecture !

+

Pour me contacter, envoyez-moi un email sur alexis@ ce domaine (en enlevant blog.).

+
+
+

👋 Welcome here, I'm Alexis Métaireau, a software engineer interested by digital freedom and privacy.

+

I'm also a fellow human, exploring how to participate to healthy collectives via listening and conflict-resolution techniques.

+

I mostly publish here in French, but some stuff is in English. You can find here journal entries (fr), + reading notes (fr) and some stuff related to software engineering (en). Also, some writing (fr)

+

To contact me, send me an email on alexis@ this domain (without blog.).

+
+
{% if articles %}
-

Les derniers articles / Last articles

- - Archives + {% endfor %} +
{% endif %} {% endblock content %}