Compare commits

..

No commits in common. "a482828244f2f24a8c29edf49782e2a885ff4572" and "932033682de708c063a1342ee9a0e6df2b89eeb6" have entirely different histories.

6 changed files with 21 additions and 59 deletions

View File

@ -6,6 +6,6 @@ DB_PORT=5432
DB_NAME= DB_NAME=
PORT=5000 PORT=5000
JWT_SECRET=change-me JWT_SECRET=change-me
ALLOWED_ORIGINS=http://localhost:3010,http://127.0.0.1:3010,http://192.168.7.45:3010 ALLOWED_ORIGINS=http://localhost:3000
SESSION_COOKIE_NAME=sid SESSION_COOKIE_NAME=sid
SESSION_TTL_DAYS=30 SESSION_TTL_DAYS=30

View File

@ -1,3 +1,2 @@
# Leave blank to infer the API host from the browser URL, e.g. http://192.168.7.45:5000. VITE_API_URL=http://localhost:5000
VITE_API_URL= VITE_ALLOWED_HOSTS=localhost,127.0.0.1
VITE_ALLOWED_HOSTS=localhost,127.0.0.1,192.168.7.45

View File

@ -1,41 +1 @@
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "::1"]); export const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:5000";
function trimTrailingSlash(value: string) {
return value.replace(/\/+$/, "");
}
function getDefaultApiBaseUrl() {
if (typeof window === "undefined") {
return "http://localhost:5000";
}
const protocol = window.location.protocol === "https:" ? "https:" : "http:";
return `${protocol}//${window.location.hostname}:5000`;
}
function shouldUseBrowserHostForApi(url: URL) {
if (typeof window === "undefined") {
return false;
}
return LOOPBACK_HOSTS.has(url.hostname) && !LOOPBACK_HOSTS.has(window.location.hostname);
}
function resolveApiBaseUrl() {
const configuredApiUrl = import.meta.env.VITE_API_URL?.trim();
if (!configuredApiUrl) {
return getDefaultApiBaseUrl();
}
try {
const apiUrl = new URL(configuredApiUrl);
if (shouldUseBrowserHostForApi(apiUrl)) {
apiUrl.hostname = window.location.hostname;
}
return trimTrailingSlash(apiUrl.toString());
} catch {
return trimTrailingSlash(configuredApiUrl);
}
}
export const API_BASE_URL = resolveApiBaseUrl();

View File

@ -1200,7 +1200,7 @@
} }
.location-map-toolbar { .location-map-toolbar {
--location-map-mode-slot: 132px; --location-map-mode-slot: 168px;
--location-map-history-slot: 84px; --location-map-history-slot: 84px;
column-gap: 0.15rem; column-gap: 0.15rem;
row-gap: 0.35rem; row-gap: 0.35rem;
@ -1219,6 +1219,13 @@
min-width: 28px; min-width: 28px;
} }
.location-map-toolbar.has-history-slot .location-map-zoom-controls {
grid-column: 1 / -1;
width: 100%;
justify-self: stretch;
justify-content: space-between;
}
.location-map-display-controls { .location-map-display-controls {
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
} }

View File

@ -1443,8 +1443,8 @@ test("mobile keeps viewing draft status compact in the topbar", async ({ page })
expect(statusBox.y).toBeLessThan(titleBox.y + titleBox.height); expect(statusBox.y).toBeLessThan(titleBox.y + titleBox.height);
expect(statusBox.x).toBeGreaterThan(titleBox.x); expect(statusBox.x).toBeGreaterThan(titleBox.x);
expect(toolbarBox.height).toBeLessThanOrEqual(64); expect(toolbarBox.height).toBeLessThanOrEqual(64);
expect(modeBox.width).toBeGreaterThanOrEqual(130); expect(modeBox.width).toBeGreaterThanOrEqual(166);
expect(modeBox.width).toBeLessThanOrEqual(136); expect(modeBox.width).toBeLessThanOrEqual(172);
await expect(historyActions).toHaveCount(0); await expect(historyActions).toHaveCount(0);
expect(zoomBox.y).toBeLessThan(modeBox.y + modeBox.height); expect(zoomBox.y).toBeLessThan(modeBox.y + modeBox.height);
expect(zoomBox.x).toBeGreaterThan(modeBox.x + modeBox.width - 1); expect(zoomBox.x).toBeGreaterThan(modeBox.x + modeBox.width - 1);
@ -1470,14 +1470,13 @@ test("mobile keeps viewing draft status compact in the topbar", async ({ page })
expect(Math.abs(editModeBox.x - modeBox.x)).toBeLessThanOrEqual(1); expect(Math.abs(editModeBox.x - modeBox.x)).toBeLessThanOrEqual(1);
expect(Math.abs(editModeGroupBox.width - modeGroupBox.width)).toBeLessThanOrEqual(1); expect(Math.abs(editModeGroupBox.width - modeGroupBox.width)).toBeLessThanOrEqual(1);
expect(Math.abs(editModeBox.width - modeBox.width)).toBeLessThanOrEqual(1); expect(Math.abs(editModeBox.width - modeBox.width)).toBeLessThanOrEqual(1);
expect(editToolbarBox.height).toBeLessThanOrEqual(64); expect(editModeBox.width).toBeGreaterThanOrEqual(166);
expect(editModeBox.width).toBeGreaterThanOrEqual(130); expect(editModeBox.width).toBeLessThanOrEqual(172);
expect(editModeBox.width).toBeLessThanOrEqual(136);
expect(editHistoryBox.width).toBeGreaterThanOrEqual(82); expect(editHistoryBox.width).toBeGreaterThanOrEqual(82);
expect(editHistoryBox.x).toBeGreaterThan(editModeBox.x + editModeBox.width); expect(editHistoryBox.x).toBeGreaterThan(editModeBox.x + editModeBox.width);
expect(editHistoryBox.x + editHistoryBox.width).toBeLessThanOrEqual(editToolbarBox.x + editToolbarBox.width + 1); expect(editHistoryBox.x + editHistoryBox.width).toBeLessThanOrEqual(editToolbarBox.x + editToolbarBox.width + 1);
expect(editZoomBox.y).toBeLessThan(editModeBox.y + editModeBox.height); expect(editZoomBox.y).toBeGreaterThan(editModeBox.y + editModeBox.height - 1);
expect(editZoomBox.x).toBeGreaterThan(editHistoryBox.x + editHistoryBox.width - 1); expect(editZoomBox.x).toBeGreaterThanOrEqual(editToolbarBox.x);
expect(editZoomBox.x + editZoomBox.width).toBeLessThanOrEqual(editToolbarBox.x + editToolbarBox.width + 1); expect(editZoomBox.x + editZoomBox.width).toBeLessThanOrEqual(editToolbarBox.x + editToolbarBox.width + 1);
}); });
@ -1583,8 +1582,8 @@ test("narrow mobile toolbar keeps map controls tappable without overflow", async
expect(toolbarBox.x).toBeGreaterThanOrEqual(0); expect(toolbarBox.x).toBeGreaterThanOrEqual(0);
expect(toolbarBox.x + toolbarBox.width).toBeLessThanOrEqual(361); expect(toolbarBox.x + toolbarBox.width).toBeLessThanOrEqual(361);
expect(modeBox.width).toBeGreaterThanOrEqual(130); expect(modeBox.width).toBeGreaterThanOrEqual(166);
expect(modeBox.width).toBeLessThanOrEqual(136); expect(modeBox.width).toBeLessThanOrEqual(172);
expect(modeBox.x + modeBox.width).toBeLessThanOrEqual(historyBox.x); expect(modeBox.x + modeBox.width).toBeLessThanOrEqual(historyBox.x);
expect(zoomBox.y).toBeGreaterThan(modeBox.y + modeBox.height - 1); expect(zoomBox.y).toBeGreaterThan(modeBox.y + modeBox.height - 1);
expect(zoomBox.x).toBeGreaterThanOrEqual(toolbarBox.x); expect(zoomBox.x).toBeGreaterThanOrEqual(toolbarBox.x);

View File

@ -2,12 +2,9 @@ import react from '@vitejs/plugin-react';
import { defineConfig, loadEnv } from 'vite'; import { defineConfig, loadEnv } from 'vite';
const env = loadEnv('', process.cwd()); const env = loadEnv('', process.cwd());
const configuredAllowedHosts = env.VITE_ALLOWED_HOSTS const allowedHosts = env.VITE_ALLOWED_HOSTS
? env.VITE_ALLOWED_HOSTS.split(',').map((host) => host.trim()) ? env.VITE_ALLOWED_HOSTS.split(',').map((host) => host.trim())
: []; : [];
const allowedHosts = Array.from(
new Set(['localhost', '127.0.0.1', '192.168.7.45', ...configuredAllowedHosts].filter(Boolean))
);
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],