Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9a776b626 |
@@ -1,5 +1,31 @@
|
|||||||
# Changelog - FlowDeck
|
# Changelog - FlowDeck
|
||||||
|
|
||||||
|
## v7.69.2 (2026-10-08) — Le favicon est enfin le vrai logo
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Le favicon était un placeholder** : un carré bleu `#2383E2` avec les lettres
|
||||||
|
« FD » écrites en `<text>` SVG — génériques, sans lien avec la marque, et
|
||||||
|
rendus avec la police du visiteur.
|
||||||
|
- → `static/favicon.ico` généré depuis `assets/logo.jpg` : 16/32/48 px dans un
|
||||||
|
seul fichier (un `<link>` pour tous les navigateurs), 4,1 Ko.
|
||||||
|
|
||||||
|
**Pourquoi un fond sombre** : le logo est blanc à ~82 % (mesuré : 50,7 % de
|
||||||
|
blanc pur + 32 % de blancs proches). Posé nu, il disposerait sur un onglet clair
|
||||||
|
— cas nominal de Firefox et Safari en thème clair. Il est donc posé sur un
|
||||||
|
carré `#191919` arrondi, **le même fond que les icônes PWA** générées en v7.69.0,
|
||||||
|
ce qui garde une identité cohérente. Contraste mesuré à 16 px : σ = 106 (contre
|
||||||
|
σ = 49 pour le logo seul — le fond sombre double la lisibilité).
|
||||||
|
|
||||||
|
Mise à jour des **5 templates** qui référençaient l'ancien SVG (`base`,
|
||||||
|
`import`, `landing`, `public_page`, `welcome`) + la liste de pré-cache du
|
||||||
|
service worker. `static/favicon.svg` **supprimé** : plus aucune référence.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- `test_favicon_is_the_real_logo` (tailles ICO, absence du placeholder) +
|
||||||
|
`test_every_template_points_at_the_real_favicon` (5 templates + `sw.js`).
|
||||||
|
|
||||||
## v7.69.1 (2026-10-08) — `og:image` en URL absolue
|
## v7.69.1 (2026-10-08) — `og:image` en URL absolue
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# WORKLOAD — FlowDeck Notion Clone
|
# WORKLOAD — FlowDeck Notion Clone
|
||||||
|
|
||||||
> **Début**: 2026-07-08 | **Version**: v7.69.1 (sélection multi-blocs fonctionnelle : drag souris + Maj+↓ + Ctrl+C/X, clic droit qui préserve le surlignage ; identité visuelle logo/bannière) | **Statut**: EN COURS 🔄
|
> **Début**: 2026-07-08 | **Version**: v7.69.2 (sélection multi-blocs fonctionnelle : drag souris + Maj+↓ + Ctrl+C/X, clic droit qui préserve le surlignage ; identité visuelle logo/bannière/favicon)
|
||||||
> **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0`
|
> **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0`
|
||||||
|
|
||||||
## Avancement Global
|
## Avancement Global
|
||||||
|
|||||||
+1
-1
@@ -186,7 +186,7 @@ async def lifespan(_app: FastAPI):
|
|||||||
|
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="FlowDeck",
|
title="FlowDeck",
|
||||||
version="7.69.1",
|
version="7.69.2",
|
||||||
docs_url="/docs",
|
docs_url="/docs",
|
||||||
redoc_url="/redoc",
|
redoc_url="/redoc",
|
||||||
lifespan=lifespan,
|
lifespan=lifespan,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>FlowDeck — {% block title_prefix %}Home{% endblock %}</title>
|
<title>FlowDeck — {% block title_prefix %}Home{% endblock %}</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
<link rel="icon" href="/static/favicon.ico" sizes="48x48">
|
||||||
<link rel="manifest" href="/static/manifest.json">
|
<link rel="manifest" href="/static/manifest.json">
|
||||||
<meta name="theme-color" content="#191919">
|
<meta name="theme-color" content="#191919">
|
||||||
<link rel="apple-touch-icon" href="/static/icons/apple-touch-icon.png">
|
<link rel="apple-touch-icon" href="/static/icons/apple-touch-icon.png">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Importer — FlowDeck</title>
|
<title>Importer — FlowDeck</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
<link rel="icon" href="/static/favicon.ico" sizes="48x48">
|
||||||
<script src="/static/js/alpine.csp.min.js" defer data-cfasync="false"></script>
|
<script src="/static/js/alpine.csp.min.js" defer data-cfasync="false"></script>
|
||||||
<style>
|
<style>
|
||||||
:root{--bg:#191919;--bg2:#1F1F1F;--bg3:#2D2D2D;--border:#333;--text:#fff;--dim:#9B9A97;--accent:#2383E2;--accent-h:#1a6bc0;--success:#0F7B6C;--danger:#E03E3E;--warn:#D9730D;}
|
:root{--bg:#191919;--bg2:#1F1F1F;--bg3:#2D2D2D;--border:#333;--text:#fff;--dim:#9B9A97;--accent:#2383E2;--accent-h:#1a6bc0;--success:#0F7B6C;--danger:#E03E3E;--warn:#D9730D;}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
{% from '_icons.html' import fd_icon %}
|
{% from '_icons.html' import fd_icon %}
|
||||||
<title>FlowDeck — All-in-one workspace</title>
|
<title>FlowDeck — All-in-one workspace</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
<link rel="icon" href="/static/favicon.ico" sizes="48x48">
|
||||||
<link rel="manifest" href="/static/manifest.json">
|
<link rel="manifest" href="/static/manifest.json">
|
||||||
<meta name="theme-color" content="#191919">
|
<meta name="theme-color" content="#191919">
|
||||||
<link rel="apple-touch-icon" href="/static/icons/apple-touch-icon.png">
|
<link rel="apple-touch-icon" href="/static/icons/apple-touch-icon.png">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% from '_icons.html' import fd_icon %}
|
{% from '_icons.html' import fd_icon %}
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ title }} — FlowDeck</title>
|
<title>{{ title }} — FlowDeck</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
<link rel="icon" href="/static/favicon.ico" sizes="48x48">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg: #191919;
|
--bg: #191919;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Bienvenue sur FlowDeck</title>
|
<title>Bienvenue sur FlowDeck</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
<link rel="icon" href="/static/favicon.ico" sizes="48x48">
|
||||||
<script src="/static/js/alpine.csp.min.js" defer data-cfasync="false"></script>
|
<script src="/static/js/alpine.csp.min.js" defer data-cfasync="false"></script>
|
||||||
<style>
|
<style>
|
||||||
:root{--bg:#191919;--bg2:#1F1F1F;--bg3:#2D2D2D;--border:#333;--text:#fff;--dim:#9B9A97;--accent:#2383E2;--accent-h:#1a6bc0;--success:#0F7B6C;--danger:#E03E3E;}
|
:root{--bg:#191919;--bg2:#1F1F1F;--bg3:#2D2D2D;--border:#333;--text:#fff;--dim:#9B9A97;--accent:#2383E2;--accent-h:#1a6bc0;--success:#0F7B6C;--danger:#E03E3E;}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"openapi": "3.1.0",
|
"openapi": "3.1.0",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "FlowDeck",
|
"title": "FlowDeck",
|
||||||
"version": "7.69.1"
|
"version": "7.69.2"
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"/auth/register": {
|
"/auth/register": {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
||||||
<rect width="32" height="32" rx="6" fill="#2383E2"/>
|
|
||||||
<text x="16" y="22" text-anchor="middle" font-family="Arial,sans-serif" font-size="16" font-weight="bold" fill="#fff">FD</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 253 B |
+1
-1
@@ -30,7 +30,7 @@ const PRECACHE_URLS = [
|
|||||||
'/static/js/katex.min.js?v=0.16.11',
|
'/static/js/katex.min.js?v=0.16.11',
|
||||||
'/static/js/prism.min.js',
|
'/static/js/prism.min.js',
|
||||||
// Icônes & métadonnées
|
// Icônes & métadonnées
|
||||||
'/static/favicon.svg',
|
'/static/favicon.ico',
|
||||||
'/static/manifest.json',
|
'/static/manifest.json',
|
||||||
'/static/icons/icon-192x192.png',
|
'/static/icons/icon-192x192.png',
|
||||||
'/static/icons/icon-512x512.png',
|
'/static/icons/icon-512x512.png',
|
||||||
|
|||||||
@@ -139,6 +139,28 @@ class TestBranding:
|
|||||||
# distingue : la bonne valeur contient l'ancienne en sous-chaîne)
|
# distingue : la bonne valeur contient l'ancienne en sous-chaîne)
|
||||||
assert 'content="/static/img/' not in src, tpl
|
assert 'content="/static/img/' not in src, tpl
|
||||||
|
|
||||||
|
def test_favicon_is_the_real_logo(self):
|
||||||
|
"""L'ancien favicon était un placeholder « FD » en SVG — pas la marque."""
|
||||||
|
ico = ROOT / "static" / "favicon.ico"
|
||||||
|
assert ico.exists()
|
||||||
|
assert ico.stat().st_size < 20_000 # un favicon pèse des Ko, pas des Mo
|
||||||
|
# 16/32/48 : la taille de l'onglet ET le repli rétro
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
assert Image.open(ico).info.get("sizes") >= {(16, 16), (32, 32), (48, 48)}
|
||||||
|
# le placeholder SVG doit avoir disparu
|
||||||
|
assert not (ROOT / "static" / "favicon.svg").exists()
|
||||||
|
|
||||||
|
def test_every_template_points_at_the_real_favicon(self):
|
||||||
|
for tpl in ("base.html", "import.html", "landing.html", "public_page.html", "welcome.html"):
|
||||||
|
src = (ROOT / "app" / "templates" / tpl).read_text(encoding="utf-8")
|
||||||
|
assert 'rel="icon" href="/static/favicon.ico"' in src, tpl
|
||||||
|
assert "favicon.svg" not in src, tpl
|
||||||
|
# le service worker pré-met en cache la bonne URL
|
||||||
|
sw = (ROOT / "static" / "sw.js").read_text(encoding="utf-8")
|
||||||
|
assert "'/static/favicon.ico'," in sw
|
||||||
|
assert "favicon.svg" not in sw
|
||||||
|
|
||||||
def test_landing_shows_logo_and_banner(self):
|
def test_landing_shows_logo_and_banner(self):
|
||||||
landing = (ROOT / "app" / "templates" / "landing.html").read_text(encoding="utf-8")
|
landing = (ROOT / "app" / "templates" / "landing.html").read_text(encoding="utf-8")
|
||||||
# le logo remplace l'icône générique dans la barre de navigation
|
# le logo remplace l'icône générique dans la barre de navigation
|
||||||
|
|||||||
Reference in New Issue
Block a user