fix(android): the page stops sliding, and locking comes back
A swipe with nothing to scroll dragged the whole document, showing the body gradient sliding under the screen gradient - two gradients stacked and no content at all. overflow:hidden does not prevent that in an Android WebView; position:fixed does. The lock button went missing when the list moved to HTML: it lived in the old FMX bottom bar and had no counterpart in the page. It returns as a padlock next to the search field, no label - it is the one icon universal enough to stand alone. Icons on the unlock screen too, as code points since this source is read as ANSI. All four are basic-plane and common, so a font without them would show an empty box rather than a wrong glyph; checked on the device, they render. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,8 +31,15 @@
|
||||
}
|
||||
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
|
||||
html, body {
|
||||
margin: 0; height: 100%; overflow: hidden;
|
||||
background: linear-gradient(var(--bg-top), var(--bg-bot)) fixed;
|
||||
/* CLOUE AU CADRE. overflow:hidden ne suffit pas dans un WebView Android :
|
||||
un glissement qui ne trouve rien a faire defiler fait quand meme
|
||||
glisser le document entier, et on voit alors le degrade du corps passer
|
||||
sous celui de l'ecran - deux degrades empiles, sans le moindre contenu.
|
||||
position:fixed lui retire cette liberte. */
|
||||
position: fixed; inset: 0;
|
||||
margin: 0; overflow: hidden;
|
||||
overscroll-behavior: none;
|
||||
background: var(--bg-bot);
|
||||
color: var(--text);
|
||||
font: 15px/1.4 system-ui, "Roboto", sans-serif;
|
||||
/* Le texte de l'interface ne se selectionne pas - un appui maintenu sur
|
||||
@@ -56,7 +63,7 @@
|
||||
body.on-detail #detail { transform: translateX(0); }
|
||||
|
||||
.scroll { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
|
||||
padding: 0 12px 16px; }
|
||||
overscroll-behavior: contain; padding: 0 12px 16px; }
|
||||
|
||||
/* --- barre de recherche ------------------------------------------------ */
|
||||
.top { padding: 10px 12px 6px; display: flex; gap: 8px; }
|
||||
@@ -74,6 +81,7 @@
|
||||
color: var(--muted); font-size: 17px;
|
||||
}
|
||||
.glass { left: 2px; }
|
||||
.glass svg { width: 19px; height: 19px; }
|
||||
.clear { right: 2px; display: none; font-size: 20px; }
|
||||
body.searching .glass { display: none; }
|
||||
body.searching .clear { display: flex; }
|
||||
@@ -122,6 +130,18 @@
|
||||
|
||||
.empty { text-align: center; color: var(--muted); padding: 48px 16px; }
|
||||
|
||||
/* --- boutons a icone ---------------------------------------------------- */
|
||||
/* Une icone seule ne dit ce qu'elle fait que si elle est archi-connue. Le
|
||||
cadenas l'est ; c'est pourquoi il est le seul a se passer d'intitule. */
|
||||
.ico {
|
||||
flex: 0 0 46px; width: 46px; height: 46px; border: 0; padding: 0;
|
||||
border-radius: var(--radius-s); background: rgba(255,255,255,.10);
|
||||
color: var(--text); display: flex; align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.ico:active { opacity: .62; }
|
||||
.ico svg { width: 21px; height: 21px; }
|
||||
|
||||
/* --- detail ------------------------------------------------------------ */
|
||||
.head { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
|
||||
.head h1 { flex: 1; margin: 0; font-size: 19px; font-weight: 600;
|
||||
@@ -156,11 +176,24 @@
|
||||
<div class="screen" id="list">
|
||||
<div class="top">
|
||||
<div class="search">
|
||||
<div class="glass">⚲</div>
|
||||
<div class="glass">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round">
|
||||
<circle cx="11" cy="11" r="6.5" /><path d="M16 16l4.5 4.5" />
|
||||
</svg>
|
||||
</div>
|
||||
<input id="q" placeholder="Search" autocomplete="off" autocorrect="off"
|
||||
autocapitalize="none" spellcheck="false">
|
||||
<div class="clear" id="qx">×</div>
|
||||
</div>
|
||||
<button class="ico" id="lock" aria-label="Lock vault">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round">
|
||||
<path d="M7.5 10.5V7a4.5 4.5 0 0 1 9 0v3.5" />
|
||||
<rect x="4" y="10.5" width="16" height="10.5" rx="3" fill="currentColor"
|
||||
stroke="none" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="folders" id="folders"></div>
|
||||
<div class="scroll"><div id="rows"></div></div>
|
||||
@@ -286,6 +319,9 @@ q.addEventListener('input', function () {
|
||||
renderRows();
|
||||
send('touch');
|
||||
});
|
||||
document.getElementById('lock').addEventListener('click', function () {
|
||||
send('lock');
|
||||
});
|
||||
document.getElementById('qx').addEventListener('click', function () {
|
||||
q.value = ''; query = '';
|
||||
document.body.classList.remove('searching');
|
||||
|
||||
+17
-6
@@ -187,6 +187,17 @@ uses
|
||||
|
||||
{$R *.fmx}
|
||||
|
||||
const
|
||||
// Pictogrammes des boutons, EN POINTS DE CODE : ce fichier n'a pas de marque
|
||||
// d'ordre d'octets, Delphi le lit en ANSI, et un caractere ecrit tel quel y
|
||||
// deviendrait deux ou trois glyphes. Tous choisis dans le plan de base et
|
||||
// parmi les plus courants - une police systeme qui n'en aurait pas
|
||||
// afficherait un rectangle vide, ce qui se verrait tout de suite.
|
||||
GLYPH_OPEN = #$279C; // fleche pleine
|
||||
GLYPH_SYNC = #$21BB; // fleche circulaire
|
||||
GLYPH_GEAR = #$2699; // engrenage
|
||||
GLYPH_LOG = #$2261; // trois traits
|
||||
|
||||
{ ----------------------------------------------------------------------------
|
||||
Construction
|
||||
---------------------------------------------------------------------------- }
|
||||
@@ -334,17 +345,17 @@ begin
|
||||
LRow.Height := 48;
|
||||
LRow.Margins.Rect := RectF(16, 8, 16, 0);
|
||||
|
||||
FBtnLog := FlatButton(LRow, 'Log', OnToggleLog);
|
||||
FBtnLog := FlatButton(LRow, GLYPH_LOG + ' Log', OnToggleLog);
|
||||
FBtnLog.Align := TAlignLayout.Right;
|
||||
FBtnLog.Width := 120;
|
||||
FBtnLog.Margins.Left := 8;
|
||||
|
||||
FBtnSettings := FlatButton(LRow, 'Server settings', OnToggleSettings);
|
||||
FBtnSettings := FlatButton(LRow, GLYPH_GEAR + ' Server settings', OnToggleSettings);
|
||||
FBtnSettings.Align := TAlignLayout.Client;
|
||||
|
||||
FBtnSync := TopButton(FLayUnlock, 'Sync', DoSync);
|
||||
FBtnSync := TopButton(FLayUnlock, GLYPH_SYNC + ' Sync', DoSync);
|
||||
// Accentue : c'est l'action attendue quand aucun coffre n'est encore la.
|
||||
FBtnOpen := TopButton(FLayUnlock, 'Open vault', DoOpenLocal, 52, True);
|
||||
FBtnOpen := TopButton(FLayUnlock, GLYPH_OPEN + ' Open vault', DoOpenLocal, 52, True);
|
||||
|
||||
FStatus := TLabel.Create(Self);
|
||||
FStatus.Parent := FLayUnlock;
|
||||
@@ -373,12 +384,12 @@ begin
|
||||
Status('Vault on this device - protected')
|
||||
else
|
||||
Status('Vault on this device');
|
||||
SetButtonText(FBtnSync, 'Sync');
|
||||
SetButtonText(FBtnSync, GLYPH_SYNC + ' Sync');
|
||||
end
|
||||
else
|
||||
begin
|
||||
Status('No local vault - first download');
|
||||
SetButtonText(FBtnSync, 'Download vault');
|
||||
SetButtonText(FBtnSync, GLYPH_SYNC + ' Download vault');
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user