feat: multiple map tile styles switchable in Settings > Interface

New src/mapStyles.ts defines five styles from bincio_planner's sources:
- Liberty (OpenFreeMap vector, default)
- CyclOSM (cycling infrastructure raster)
- Topo (OpenTopoMap elevation raster)
- Satellite (Esri World Imagery raster)
- OSM (standard raster fallback)

Raster sources are wrapped in a StyleSpecification so MapLibre handles
them natively. Setting persisted via ThemeContext (AsyncStorage key
mapTileStyle). RecordingScreen and ActivityDetailScreen both read from
context so the style updates everywhere simultaneously.

MAP_STRATEGY.md added (untracked) with full map roadmap.
This commit is contained in:
Davide Scaini
2026-06-04 00:52:58 +02:00
parent 7db54712fa
commit 8cc2b07b1f
6 changed files with 110 additions and 10 deletions
+21 -1
View File
@@ -7,6 +7,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
import { login, logout, loadAuthState } from '../services/auth';
import { colors, PALETTES, type PaletteKey, type FontSizeKey } from '../theme';
import { useTheme, type MapOrientation } from '../ThemeContext';
import { MAP_STYLES, MAP_TILE_STYLE_ORDER } from '../mapStyles';
type Tab = 'ui' | 'app' | 'sync';
@@ -41,7 +42,7 @@ export function SettingsScreen() {
// ─── UI tab ─────────────────────────────────────────────────────────────────
function UITab() {
const { accent, palette, setPalette, fontSize, setFontSize, boldLabels, setBoldLabels } = useTheme();
const { accent, palette, setPalette, fontSize, setFontSize, boldLabels, setBoldLabels, mapTileStyle, setMapTileStyle } = useTheme();
const fontSizes: FontSizeKey[] = ['small', 'medium', 'large'];
const palettes = Object.entries(PALETTES) as [PaletteKey, typeof PALETTES[PaletteKey]][];
@@ -77,6 +78,25 @@ function UITab() {
))}
</View>
<Text style={styles.sectionTitle}>Map style</Text>
{MAP_TILE_STYLE_ORDER.map((key) => {
const def = MAP_STYLES[key];
const active = mapTileStyle === key;
return (
<TouchableOpacity
key={key}
style={[styles.row, active && { borderColor: accent, backgroundColor: PALETTES[palette].accentDim }]}
onPress={() => setMapTileStyle(key)}
>
<View>
<Text style={[styles.rowLabel, active && { color: accent }]}>{def.label}</Text>
<Text style={styles.rowSub}>{def.description}</Text>
</View>
{active && <Text style={{ color: accent, fontSize: 16 }}></Text>}
</TouchableOpacity>
);
})}
<Text style={styles.sectionTitle}>Stat labels</Text>
<View style={styles.row}>
<Text style={styles.rowLabel}>Bold labels</Text>