feat(FN-1813): merge fusion/fn-1813
This commit is contained in:
@@ -538,7 +538,6 @@ export async function runServe(
|
||||
const settingsStore = new GlobalSettingsStore(globalDir);
|
||||
const tokenManager = new DaemonTokenManager(settingsStore);
|
||||
daemonToken = await tokenManager.generateToken();
|
||||
await tokenManager.storeToken(daemonToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,9 @@ function useDraggable(projectId?: string, externalDidDragRef?: React.MutableRefO
|
||||
|
||||
// Default positions
|
||||
const getDefaultPosition = useCallback((): Position => {
|
||||
// Mobile uses smaller default offset (16px vs 24px)
|
||||
// Mobile uses tighter default offset (4px vs 24px) to maximize screen space
|
||||
if (typeof window !== "undefined" && window.innerWidth <= 768) {
|
||||
return { x: 16, y: 16 + getFooterHeight() };
|
||||
return { x: 4, y: 4 + getFooterHeight() };
|
||||
}
|
||||
return { x: 24, y: 24 + getFooterHeight() };
|
||||
}, [getFooterHeight]);
|
||||
@@ -82,7 +82,8 @@ function useDraggable(projectId?: string, externalDidDragRef?: React.MutableRefO
|
||||
if (typeof window === "undefined") return pos;
|
||||
|
||||
const fabSize = 48; // FAB is 48x48px
|
||||
const edgeMargin = 48; // Keep at least 48px from viewport edges
|
||||
// Mobile uses tighter margin (4px) to maximize screen space on small devices
|
||||
const edgeMargin = window.innerWidth <= 768 ? 4 : 48;
|
||||
// Account for mobile nav height when clamping bottom
|
||||
const mobileNavHeight = window.innerWidth <= 768 ? 44 : 0;
|
||||
// Account for executor footer height on desktop
|
||||
|
||||
@@ -2322,7 +2322,7 @@ describe("GitManagerModal", () => {
|
||||
fireEvent.click(screen.getByRole("tab", { name: /remotes/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("origin")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("remote-detail-card")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const editButton = screen.getByTitle("Edit remote URL");
|
||||
|
||||
@@ -533,6 +533,7 @@ describe("QuickChatFAB", () => {
|
||||
});
|
||||
|
||||
it("FAB position is clamped to viewport boundaries", async () => {
|
||||
// Desktop viewport (jsdom default 1024px > 768px): 48px edge margin
|
||||
render(<QuickChatFAB addToast={addToast} projectId="proj-123" />);
|
||||
|
||||
const fab = screen.getByTestId("quick-chat-fab");
|
||||
@@ -559,7 +560,81 @@ describe("QuickChatFAB", () => {
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
// Position should be clamped to at least 48px from edges
|
||||
// Desktop: position should be clamped to at least 48px from edges
|
||||
const savedPosition = JSON.parse(localStorageMock.setItem.mock.calls[0]?.[1] || "{}");
|
||||
expect(savedPosition.x).toBeGreaterThanOrEqual(48);
|
||||
expect(savedPosition.y).toBeGreaterThanOrEqual(48);
|
||||
});
|
||||
|
||||
it("on mobile viewport, FAB can be dragged to within 4px of the edge", async () => {
|
||||
// Mock mobile viewport (375px wide, which is <= 768px)
|
||||
Object.defineProperty(window, "innerWidth", { value: 375, writable: true });
|
||||
Object.defineProperty(window, "innerHeight", { value: 812, writable: true });
|
||||
|
||||
render(<QuickChatFAB addToast={addToast} projectId="proj-123" />);
|
||||
|
||||
const fab = screen.getByTestId("quick-chat-fab");
|
||||
|
||||
// Simulate drag to extreme position (off viewport)
|
||||
fireEvent.pointerDown(fab, {
|
||||
clientX: 100,
|
||||
clientY: 100,
|
||||
button: 0,
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
// Try to drag way off screen (negative coordinates)
|
||||
fireEvent.pointerMove(fab, {
|
||||
clientX: -1000,
|
||||
clientY: -1000,
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
fireEvent.pointerUp(fab, {
|
||||
clientX: -1000,
|
||||
clientY: -1000,
|
||||
button: 0,
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
// Mobile (375px <= 768px): position should be clamped to at least 4px from edges
|
||||
const savedPosition = JSON.parse(localStorageMock.setItem.mock.calls[0]?.[1] || "{}");
|
||||
expect(savedPosition.x).toBeGreaterThanOrEqual(4);
|
||||
expect(savedPosition.y).toBeGreaterThanOrEqual(4);
|
||||
});
|
||||
|
||||
it("on desktop viewport, FAB edge margin remains 48px", async () => {
|
||||
// Explicitly set desktop viewport (1024px wide, which is > 768px)
|
||||
Object.defineProperty(window, "innerWidth", { value: 1024, writable: true });
|
||||
Object.defineProperty(window, "innerHeight", { value: 768, writable: true });
|
||||
|
||||
render(<QuickChatFAB addToast={addToast} projectId="proj-123" />);
|
||||
|
||||
const fab = screen.getByTestId("quick-chat-fab");
|
||||
|
||||
// Simulate drag to extreme position (off viewport)
|
||||
fireEvent.pointerDown(fab, {
|
||||
clientX: 100,
|
||||
clientY: 100,
|
||||
button: 0,
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
// Try to drag way off screen (negative coordinates)
|
||||
fireEvent.pointerMove(fab, {
|
||||
clientX: -1000,
|
||||
clientY: -1000,
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
fireEvent.pointerUp(fab, {
|
||||
clientX: -1000,
|
||||
clientY: -1000,
|
||||
button: 0,
|
||||
pointerId: 1,
|
||||
});
|
||||
|
||||
// Desktop: position should be clamped to at least 48px from edges
|
||||
const savedPosition = JSON.parse(localStorageMock.setItem.mock.calls[0]?.[1] || "{}");
|
||||
expect(savedPosition.x).toBeGreaterThanOrEqual(48);
|
||||
expect(savedPosition.y).toBeGreaterThanOrEqual(48);
|
||||
|
||||
@@ -29006,15 +29006,15 @@ html .column.drag-over * {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.quick-chat-fab {
|
||||
right: 16px;
|
||||
bottom: calc(16px + var(--executor-footer-height-mobile, var(--executor-footer-height, 0px)) + var(--mobile-nav-height, 44px) + env(safe-area-inset-bottom, 0px));
|
||||
right: 4px;
|
||||
bottom: calc(4px + var(--executor-footer-height-mobile, var(--executor-footer-height, 0px)) + var(--mobile-nav-height, 44px) + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.quick-chat-panel {
|
||||
right: 16px;
|
||||
left: 16px;
|
||||
right: 4px;
|
||||
left: 4px;
|
||||
width: auto;
|
||||
bottom: calc(72px + var(--executor-footer-height-mobile, var(--executor-footer-height, 0px)) + var(--mobile-nav-height, 44px) + env(safe-area-inset-bottom, 0px));
|
||||
bottom: calc(60px + var(--executor-footer-height-mobile, var(--executor-footer-height, 0px)) + var(--mobile-nav-height, 44px) + env(safe-area-inset-bottom, 0px));
|
||||
height: min(420px, calc(100dvh - 160px));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user