Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@
html.skip-static-landing #static-landing { display: none; }
</style>

<!-- Décide AVANT le 1er paint si la landing statique doit être affichée,
et quelle variante du flow d'install iOS afficher (Safari < 26 vs ≥ 26
où Apple a déplacé le bouton de partage derrière "•••"). Inline + sync
pour tourner avant le rendu du <body>. -->
<!-- Décide AVANT le 1er paint si la landing statique doit être affichée
(et marque iOS, pour choisir le bon panneau d'aide à l'installation).
Inline + sync pour tourner avant le rendu du <body>. -->
<script>
(function() {
try {
Expand All @@ -63,10 +62,14 @@
// Sert au handler "Installer" à choisir le bon panneau d'aide
// (iOS share-sheet vs desktop) quand il n'y a pas de prompt natif.
document.documentElement.classList.add('is-ios');
var v = ua.match(/Version\/(\d+)/);
var major = v ? parseInt(v[1], 10) : 0;
if (major > 0 && major < 26) {
document.documentElement.classList.add('ios-classic');
// Hors Safari (Chrome/Firefox/Edge… iOS), le partage n'expose pas
// « Sur l'écran d'accueil » : on affichera un préambule "ouvre dans
// Safari". Détection fail-safe : par défaut on suppose Safari (le
// visiteur n'a pas à se voir dire d'ouvrir Safari s'il y est déjà).
// ⚠ Même denylist que isIOSSafari() dans src/lib/install.ts — ce
// script inline tourne pré-paint (avant tout module), d'où la copie.
if (/CriOS|FxiOS|EdgiOS|OPiOS|YaBrowser/.test(ua)) {
document.documentElement.classList.add('ios-other-browser');
}
}
} catch (e) {}
Expand Down Expand Up @@ -210,23 +213,27 @@ <h1 class="landing-title">Tablito</h1>
</div>

<!-- Instructions iOS, montrées au clic "Installer" si pas de prompt natif.
Deux variantes selon la version Safari (cf. inline script en <head>
qui pose `html.ios-classic` pour iOS < 26). -->
Une seule liste, centrée sur l'ICÔNE de partage plutôt que sur sa
position : le bouton est en bas (iPhone) ou en haut (iPad), et son
emplacement dépend aussi du réglage « barre d'adresse » — rien de
tout ça n'est détectable côté web. Un repli ••• couvre le cas où le
partage est replié dans le menu (Safari compact). -->
<div id="ios-install-help" class="install-help">
<h2>Installer sur iPhone / iPad</h2>
<p>Ouvre cette page dans Safari, puis ajoute l'app à l'écran d'accueil&nbsp;:</p>
<ol class="ios-steps-modern">
<li>Touche le bouton <strong>•••</strong> en bas à droite de Safari (en mode compact, c'est lui qui cache le partage).</li>
<li>Choisis <strong>« Partager »</strong> dans le menu qui s'ouvre.</li>
<li>Touche <strong>« Plus »</strong> pour afficher toutes les actions.</li>
<li>Choisis <strong>« Sur l'écran d'accueil »</strong> puis touche <strong>« Ajouter »</strong>. L'icône Tablito apparaît sur ton écran.</li>
</ol>
<ol class="ios-steps-classic">
<li>Touche le bouton <strong>de partage</strong> en bas de l'écran (icône avec une flèche vers le haut).</li>
<li>Choisis <strong>« Sur l'écran d'accueil »</strong> dans la liste.</li>
<li>Touche <strong>« Ajouter »</strong> en haut à droite. L'icône Tablito apparaît sur ton écran d'accueil.</li>
<!-- Préambule montré uniquement hors Safari (cf. html.ios-other-browser) :
en Safari, inutile de dire au visiteur d'ouvrir Safari. -->
<p class="ios-open-in-safari">Tu es dans Chrome ou Firefox&nbsp;? Ouvre d'abord cette page dans <strong>Safari</strong> (le menu de ton navigateur propose <strong>« Ouvrir dans Safari »</strong>), puis&nbsp;:</p>
<p class="ios-intro">Ajoute l'app à ton écran d'accueil en 3 touches&nbsp;:</p>
<ol>
<li>
Touche l'icône <strong>Partager</strong>
<span class="ios-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 14V4"/><path d="M8.5 7.5 12 4l3.5 3.5"/><path d="M7 11H6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2h-1"/></svg></span>
dans la barre d'outils de Safari (<strong>en bas</strong> sur iPhone, <strong>en haut</strong> sur iPad).
<span class="ios-step-hint">Tu ne la vois pas&nbsp;? Touche d'abord <strong>•••</strong>, puis <strong>« Partager »</strong>.</span>
</li>
<li>Fais défiler, puis choisis <strong>« Sur l'écran d'accueil »</strong> <span class="ios-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="4.5"/><path d="M12 8.5v7M8.5 12h7"/></svg></span>.</li>
<li>Touche <strong>« Ajouter »</strong> en haut à droite. L'icône Tablito apparaît sur ton écran&nbsp;!</li>
</ol>
<p class="install-note">Astuce&nbsp;: dans Chrome ou Firefox sur iOS, l'ajout n'est pas disponible — ouvre cette page dans Safari.</p>
</div>

<!-- Desktop sans prompt natif (Safari macOS, Firefox…). Montré au clic
Expand Down
13 changes: 3 additions & 10 deletions src/lib/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,12 @@ export function isIOS(): boolean {
export function isIOSSafari(): boolean {
if (!isIOS()) return false;
const ua = navigator.userAgent;
// ⚠ Cette denylist est aussi dupliquée dans l'inline script de index.html
// (détection pré-paint `ios-other-browser`). Si tu la modifies, mets à jour
// les deux.
return /Safari/.test(ua) && !/CriOS|FxiOS|EdgiOS|OPiOS|YaBrowser/.test(ua);
}

// La version Safari suit la version iOS depuis qu'Apple a unifié la
// numérotation en 2025 (Safari 26 ↔ iOS 26). On s'en sert pour distinguer
// l'UI historique (Safari < 26 : bouton de partage direct dans le toolbar)
// du nouveau flow iOS 26+ (••• → Partager → Plus → Sur l'écran d'accueil).
export function getIOSMajorVersion(): number | null {
if (typeof navigator === 'undefined') return null;
const match = navigator.userAgent.match(/Version\/(\d+)/);
return match ? parseInt(match[1], 10) : null;
}

export function hasSkippedInstall(): boolean {
try {
return localStorage.getItem(SKIP_INSTALL_KEY) === '1';
Expand Down
49 changes: 42 additions & 7 deletions src/static-landing.css
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,48 @@
color: var(--indigo-ink);
}

/* Par défaut on montre la variante "modern" (Safari iOS 26+, ~66 % des
iPhones en 2026). L'inline script du <head> pose `html.ios-classic`
pour iOS < 26 (Version/<26 dans l'UA Safari) — l'autre variante prend
la main alors. */
.install-help .ios-steps-classic { display: none; }
html.ios-classic .install-help .ios-steps-modern { display: none; }
html.ios-classic .install-help .ios-steps-classic { display: block; }
/* On décrit l'action par son ICÔNE plutôt que par sa position : le bouton de
partage iOS est en bas (iPhone) ou en haut (iPad), et son emplacement dépend
en plus du réglage « barre d'adresse » — impossible à détecter côté web. Une
instruction unique, centrée sur l'icône, marche dans tous les cas. */
.install-help .ios-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 23px;
height: 23px;
margin: 0 1px;
vertical-align: -6px;
color: var(--indigo-ink);
background: var(--indigo-soft);
border-radius: 7px;
}

/* Présentation commune aux deux glyphes (partage, « + ») : factorisée ici pour
que le markup inline ne porte que le viewBox + le tracé. */
.install-help .ios-icon svg {
width: 15px;
height: 15px;
fill: none;
stroke: currentColor;
stroke-width: 1.9;
stroke-linecap: round;
stroke-linejoin: round;
}

.install-help .ios-step-hint {
display: block;
font-size: 12.5px;
color: var(--ink-muted);
margin-top: 4px;
}

/* « Ouvre dans Safari » : utile seulement hors Safari. Par défaut on suppose
Safari (préambule masqué, intro directe), et l'inline script du <head> pose
`html.ios-other-browser` pour Chrome/Firefox/Edge… iOS — on inverse alors. */
.install-help .ios-open-in-safari { display: none; }
html.ios-other-browser .install-help .ios-open-in-safari { display: block; }
html.ios-other-browser .install-help .ios-intro { display: none; }

.install-note {
font-size: 12px;
Expand Down
Loading