Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3a298fb7c | ||
|
|
61219dbca2 |
No files matched your search
@@ -3,6 +3,15 @@
|
||||
All notable changes to CodeCraft. Versions follow [Semantic Versioning](https://semver.org/);
|
||||
until 1.0, minor versions may contain breaking changes.
|
||||
|
||||
## [v202611-00016] – 2026-11-10
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Phone: page stayed shifted after the keyboard closed** – the top bar (menu) was out of
|
||||
reach. On Android the keyboard now shrinks the page instead of shifting it
|
||||
(`interactive-widget=resizes-content`; the chat stays at its latest message); browsers that
|
||||
still shift the page (iOS Safari) get it scrolled back once the keyboard closes.
|
||||
|
||||
## [v202611-00015] – 2026-11-10
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img alt="Version v202611-00015" src="https://img.shields.io/badge/version-v202611--00015-d69e2e?style=flat-square">
|
||||
<img alt="Version v202611-00016" src="https://img.shields.io/badge/version-v202611--00016-d69e2e?style=flat-square">
|
||||
<img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-689d6a?style=flat-square">
|
||||
<img alt="Rust backend" src="https://img.shields.io/badge/backend-Rust-b7410e?style=flat-square&logo=rust">
|
||||
<img alt="React PWA" src="https://img.shields.io/badge/frontend-React%20PWA-2d81ff?style=flat-square&logo=react">
|
||||
|
||||
+3
-1
@@ -2,7 +2,9 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<!-- interactive-widget: the on-screen keyboard shrinks the page (Android) instead of
|
||||
shifting it up – the top bar stays in place. -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content" />
|
||||
<meta name="theme-color" content="#282828" />
|
||||
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
|
||||
@@ -202,6 +202,17 @@ export function ChatView({ sessionId, onMenu, onClosePane }: { sessionId: string
|
||||
const el = scrollRef.current;
|
||||
if (el && stick.current) el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
// … also when the pane gets smaller (on-screen keyboard opens) without a render.
|
||||
const hasSession = !!session;
|
||||
useEffect(() => {
|
||||
const el = scrollRef.current;
|
||||
if (!el || typeof ResizeObserver === "undefined") return;
|
||||
const ro = new ResizeObserver(() => {
|
||||
if (stick.current) el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
ro.observe(el);
|
||||
return () => ro.disconnect();
|
||||
}, [hasSession, sessionId]);
|
||||
|
||||
if (loadError) return <div className="empty">{loadError}</div>;
|
||||
if (!session) return <div className="empty">{t("common.loading")}</div>;
|
||||
|
||||
@@ -10,6 +10,43 @@ import { captureShare } from "./share";
|
||||
applyTheme();
|
||||
captureShare();
|
||||
registerSW({ immediate: true });
|
||||
undoKeyboardShift();
|
||||
|
||||
/**
|
||||
* Browsers that do not resize the page for the on-screen keyboard (iOS Safari, older
|
||||
* Android) scroll the whole page up to show the input – and do not always scroll it back
|
||||
* when the keyboard closes, leaving the top bar (menu) out of reach. The app never
|
||||
* scrolls the page itself (only its panes), so any page offset is undone once the
|
||||
* visible area grows again.
|
||||
*/
|
||||
function undoKeyboardShift() {
|
||||
const vv = window.visualViewport;
|
||||
if (!vv) return;
|
||||
let last = vv.height;
|
||||
const reset = () => {
|
||||
const el = document.scrollingElement ?? document.documentElement;
|
||||
if (window.scrollY !== 0 || el.scrollTop !== 0 || document.body.scrollTop !== 0) {
|
||||
window.scrollTo(0, 0);
|
||||
el.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
}
|
||||
};
|
||||
vv.addEventListener("resize", () => {
|
||||
// Grown back (keyboard closed or closing): after the browser's own adjustment.
|
||||
if (vv.height > last + 1) {
|
||||
requestAnimationFrame(reset);
|
||||
setTimeout(reset, 350);
|
||||
}
|
||||
last = vv.height;
|
||||
});
|
||||
// Keyboard closed by leaving the input (no resize on some browsers).
|
||||
document.addEventListener("focusout", () =>
|
||||
setTimeout(() => {
|
||||
const a = document.activeElement;
|
||||
if (!a || !(a instanceof HTMLInputElement || a instanceof HTMLTextAreaElement || (a as HTMLElement).isContentEditable)) reset();
|
||||
}, 300),
|
||||
);
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
|
||||
Reference in new issue
Block a user