mirror of
https://github.com/xmanrui/OpenClaw-bot-review.git
synced 2026-07-27 22:25:52 +00:00
fix: stabilize mobile logo carry across page re-entry
This commit is contained in:
@@ -47,21 +47,34 @@ export function GlobalBugsOverlay() {
|
||||
|
||||
const onStorage = () => applyConfig();
|
||||
const onConfigChanged = () => applyConfig();
|
||||
const getVisibleLogoAnchorCenter = (): { x: number; y: number } | null => {
|
||||
const anchors = Array.from(document.querySelectorAll<HTMLElement>("[data-openclaw-logo-anchor='true']"));
|
||||
for (const anchor of anchors) {
|
||||
const rect = anchor.getBoundingClientRect();
|
||||
if (rect.width <= 0 || rect.height <= 0) continue;
|
||||
return {
|
||||
x: (rect.left + rect.width / 2) / BUGS_ZOOM,
|
||||
y: (rect.top + rect.height / 2) / BUGS_ZOOM,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const onLogoDragStart = () => {
|
||||
if (!systemRef.current) return;
|
||||
// Detect mobile viewport
|
||||
const isMobile = window.matchMedia("(max-width: 767px)").matches;
|
||||
|
||||
// Calculate logo position based on viewport
|
||||
let startX: number;
|
||||
let startY: number;
|
||||
|
||||
if (isMobile) {
|
||||
// Mobile: logo is in top header, centered horizontally
|
||||
startX = (window.innerWidth / 2) / BUGS_ZOOM;
|
||||
startY = 28 / BUGS_ZOOM; // Half of header height (h-14 = 56px)
|
||||
const anchorCenter = getVisibleLogoAnchorCenter();
|
||||
if (anchorCenter) {
|
||||
startX = anchorCenter.x;
|
||||
startY = anchorCenter.y;
|
||||
} else {
|
||||
startX = (window.innerWidth / 2) / BUGS_ZOOM;
|
||||
startY = 28 / BUGS_ZOOM;
|
||||
}
|
||||
} else {
|
||||
// Desktop: logo is in left sidebar
|
||||
// Keep desktop behavior unchanged.
|
||||
startX = 58 / BUGS_ZOOM;
|
||||
startY = 42 / BUGS_ZOOM;
|
||||
}
|
||||
|
||||
+21
-2
@@ -188,6 +188,7 @@ export function Sidebar() {
|
||||
};
|
||||
|
||||
const logoTransform = `translate(${manualLogoOffset.dx + logoCarry.dx}px, ${manualLogoOffset.dy + logoCarry.dy}px) rotate(${logoCarry.angle + manualLogoAngle}rad)`;
|
||||
const mobileLogoTransform = `translate(${logoCarry.dx}px, ${logoCarry.dy}px) rotate(${logoCarry.angle}rad)`;
|
||||
const logoCursor = !bugsEnabled ? (isLogoDragging ? "grabbing" : "grab") : "default";
|
||||
const mobileCurrent = NAV_ITEMS.flatMap((g) => g.items).find((item) =>
|
||||
item.href === "/" ? pathname === "/" : pathname.startsWith(item.href)
|
||||
@@ -243,8 +244,26 @@ export function Sidebar() {
|
||||
>
|
||||
☰
|
||||
</button>
|
||||
<Link href="/" className="flex items-center gap-2 min-w-0">
|
||||
<span className="text-2xl leading-none">🦞</span>
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-2 min-w-0"
|
||||
onClickCapture={handleLogoClickCapture}
|
||||
onDragStart={handleLogoNativeDragStart}
|
||||
draggable={false}
|
||||
>
|
||||
<span
|
||||
className="relative inline-block text-2xl leading-none transition-opacity duration-300"
|
||||
data-openclaw-logo-anchor="true"
|
||||
onDragStart={handleLogoNativeDragStart}
|
||||
draggable={false}
|
||||
style={{
|
||||
transform: mobileLogoTransform,
|
||||
transformOrigin: "50% 50%",
|
||||
opacity: logoCarry.hidden ? 0 : 1,
|
||||
}}
|
||||
>
|
||||
🦞
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-bold tracking-wide truncate">OPENCLAW</div>
|
||||
<div className="text-[10px] text-[var(--text-muted)] truncate">
|
||||
|
||||
@@ -297,10 +297,25 @@ export class BugSystem {
|
||||
this.logoCarry.carrierIds.clear()
|
||||
this.logoCarry.laggers.clear()
|
||||
this.logoCarry.regripUntil.clear()
|
||||
this.logoCarry.logoX = this.logoCarry.startX
|
||||
this.logoCarry.logoY = this.logoCarry.startY
|
||||
this.logoCarry.logoVx = 0
|
||||
this.logoCarry.logoVy = 0
|
||||
this.logoCarry.logoAngle = 0
|
||||
this.logoCarry.logoAngularV = 0
|
||||
this.logoCarry.displayX = this.logoCarry.startX
|
||||
this.logoCarry.displayY = this.logoCarry.startY
|
||||
this.logoCarry.displayVx = 0
|
||||
this.logoCarry.displayVy = 0
|
||||
this.logoCarry.displayAngle = 0
|
||||
this.logoCarry.displayAngularV = 0
|
||||
for (const b of this.bugs) b.isCarrier = false
|
||||
}
|
||||
|
||||
getLogoCarryVisual(): { active: boolean; dx: number; dy: number; angle: number; hidden: boolean } {
|
||||
if (!this.logoCarry.active) {
|
||||
return { active: false, dx: 0, dy: 0, angle: 0, hidden: false }
|
||||
}
|
||||
return {
|
||||
active: this.logoCarry.active,
|
||||
dx: this.logoCarry.displayX - this.logoCarry.startX,
|
||||
@@ -660,11 +675,15 @@ export class BugSystem {
|
||||
this.logoCarry.logoAngle = clamp(this.logoCarry.logoAngle, -0.75, 0.75)
|
||||
this.logoCarry.logoX += this.logoCarry.logoVx * dt
|
||||
this.logoCarry.logoY += this.logoCarry.logoVy * dt
|
||||
} else {
|
||||
} else if (n > 0) {
|
||||
this.logoCarry.logoVx *= 0.85
|
||||
this.logoCarry.logoVy *= 0.85
|
||||
this.logoCarry.logoAngularV *= 0.82
|
||||
this.logoCarry.logoAngle += this.logoCarry.logoAngularV * dt
|
||||
} else {
|
||||
this.logoCarry.logoVx = 0
|
||||
this.logoCarry.logoVy = 0
|
||||
this.logoCarry.logoAngularV = 0
|
||||
}
|
||||
|
||||
// Keep visual center fully aligned with physical payload center.
|
||||
|
||||
Reference in New Issue
Block a user