Files
wiki/tasks/enduro-trails/DEV_TASK_DARK_STYLE.md
2026-05-12 23:20:01 +03:00

286 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DEV TASK: Тёмная тема карты (F-18)
**Статус:** Ready for dev
**Проект:** enduro-trails
**Фаза:** 5.1
**BRD:** нет (простая фича)
---
## Цель
> Карта MapLibre переключается между светлым и тёмным стилем синхронно с темой UI (auto/light/dark + SunCalc).
## Архитектура
Сейчас `style.json` — это светлый стиль (фон `#f0ede6`, OSM raster desaturated). Нужно создать `style-dark.json` с тёмной палитрой и исправить логику в `switchMapStyle()`, которая сейчас инвертирована (считает `style.json` тёмным).
Подход: тёмный стиль = тот же OSM raster, но с `brightness-max: 0.3`, `contrast: -0.2`, тёмный background. Цвета треков и POI адаптированы для тёмного фона.
## Стек / Зависимости
- MapLibre GL JS (уже подключён)
- Никаких новых зависимостей
---
## Инфраструктура
| Параметр | Значение |
|----------|----------|
| Сервер | `slin@82.22.50.71` (пароль: `motoZ@yaz2010`) |
| Рабочая директория | `/home/slin/enduro-trails/prototype/static/` |
| Workspace | `/home/node/.openclaw/workspace/tasks/enduro-trails/prototype/static/` |
| Деплой | SFTP + `docker cp` после рестарта |
| Контейнер | `prototype-enduro-trails-1` |
| URL | `https://openclaw.mva154.duckdns.org/enduro/` |
---
## Файловая карта
| Действие | Файл | Ответственность |
|----------|------|-----------------|
| Создать | `static/style-dark.json` | Тёмный стиль карты |
| Переименовать | `static/style.json` → оставить как есть | Светлый стиль (уже есть) |
| Изменить | `static/app.js` (строки 86-105) | Исправить логику switchMapStyle |
---
## Задачи
### Task 1: Создать style-dark.json
**Файлы:**
- Создать: `static/style-dark.json`
**Шаги:**
- [ ] **1.1** Создать `style-dark.json` на основе `style.json` со следующими изменениями:
```json
{
"name": "Enduro Trails Dark",
"layers": [
{
"id": "background",
"paint": { "background-color": "#1a1a2e" }
},
{
"id": "osm-base",
"paint": {
"raster-opacity": 1.0,
"raster-saturation": -0.6,
"raster-contrast": -0.1,
"raster-brightness-min": 0,
"raster-brightness-max": 0.35
}
},
{
"id": "trails-track",
"paint": {
"line-color": "...",
"line-opacity": 0.95
}
// Цвета треков: grade1/2 → #FFE066, grade3/4/5 → #FF6633, default → #FF6633
},
{
"id": "trails-path-bridleway",
"paint": {
"line-color": "#ff4444",
"line-opacity": 0.9
}
},
{
"id": "poi-circles",
"paint": {
"circle-stroke-color": "#333333"
// Остальные цвета POI — ярче на 10-15% для контраста на тёмном фоне
}
},
{
"id": "poi-labels",
"paint": {
"text-color": "#e0e0e0",
"text-halo-color": "#1a1a2e",
"text-halo-width": 2
}
}
]
}
```
Полная спецификация изменений относительно `style.json`:
| Слой | Свойство | Светлый | Тёмный |
|------|----------|---------|--------|
| background | background-color | `#f0ede6` | `#1a1a2e` |
| osm-base | raster-saturation | `-0.4` | `-0.6` |
| osm-base | raster-contrast | `0.25` | `-0.1` |
| osm-base | raster-brightness-max | `0.9` | `0.35` |
| trails-track | line-color grade1/2 | `#FFD700` | `#FFE066` |
| trails-track | line-color grade3/4/5/default | `#FF4400` | `#FF6633` |
| trails-path-bridleway | line-color | `#cc0000` | `#ff4444` |
| poi-circles | circle-stroke-color | `#ffffff` | `#333333` |
| poi-labels | text-color | `#333333` | `#e0e0e0` |
| poi-labels | text-halo-color | `#ffffff` | `#1a1a2e` |
| poi-labels | text-halo-width | `1.5` | `2` |
Все остальные свойства (sources, glyphs, filters, zoom levels, line-width) — копировать из `style.json` без изменений.
- [ ] **1.2** Проверить валидность JSON
```bash
cat static/style-dark.json | python3 -m json.tool > /dev/null && echo "OK"
# Ожидаемый результат: OK
```
**Критерий готовности:** Файл `style-dark.json` существует, валидный JSON, содержит все слои из style.json с тёмной палитрой.
---
### Task 2: Исправить switchMapStyle() в app.js
**Файлы:**
- Изменить: `static/app.js` (строки 86-105)
**Шаги:**
- [ ] **2.1** Заменить функцию `switchMapStyle()` (строки 86-105):
**Было:**
```javascript
function switchMapStyle() {
const map = window._map;
if (!map) return;
const dark = isDarkTheme();
const basePath = window.location.pathname.replace(/\/[^/]*$/, '') || '';
const styleUrl = dark ? basePath + '/style.json' : basePath + '/style-light.json';
// Check if style-light.json exists - if not, keep current
fetch(styleUrl, { method: 'HEAD' }).then(r => {
if (r.ok) {
map.setStyle(styleUrl);
} else {
// No light style available, keep dark
if (!dark) {
console.log('Light map style not available, keeping dark');
}
}
}).catch(() => {
// Network error, don't switch
});
}
```
**Стало:**
```javascript
function switchMapStyle() {
const map = window._map;
if (!map) return;
const dark = isDarkTheme();
const basePath = window.location.pathname.replace(/\/[^/]*$/, '') || '';
const styleUrl = dark ? basePath + '/style-dark.json' : basePath + '/style.json';
fetch(styleUrl, { method: 'HEAD' }).then(r => {
if (r.ok) {
map.setStyle(styleUrl);
} else {
console.log('Map style not available:', styleUrl);
}
}).catch(() => {
// Network error, don't switch
});
}
```
Ключевое изменение: `dark → style-dark.json`, `light → style.json` (было инвертировано).
- [ ] **2.2** Проверить что `switchMapStyle()` вызывается в `applyTheme()` (строка 26) — уже есть, не трогать.
**Критерий готовности:** При `isDarkTheme() === true` загружается `style-dark.json`, при `false``style.json`.
---
### Task 3: Деплой и проверка
**Шаги:**
- [ ] **3.1** Загрузить файлы на сервер
```bash
# Через Node.js ssh2 (deploy_static.js) или напрямую:
scp static/style-dark.json slin@82.22.50.71:/home/slin/enduro-trails/prototype/static/
scp static/app.js slin@82.22.50.71:/home/slin/enduro-trails/prototype/static/
```
- [ ] **3.2** Docker cp в контейнер
```bash
ssh slin@82.22.50.71 << 'EOF'
docker cp /home/slin/enduro-trails/prototype/static/style-dark.json prototype-enduro-trails-1:/app/static/style-dark.json
docker cp /home/slin/enduro-trails/prototype/static/app.js prototype-enduro-trails-1:/app/static/app.js
EOF
```
⚠️ НЕ рестартовать контейнер! Просто cp — иначе придётся копировать ВСЕ файлы заново.
- [ ] **3.3** Проверить доступность стилей
```bash
curl -s -o /dev/null -w "%{http_code}" https://openclaw.mva154.duckdns.org/enduro/style.json
# Ожидаемый результат: 200
curl -s -o /dev/null -w "%{http_code}" https://openclaw.mva154.duckdns.org/enduro/style-dark.json
# Ожидаемый результат: 200
```
- [ ] **3.4** Проверить содержимое тёмного стиля
```bash
curl -s https://openclaw.mva154.duckdns.org/enduro/style-dark.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['name'], d['layers'][0]['paint'])"
# Ожидаемый результат: Enduro Trails Dark {'background-color': '#1a1a2e'}
```
**Критерий готовности:** Оба стиля доступны по URL, тёмный стиль содержит правильную палитру.
---
## Проверка (Acceptance)
| # | Проверка | Действие | Ожидаемый результат |
|---|----------|----------|---------------------|
| 1 | Светлая тема | Открыть сайт, выбрать ☀️ | Карта светлая (бежевый фон) |
| 2 | Тёмная тема | Переключить на 🌙 | Карта тёмная (тёмно-синий фон, приглушённый OSM) |
| 3 | Auto (день) | Режим auto днём | Карта светлая |
| 4 | Auto (ночь) | Режим auto ночью | Карта тёмная |
| 5 | Overlay сохраняется | Включить terrain → переключить тему | Terrain слой остаётся видимым |
| 6 | Маршрут сохраняется | Построить маршрут → переключить тему | Маршрут остаётся на карте |
| 7 | style-dark.json 200 | `curl` | HTTP 200 |
---
## Ограничения и контекст
- ⚠️ `docker cp` БЕЗ рестарта контейнера — рестарт перезапишет статику из образа
- ⚠️ SSH через Node.js ssh2 модуль (бинарный ssh в контейнере OpenClaw не работает — glibc mismatch). Альтернатива: `deploy_static.js`
- ⚠️ После `map.setStyle()` все кастомные слои (terrain, routes, markers) слетают — `onMapStyleLoad()` + `rebuildMapOverlays()` уже обрабатывают это через событие `style.load`
- 🚫 Не трогать `style.json` — это рабочий светлый стиль
- 🚫 Не менять логику SunCalc / applyAutoTheme — она работает корректно
---
## Деплой-чеклист
- [ ] `style-dark.json` создан и валиден
- [ ] `app.js` — логика `switchMapStyle` исправлена
- [ ] Файлы загружены на сервер (`/home/slin/enduro-trails/prototype/static/`)
- [ ] `docker cp` выполнен (без рестарта!)
- [ ] `style-dark.json` доступен по URL (HTTP 200)
- [ ] Переключение темы меняет стиль карты
- [ ] Overlays (terrain, routes) сохраняются при смене стиля
---
*Создано: 2026-05-12 | Автор ТЗ: Стрим | Исполнитель: Dev-агент*