Init/tarkov checker#2
Merged
Merged
Conversation
Add pnpm workspaces + Turborepo wiring, strict TS base config with @shared/* path alias, ESLint flat config (TS + Vue + Prettier), Prettier, EditorConfig, .nvmrc (Node 20), and .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Discriminated zod union for heartbeat/raid lifecycle/position WS payloads. Canonical Tarkov location code -> display name table (bigmap -> Customs, etc.) with type guard and helper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fastify 5 with pino (pino-pretty in dev), CORS open, and a /ws route
that emits {type:'heartbeat', t} every 5 seconds per connection.
Watcher path resolver stubbed with TODOs for the log and screenshot
directories.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vue 3 (Composition API) + Vite 5 + Pinia. Tailwind v4 wired via @tailwindcss/vite (CSS-first @import "tailwindcss"; no JS config). Thin imperative useLeafletMap composable with OSM placeholder tiles and useWebSocket that validates payloads with the shared zod schema. App.vue shows "Customs map placeholder" overlay + connection badge. vite-plugin-pwa with iOS-friendly manifest; placeholder icon files TODO. One Vitest placeholder spec covering the maps mapping. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hand-written Cargo.toml + tauri.conf.json + build.rs + src/{main,lib}.rs
+ capabilities/default.json. frontendDist points at ../../client/dist;
devUrl is http://localhost:5173; beforeDevCommand left empty so Vite
stays under Turbo orchestration (documented in apps/desktop/README.md
and CLAUDE.md). Window is 800x600, decorations on; transparency and
always-on-top deferred. @tauri-apps/cli pinned as a workspace devDep.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Generated by pnpm 10.13.1 across all four workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- apps/server/src/ws.ts: annotate socket error listener parameter (Fastify ws hands back a Node EventEmitter Error; explicit type avoids implicit-any under strict TS). - apps/client/tsconfig.app.json: drop composite, set baseUrl explicitly, and include packages/shared/src so vue-tsc resolves @shared/* imports without project references. - apps/client/tsconfig.node.json: same composite removal for the Vite/Vitest config project. - apps/client/vite.config.ts + vitest.config.ts: switch the alias block from object form to array-with-regex form so @shared/foo resolves to packages/shared/src/foo instead of concatenating onto index.ts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
README covers install, dev/build workflow with port table, lint/test commands, and conventions. CLAUDE.md records the non-obvious bits: @shared/* path alias scheme, the assume-running-Vite Tauri dev choice, the Tailwind v4 CSS-first deviation from the original spec, and the bootstrap quirk that the Rust toolchain was absent during scaffolding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace OSM placeholder tiles with the SVG maps from the-hideout/
tarkov-dev-svg-maps (added as a submodule at apps/client/public/maps/,
CC BY-NC-SA 4.0). Switch Leaflet to L.CRS.Simple, fetch the SVG and
parse it with DOMParser so top-level <g> groups remain reachable for a
future floor switcher (Customs is single-level so no switcher UI yet).
useLeafletMap now takes an svgUrl, returns shallow refs for map +
loaded metadata + error.
Promote the TARKOV_MAPS table in @tarkov-checker/shared from raw-code
-> string to raw-code -> { displayName, svgFile } so PascalCase SVG
filenames (StreetsOfTarkov.svg, GroundZero.svg) can diverge from the
human-readable name shown in the UI. Add mapSvgPath() helper.
App.vue now drives the current map from a hardcoded bigmap — the WS
raid-start handler will replace that once real raid events arrive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CREDITS.md attributes the-hideout/tarkov-dev-svg-maps and explains how the CC BY-NC-SA submodule stays isolated from our code license. README adds the submodule init step for first-time clones. CLAUDE.md gains sections covering the runtime SVG-fetch + L.CRS.Simple wiring, the per-map nature of <g>-group semantics (feature layers vs floors), and a note that in-game-to-SVG coord calibration is per-map and deferred until real position events arrive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
.claude/launch.json registers the workspace dev script so the preview tool can attach to the Vite server on :5173 without re-spawning it. Safe to share — no secrets, no machine-specific paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Promote TARKOV_MAPS entries with the in-game-to-SVG affine values (transform, rotation, bounds) and the base SVG layer id, copied from the-hideout/tarkov-dev frontend (MIT) — single source of truth so we do not have to recalibrate per map empirically. Add tarkov-api.ts with zod schemas for the GraphQL payloads we will actually consume (Position3D, Extract, MapExtracts). Wire the new subpath export. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
useLeafletMap now builds a per-map CRS extending L.CRS.Simple: rotation handled in projection, affine in transformation. Marker placement is just L.marker([z, x]) — no per-call math, calibration lives entirely in the CRS. Mirrors tarkov-dev/src/pages/map/index.jsx. apps/client/src/api/tarkov-dev.ts is a tiny GraphQL client (plain fetch, zod-validated, module-level promise cache) — no Apollo/urql for one query type. App.vue fetches extracts for the current map and drops L.circleMarker per extract, colored by faction (pmc green, scav yellow, shared blue), with a name tooltip on hover. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CREDITS.md gains sections for the tarkov-dev frontend (MIT, source of all per-map transform/rotation/bounds values) and the public tarkov.dev GraphQL endpoint. CLAUDE.md replaces the old map-rendering section with the custom CRS pipeline (rotation in projection, affine in transformation) and adds a section on the GraphQL client and how Map.nameId case-insensitively matches our raw codes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add FACTION_COLORS to @shared/maps so the map markers and the legend in the new settings popover never drift. fetchExtractsForMap now takes an explicit lang argument (en/ru/de/...) and the module-level promise cache is keyed by language — switching languages is one HTTP hit per language per session. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
apps/client/src/stores/settings.ts is a Pinia store backing apiLang, extractFactions, extractsVisible, and extractLabelMode. Persists to localStorage under a versioned key via a deep watch, with zod-validated load (corrupt data silently falls back to defaults). useLeafletMap grows three external setters — addExtractMarkers, setExtractFilter, setLabelMode — and an internal state object so that settings pushed before markers exist still apply on the first fetch. Faction filter toggles per-marker layer membership. Smart label mode binds tooltips with permanent: true and uses moveend / zoomend listeners to openTooltip only for markers whose latLng is inside map.getBounds() AND whose zoom is at least initialZoom + SMART_LABEL_ZOOM_DELTA — so on a full-map fitBounds view there is no text noise, and labels appear as the user zooms in. styles.css gets a small extract-tooltip rule: dark glassy background, no arrow, small bold text — matches the badges and stays unobtrusive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
components/SettingsPanel.vue is a gear-icon button with a dark popover-above-icon panel: language radio (EN/RU), an Extracts master switch, three faction checkboxes with their map colors as legend dots, and a hover/smart label-mode toggle with a one-liner hint. Closes on outside click and on Escape; focus ring matches the app theme; touch targets are at least 36px. App.vue wires three reactive watchers — apiLang refetches, faction + master push into setExtractFilter, labelMode pushes into setLabelMode. Settings push happens once synchronously before the first fetch so brand-new markers come up already filtered. CLAUDE.md gains a User settings section documenting the store, the versioned localStorage key, and the smart-label heuristic (with a note that the zoom threshold lives in useLeafletMap as a tunable constant, not as a user setting). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three feedback-driven polish items: - Map title at top now reads from the API localized Map.name (e.g. Customs becomes Таможня when apiLang=ru) instead of the hardcoded TARKOV_MAPS displayName. shared.tarkov-api gets a name field on MapExtracts; the App.vue title binding swaps to a ref updated on every fetch, with the hardcoded displayName as a startup fallback. - Co-located extracts (e.g. RUAF Roadblock has both a PMC and a Scav variant at nearly identical x,z) used to render as a single obscured marker. addExtractMarkers now buckets entries by rounded game-coord position and, for any bucket with more than one entry, spreads them radially around the original point. Offset is a constant pixel value divided by the per-map scale so the visual spacing stays consistent across maps. - SettingsPanel switches from an absolute popover anchored to the gear icon, to a fixed bottom-sheet on viewports below the sm breakpoint (covers the iPod touch 7 case at 320px wide). Tailwind prefix restores the desktop popover above the breakpoint, so the experience stays compact on big screens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…amp pan Markers stay at their true in-game (x, z) coordinates — the previous spreadOverlapping shifted the marker latLng itself, which moved the dot off the actual exit. That is reverted. Instead, computeTooltipOffsets buckets entries by rounded (x, z) and assigns each member of a colocated group a radial pixel offset (TOOLTIP_RING_RADIUS = 22 px). Tooltip direction switches to center so the offset places the label centre relative to the marker centre; bindTooltip is called per-entry with its own offset. Singleton extracts get the same formula (offset [0, -22] = label above the dot). Map panning is now bounded. L.map gets maxBoundsViscosity = 1.0 and we call setMaxBounds(bounds.pad(0.15)) after fitBounds, plus setMinZoom to the post-fit zoom so the map cannot be zoomed-out into infinity either. Wild swipes resist and snap; the map can no longer disappear off-screen. mapBoundsLatLng to mapLatLngBounds and now returns L.LatLngBounds directly so .pad() composes; the LatLngBoundsExpression import is no longer needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Faction names in the tarkov.dev API are raw enum strings (pmc/scav/ shared) with no localized variant, so UI labels are kept locally in a small i18n module instead. apps/client/src/i18n.ts ships en/ru bundles covering: Language/Extracts/Labels section headers, faction names (PMC/Scav/Shared vs ЧВК/Дикие/Общие), label-mode toggle, the smart- mode hint, and the Settings aria-label. useUiText composable returns a computed bundle keyed off settings.apiLang, so switching language refreshes the whole popover instantly. Map title moved from top-center to top-right and bumped to z-1000 so it no longer collides with Leaflet tooltip-pane content (which ships at z 650). Settings popover lifted to z-1010, error toasts moved just below the title row. The previous overlap visible on the iPod touch screenshot, where extract label Pruti (Signal) mashed into the title, is gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Server now watches the Tarkov screenshots directory for new F12-overlay PNGs, parses their filename for the embedded (X, Y, Z) position triple, and fans the result to every connected WS client as a position message. Path resolver tries TARKOV_SCREENSHOT_DIR first, then walks the usual OneDrive / Documents candidates under the home directory so OneDrive setups (where the Documents folder is redirected) get picked up without extra config. Logs a warning instead of crashing if the folder is missing — the player marker pipeline just stays dormant. WS plugin gains a Hub class: a Set of connected sockets plus a broadcast helper that lets watchers fan out without knowing about individual sockets. The 5s heartbeat stays per-socket; position and future raid events go through broadcast. The filename parser lives in @tarkov-checker/shared (re-exported from the index barrel) so the client side can run unit tests against it. Vitest covers the typical Tarkov filename, full Windows paths, .jpg rejection, names without a coordinate triple, and integer-only coords. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Map rendering, extracts fetching and the position-stream subscription move out of App.vue into MapView.vue. App now drives MapView through a :key bound to the current mapCode, so changing the selected map fully re-mounts the composable instead of trying to mutate Leaflet state in place. App.vue still owns the WS connection (kept stable across map switches) and forwards lastMessage down as a prop. useLeafletMap exposes setPlayerPosition / clearPlayerPosition. A position WS message paints two markers under the player layer: a solid red dot and a pulsing ring (CSS keyframe scaling stroke outward, fading). A 90-second stale timer clears the marker if no new position arrives. Settings store gains a persisted mapCode field plus a zod default so saves from older builds keep their other settings. SettingsPanel gets a Map section with a localized dropdown built from the fetchAllExtracts(lang) names cache, falling back to the hardcoded displayName until the API responds. The i18n bundle gets a map label for the section header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two changes: - turbo.json dev task gains an explicit env passthrough list (NODE_ENV, PORT, HOST, TARKOV_LOG_DIR, TARKOV_SCREENSHOT_DIR, LOCALAPPDATA, USERPROFILE, OneDrive, HOME). Without this, depending on the turbo version, system env vars may not reach the spawned task and resolveWatcherPaths fell back to null. - resolveWatcherPaths now returns the full candidate list with each paths existence flag, and startWatchers logs the candidates plus the relevant env vars at startup. So when a user reports that the pipeline is dormant, the logs immediately show exactly which paths were tried and what the env looks like. Screenshot candidate list extended to cover OneDrive variants users hit in the wild ($OneDrive/Documents, ~/OneDrive/Documents, ~/OneDrive - Personal/Documents, ~/Escape from Tarkov/Screenshots). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the two Tarkov paths out of shell env vars and OneDrive/Documents guesswork into a single .env at the repo root. Node 22 reads it on boot via --env-file-if-exists, so no dotenv dep, and missing file is silent. The heuristics from the previous diagnostic commit go away entirely — Tarkov installs vary too much for a heuristic to be reliable, and asking the user to set two absolute paths once is strictly less friction than walking them through what OneDrive did. resolveWatcherPaths is now literally read TARKOV_SCREENSHOT_DIR and TARKOV_LOG_DIR. dirExists stays the gate for actually starting a watcher, so an unset or wrong path falls through to a warning and the server keeps running with extracts/map intact. turbo dev task no longer needs the LOCALAPPDATA/OneDrive/USERPROFILE passthrough either — those mattered only for the old heuristics. .env.example documents the two keys with example Windows paths so a fresh clone has a one-step setup: cp .env.example .env, fill in. A first-class UI for path config (settings panel section + server config endpoint) can land later when it is worth the backend. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tarkov path resolution gets a real priority chain instead of OneDrive guesswork. Highest-priority source wins: 1. .env (TARKOV_GAME_DIR, TARKOV_SCREENSHOT_DIR, optional TARKOV_LOG_DIR override). 2. Manual override stored in apps/server/data/config.json (gitignored, written by PUT /api/config from the in-app Settings panel). 3. Windows-registry auto-detect — HKCU User Shell Folders\Personal for Documents (so OneDrive-redirected Documents resolves correctly), plus the usual Battlestate Games\EFT\InstallLocation keys for the game folder. reg query is invoked with chcp 65001 first so Cyrillic paths decode cleanly. logsDir is derived (gameDir/Logs) unless overridden explicitly, so the user only ever has to set the game folder. WatcherManager replaces the one-shot startWatchers helper: stopAll + apply(paths) so PUT /api/config can reconfigure in place without a process restart. CORS now allows GET/POST/PUT/DELETE/OPTIONS explicitly — its default methods list dropped PUT silently after preflight. The Fastify port reads SERVER_PORT (not PORT) since dev tooling sometimes sets PORT=5173 for the whole runner. Shared adds a config-api zod module so the client gets a typed ServerConfigResponse/Update without having to redeclare the shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New Tarkov paths section at the top of the Settings panel. - Two text inputs (Game folder, Screenshots folder), each with a small status dot (green = exists, amber = set but not on disk, red = no value) and a source badge (auto-detected, manual, from env, not found). Logs path is shown read-only underneath Game folder since it derives from it. - Inputs become read-only on viewports below the sm breakpoint (configuring D-colon-EFT on an on-screen phone keyboard is painful), with a hint to configure on the desktop. A window resize listener flips isDesktop reactively so the same browser tab works after DevTools device emulation toggles. - env-sourced values get the input disabled (cannot edit through UI when env is the priority source). Save button only enables when there is an actual dirty diff and at least one editable field. - Saved pill flashes for 2s after a successful PUT. apps/client/src/api/server-config.ts is a plain fetch wrapper validating GET/PUT against the shared zod schemas. i18n bundle gains a paths block (en plus ru, including source badges and the missing- folder tooltip) keyed off apiLang as before. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
README Tarkov paths section now describes the priority chain (env then manual UI override then registry auto-detect) instead of pretending env is the only source. Notes that gameDir is the one users will likely have to set manually since BSG Launcher writes the registry key inconsistently across installs. .env.example documents the three keys (game, screenshot, optional log override) with explicit leave-blank-to-let-lower-priority-source- win guidance. CLAUDE.md gains a Tarkov path resolution section covering the priority chain, the chcp 65001 trick for Cyrillic Documents, the SERVER_PORT vs PORT split, and the fastify-cors PUT-method gotcha. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parser now returns ParsedScreenshot (position, orientation Quaternion or null), so unrelated PNGs still fall through cleanly while real Tarkov F12 screenshots also surface the orientation quaternion. quaternionToYawDegrees extracts rotation around the world Y axis from the quaternion (atan2 on the standard Unity Y-up formula). The screenshot watcher computes yaw on the server and sends it as an optional field on the position WS message, so clients do not need a quaternion math helper. Unit tests cover identity, plus 90 and 180 degrees around Y, plus the parser-with-orientation case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Player marker is now a divIcon SVG (white dot + red cone) rotated by in-game yaw plus the maps own coordinateRotation, so the arrow points where the player is actually looking on the rendered map. yaw comes through the position WS message; null yaw skips the cone and shows just the dot, so clients connecting to older servers degrade gracefully. Pulse animation softened from scale 0.4 to 2.2 with 0.9 opacity down to scale 1 to 1.55 with 0.55 opacity, on a slower ease curve. Less flashy, easier on the eye. Extract label mode smart replaced with always — permanent tooltips show up regardless of zoom or viewport, matching the preferred behaviour. The settings store auto-migrates old smart saves to always via a zod transform; default is always. i18n bundle labels updated to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tailwind v4 plus @plugin daisyui locked to a single dark theme. data-theme on html keeps SSR-free render predictable. SettingsPanel rewritten with DaisyUI primitives instead of hand-rolled classes: card+card-body for the popover, join+btn for language and label-mode pickers, badge with semantic colour variants for the path-source pill, input with input-bordered for path text fields, toggle for the extracts master switch, checkbox-primary for faction filters, select-bordered for the map dropdown, alert-error for the inline error toast, plus a max-h scroll container on the popover body so mobile sheets stay in viewport. App overlays migrate to base-* tokens so they pick up the daisy theme: ws-status pill uses bg-success/warning/error, error toasts become alert components, the map-title chip uses bg-base-300/70. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five small follow-ups from a feedback pass: - Custom Leaflet pane extracts with z-index 500 holds all extract + player markers, so async-loaded svgOverlay (overlayPane z 400) no longer covers them after a map switch. - Permanent tooltips were being closed by stray click events on the marker. A per-marker click handler now re-opens the tooltip on the next tick when label mode is always. - Drop the zod transform that migrated old smart label-mode saves and bump the settings storage key v1 -> v2. Cleaner schema; the price is that users coming from a very old build re-pick defaults once. Rename i18n labelSmart -> labelAlways so naming matches behaviour. - Faction checkboxes are now stacked vertically (flex flex-col) — the DaisyUI .label class is inline-flex so multiple labels in a row used to sit on the same line. - Path input fields lift to bg-base-100 (vs the popovers bg-base-200) for visible contrast. Map dropdown gets the same. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four interlocked UX changes: - Settings popover replaced with a slide-in drawer (Teleport to body, backdrop overlay, Escape and click-outside close). Full width on mobile, w-96 on sm and up. Bottom of body is a single scroll area so long lists do not overflow on small phones. - Each section is now a real fieldset+fieldset-legend on a base-100 surface with a border, matching the daisy theme. Inputs inside go to bg-base-200 for contrast against the fieldset. - Master extracts toggle is gone. extractsVisible removed from the settings store (storage key bumped v2 to v3), useLeafletMap loses the second arg of setExtractFilter, MapView watches just the factions array. Empty factions = nothing shown, which is the same end state but with one fewer control. - tarkov.dev API client gains a localStorage cache keyed by language with a fetchedAt timestamp. fetchAllExtracts is cache-first; refreshExtracts forces a network round-trip and replaces the entry. Settings drawer gets a Data cache fieldset showing last updated relative age plus a Refresh button. tarkov.dev is blocked from some RU networks, so a stable offline copy is the difference between working and broken. shadow-none on the active join buttons fixes the visible blob under the chosen option in EN/RU and labels picker. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the tarkov.dev cache off the client onto the server, where it
belongs architecturally:
- apps/server/src/extracts-cache.ts: file-backed cache at
apps/server/data/extracts-cache.json keyed by language. Concurrent
fetches for the same language share one in-flight promise.
- GET /api/extracts?lang=<lang>&refresh=<0|1>: cache-first by default,
refresh=1 forces a network round-trip and replaces the entry.
Response is { lang, fetchedAt, data }, all zod-validated through
the new extractsCacheResponse schema in @tarkov-checker/shared.
- Client tarkov-dev.ts drops its localStorage cache layer and just
GETs the local server endpoint. refreshExtracts passes refresh=1;
getCacheTimestamp reads from a small in-memory Map populated on
each successful response.
- SettingsPanel loadMapNames refreshes the cache timestamp in finally,
so the Data cache section shows a real time the moment maps load
on mount.
The win is operational, not just architectural: tarkov.dev is blocked
from some RU networks, but the server only needs working egress once
(VPN, mobile hotspot, etc.) and every phone/desktop/Tauri client on
the LAN reads the cached data over local HTTP regardless of their
own connectivity.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
factory4_night and sandbox_high share their SVG, transform and bounds with factory4_day and sandbox respectively, so picking between them in the UI is noise. Their nameId still matters for log parsing — keep the entries in TARKOV_MAPS, mark them as aliases. TarkovMapInfo gets `canonical: TarkovMapCode | null`. Non-null means this code is an alias of the listed code. Canonicals stay null. factory4_day display name drops the (Day) suffix now that no second Factory variant sits next to it in the picker. Exported helpers: - canonicalMapCode(code) — resolves an alias to its canonical (or passes the code through unchanged). Useful once the log watcher starts surfacing raw nameIds. - VISIBLE_MAP_CODES — pre-filtered list of canonical codes for selectors. SettingsPanel now imports this instead of all TARKOV_MAPS keys, so the map dropdown shows 10 entries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two small drawer rough edges: - backdrop-blur-sm on the overlay was blurring the visible map on desktop where the drawer only takes 384px on the right. The blur was meaningful on mobile (drawer covers everything anyway) so it was dead weight everywhere — dropped. Just dim with bg-black/40 now. - The SETTINGS header used to scroll away with the body on long mobile panels. Made it sticky top-0 with bg-base-200 and a small z-index so it stays parked at the top while the fieldsets scroll under it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A click on an extract marker reopened the tooltip (per-marker click handler set it up), but a follow-up click on empty map space closed it again and stayed closed until reload. Leaflet fires map.click for the empty area, no marker.click — so the existing handler never ran. Reworked into reopenAllPermanentTooltips: instead of re-opening just the clicked marker, re-open every visible markers tooltip after any click. Bound it both on each marker click (unchanged path) and on map.click (new), so a click on empty map space now restores every permanent tooltip too. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…itle TARKOV_MAPS gains floors and defaultFloor per map, populated from the actual top-level g ids in each vendored SVG (Customs, Shoreline, Streets, Ground Zero get a five-floor stack, Factory four, Interchange three, Labs and Reserve two; Woods and Lighthouse stay single-level and skip the switcher). useLeafletMap exposes setActiveFloor and a currentFloor ref. Ground floor (the maps defaultFloor) is never hidden — when the user picks a different level the ground stays visible at opacity 0.2 so the upper floors interior still has a street layout behind it. Other floors are fully hidden with display none. New FloorSwitcher.vue lives bottom-left. A pill button shows the current level as Floor N (i18n: Floor or Уровень), click expands a vertical stack of small circle buttons upward. Active floor is btn-primary, others btn-neutral. Click outside or Escape closes. Component hides itself when the map has 0 or 1 floors. WS status moves out of its own bottom-right chip into a small colored dot before the map title in the top-right pill. Hover title surfaces the raw state. Less visual clutter for the LAN/phone use case where the connection is essentially always on. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Labs Technical_Level and Factory Basement cover the same horizontal area as their ground floor and sit underneath it in the SVG DOM. The old ground-stays-dim rule painted the dim ground group on top of the underground geometry and obscured most of it. setActiveFloor now keeps ground dim only when the active floor label is strictly greater than ground label, i.e. when the player goes UP the building, where the ground street layout is genuinely useful as context. For below-ground floors the ground group goes display:none so the underground geometry renders clean. Above-ground behaviour is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ground floor is the persistent context — it is never hidden now, just dimmed to opacity 0.15 when another level is active and shown at full opacity when ground itself is active. The previous fix that display:noned ground for below-ground floors solved the occlusion symptom but lost the spatial context. The real problem was SVG draw order: in Labs the Technical_Level group is the first child of the SVG so the later-rendered First_Level (ground) paints over it. Same shape on Factory. setActiveFloor now also appendChild()s the active group on each switch, moving it to the end of the SVG children list. SVG draws later siblings on top of earlier ones, so the chosen floor always renders above ground regardless of its original DOM position. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Added PrimeVue components including Button, ConfirmDialog, and Message for enhanced UI interactions. - Updated package dependencies to include @primeuix/themes, @tauri-apps/api, and others for improved functionality. - Introduced a new Tarkov preset for theming with PrimeVue. - Implemented new font styles and icons for better visual consistency. - Enhanced overlay functionality with click-through options and hotkey management. - Updated i18n support for new UI elements and settings. This commit enhances the overall user experience by leveraging PrimeVue's component library and improving the application's visual design.
…on; add essential components, routing, and state management. Create CLAUDE.md for project structure and development workflow documentation. Update pnpm lockfile for dependency management.
- Updated the context menu handling to open the quick transparency panel only in Tauri environments, allowing the native context menu to function normally in browsers. - Added a check to ensure the context menu is only triggered when right-clicking within the `.leaflet-container`, improving user experience and preventing unintended interactions.
…verlayClickThrough state - Updated the App.vue component to only display the SettingsPanel when overlayClickThrough is false, enhancing user interaction. - Adjusted the Button visibility to also depend on the isTauri and overlayClickThrough states, ensuring a more intuitive UI experience.
…DELTA values - Consolidated LeafletMap imports for cleaner code. - Updated FOLLOW_ZOOM_DELTA values to improve zoom behavior in follow modes, enhancing user experience on the map.
…te project structure - Added a new in-process server in the Tauri application to replace the Node/Fastify backend, allowing for direct communication via Tauri events and commands. - Updated CLAUDE.md to reflect changes in project structure and development workflow, including detailed descriptions of each package's responsibilities. - Introduced new commands for configuration management and extracts fetching, enhancing the integration between the Rust backend and the Tauri frontend. - Updated package.json to include a new build script for the overlay. - Created a GitHub Actions workflow for building the overlay and attaching the executable to draft releases. - Refactored client-side code to utilize the new server transport mechanism, improving communication efficiency in Tauri mode.
…se process - Enhanced the build workflow to support manual dispatch and automatic releases on master and version tag pushes. - Added permissions for content writing to facilitate release creation. - Improved artifact handling to ensure .exe files are always uploaded as workflow artifacts. - Updated release publishing logic to differentiate between manual and automated builds, ensuring proper tagging and release notes generation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.