1.8.6
Integrate fonts Add office profile Fix onload pulldown selections
This commit is contained in:
@@ -26,7 +26,7 @@ import { useState, useEffect, useRef, useCallback } from '../../vendor/preact-ho
|
||||
import {
|
||||
FREE_DAYS, FILTER_PROFILES, OUTDOORS_VARIANTS,
|
||||
profileButtonOrder, variantIcons,
|
||||
activityVariantKeys, placeVariantKeys,
|
||||
activityVariantKeys, placeVariantKeys, workVariantKeys,
|
||||
} from '../config.js';
|
||||
import { utciCategory } from '../utils.js';
|
||||
import { buildHourlyRows } from '../compute.js';
|
||||
@@ -167,8 +167,20 @@ export function useAppState() {
|
||||
|
||||
// ── 5. SKIN, VEHICLE, INDOOR, POLLEN ─────────────────────────────────
|
||||
const [skinType, setSkinType] = useState('II');
|
||||
const [vehicleType, setVehicleType] = useState('car');
|
||||
const [vehicleVent, setVehicleVent] = useState(false);
|
||||
const [vehicleType, setVehicleType] = useState(() => {
|
||||
try { return localStorage.getItem('sunscope_vehicle_type') || 'car'; } catch (e) { return 'car'; }
|
||||
});
|
||||
const setVehicleTypeAndSave = (v) => {
|
||||
try { localStorage.setItem('sunscope_vehicle_type', v); } catch (e) { /* ignore */ }
|
||||
setVehicleType(v);
|
||||
};
|
||||
const [vehicleVent, setVehicleVent] = useState(() => {
|
||||
try { return localStorage.getItem('sunscope_vehicle_vent') === '1'; } catch (e) { return false; }
|
||||
});
|
||||
const setVehicleVentAndSave = (v) => {
|
||||
try { localStorage.setItem('sunscope_vehicle_vent', v ? '1' : '0'); } catch (e) { /* ignore */ }
|
||||
setVehicleVent(v);
|
||||
};
|
||||
|
||||
const [outdoorsVariant, setOutdoorsVariant] = useState(() => {
|
||||
try { return localStorage.getItem('sunscope_outdoors_variant') || 'urban'; } catch (e) { return 'urban'; }
|
||||
@@ -190,15 +202,40 @@ export function useAppState() {
|
||||
? (OUTDOORS_VARIANTS[outdoorsVariant]?.cols ?? FILTER_PROFILES.outdoors.cols)
|
||||
: (FILTER_PROFILES[activeProfile]?.cols ?? FILTER_PROFILES.basic.cols);
|
||||
|
||||
const [buildingType, setBuildingType] = useState('brick');
|
||||
const [indoorManaged, setIndoorManaged] = useState(false);
|
||||
const [indoorMode, setIndoorMode] = useState(() => {
|
||||
const [buildingType, setBuildingType] = useState(() => {
|
||||
try {
|
||||
const saved = localStorage.getItem('sunscope_profile') || 'basic';
|
||||
const cols = FILTER_PROFILES[saved]?.cols ?? FILTER_PROFILES.basic.cols;
|
||||
const saved = localStorage.getItem('sunscope_building_type');
|
||||
if (saved) return saved;
|
||||
// Fall back to office if the saved variant is office and no explicit building saved
|
||||
const savedVariant = localStorage.getItem('sunscope_outdoors_variant') || '';
|
||||
if (savedVariant === 'office') return 'office';
|
||||
} catch (e) { /* ignore */ }
|
||||
return 'brick';
|
||||
});
|
||||
const setBuildingTypeAndSave = (v) => {
|
||||
try { localStorage.setItem('sunscope_building_type', v); } catch (e) { /* ignore */ }
|
||||
setBuildingType(v);
|
||||
};
|
||||
const [indoorManaged, setIndoorManaged] = useState(() => {
|
||||
try { return localStorage.getItem('sunscope_indoor_managed') === '1'; } catch (e) { return false; }
|
||||
});
|
||||
const setIndoorManagedAndSave = (v) => {
|
||||
try { localStorage.setItem('sunscope_indoor_managed', v ? '1' : '0'); } catch (e) { /* ignore */ }
|
||||
setIndoorManaged(v);
|
||||
};
|
||||
const [indoorMode, setIndoorMode] = useState(() => {
|
||||
try {
|
||||
const saved = localStorage.getItem('sunscope_indoor_mode');
|
||||
if (saved) return saved;
|
||||
const profile = localStorage.getItem('sunscope_profile') || 'basic';
|
||||
const cols = FILTER_PROFILES[profile]?.cols ?? FILTER_PROFILES.basic.cols;
|
||||
return (cols['indoorT'] || cols['managedT']) ? 'on' : 'off';
|
||||
} catch (e) { return 'off'; }
|
||||
});
|
||||
const setIndoorModeAndSave = (v) => {
|
||||
try { localStorage.setItem('sunscope_indoor_mode', v); } catch (e) { /* ignore */ }
|
||||
setIndoorMode(v);
|
||||
};
|
||||
|
||||
const [pollenType, setPollenType] = useState(() => {
|
||||
try { return localStorage.getItem('sunscope_pollen_type') || 'all_pollen'; } catch (e) { return 'all_pollen'; }
|
||||
@@ -233,19 +270,13 @@ export function useAppState() {
|
||||
const searchTimeout = useRef(null);
|
||||
|
||||
// Derived selectors used by profile controls
|
||||
const activityOptions = [
|
||||
{
|
||||
value: 'farming',
|
||||
label: `${FILTER_PROFILES.farming.icon} ${FILTER_PROFILES.farming.label}`,
|
||||
},
|
||||
...activityVariantKeys.map((k) => {
|
||||
const v = OUTDOORS_VARIANTS[k];
|
||||
return {
|
||||
value: k,
|
||||
label: `${variantIcons[k]} ${v.name}${v.proOnly && !isPro ? ' 🔒' : ''}`,
|
||||
};
|
||||
}),
|
||||
];
|
||||
const activityOptions = activityVariantKeys.map((k) => {
|
||||
const v = OUTDOORS_VARIANTS[k];
|
||||
return {
|
||||
value: k,
|
||||
label: `${variantIcons[k]} ${v.name}${v.proOnly && !isPro ? ' 🔒' : ''}`,
|
||||
};
|
||||
});
|
||||
const placeOptions = placeVariantKeys.map((k) => {
|
||||
const v = OUTDOORS_VARIANTS[k];
|
||||
return {
|
||||
@@ -253,17 +284,31 @@ export function useAppState() {
|
||||
label: `${variantIcons[k]} ${v.name}${v.proOnly && !isPro ? ' 🔒' : ''}`,
|
||||
};
|
||||
});
|
||||
const workOptions = workVariantKeys.map((k) => {
|
||||
const v = k === 'farming'
|
||||
? { name: FILTER_PROFILES.farming.label, proOnly: false }
|
||||
: OUTDOORS_VARIANTS[k];
|
||||
const icon = k === 'farming' ? FILTER_PROFILES.farming.icon : variantIcons[k];
|
||||
return {
|
||||
value: k,
|
||||
label: `${icon} ${v.name}${v.proOnly && !isPro ? ' 🔒' : ''}`,
|
||||
};
|
||||
});
|
||||
|
||||
const activityValue = activeProfile === 'farming'
|
||||
? 'farming'
|
||||
: activeProfile === 'outdoors' && activityVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const activityValue = activeProfile === 'outdoors' && activityVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const activityLabel = activityOptions.find((o) => o.value === activityValue)?.label;
|
||||
const placeValue = activeProfile === 'outdoors' && placeVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const placeLabel = placeOptions.find((o) => o.value === placeValue)?.label;
|
||||
const workValue = activeProfile === 'farming'
|
||||
? 'farming'
|
||||
: activeProfile === 'outdoors' && workVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const workLabel = workOptions.find((o) => o.value === workValue)?.label;
|
||||
|
||||
// ── 6. TABLE REFS ────────────────────────────────────────────────────
|
||||
const headStickyRef = useRef(null);
|
||||
@@ -439,17 +484,18 @@ export function useAppState() {
|
||||
activeProfile, setActiveProfile,
|
||||
activateProfile, activeCols,
|
||||
visibleCols, setVisibleCols, toggleCol,
|
||||
activityOptions, placeOptions,
|
||||
activityOptions, placeOptions, workOptions,
|
||||
activityValue, activityLabel,
|
||||
placeValue, placeLabel,
|
||||
workValue, workLabel,
|
||||
// skin, vehicle, indoor, pollen
|
||||
skinType, setSkinType,
|
||||
vehicleType, setVehicleType,
|
||||
vehicleVent, setVehicleVent,
|
||||
vehicleType, setVehicleType: setVehicleTypeAndSave,
|
||||
vehicleVent, setVehicleVent: setVehicleVentAndSave,
|
||||
outdoorsVariant, setOutdoorsVariantAndSave,
|
||||
buildingType, setBuildingType,
|
||||
indoorManaged, setIndoorManaged,
|
||||
indoorMode, setIndoorMode,
|
||||
buildingType, setBuildingType: setBuildingTypeAndSave,
|
||||
indoorManaged, setIndoorManaged: setIndoorManagedAndSave,
|
||||
indoorMode, setIndoorMode: setIndoorModeAndSave,
|
||||
pollenType, setPollenTypeAndSave,
|
||||
showDecimals, toggleShowDecimals,
|
||||
showUnits, toggleShowUnits,
|
||||
|
||||
Reference in New Issue
Block a user