feat: Day/night less dark, enabled by default; remove weather widget

- Day/night terminator opacity reduced from 0.3 to 0.15
- Day/night enabled by default for new users
- Removed weather button, widget, and modal from map
- Kept blue theme as default

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
SocioWire 2026-01-10 23:46:50 +00:00
parent 025a05063f
commit 1ff240802b
3 changed files with 11 additions and 151 deletions

View File

@ -59,12 +59,12 @@ export default function App() {
setTheme(saved); setTheme(saved);
document.body.setAttribute("data-theme", saved); document.body.setAttribute("data-theme", saved);
} else { } else {
setTheme("light"); setTheme("blue");
document.body.setAttribute("data-theme", "light"); document.body.setAttribute("data-theme", "blue");
} }
} catch (e) { } catch (e) {
setTheme("light"); setTheme("blue");
document.body.setAttribute("data-theme", "light"); document.body.setAttribute("data-theme", "blue");
} }
}, []); }, []);

View File

@ -5,9 +5,8 @@ import "../../styles/mapMarkers.css";
import "../../styles/posts.css"; import "../../styles/posts.css";
import "../../styles/filters.css"; import "../../styles/filters.css";
import { createPost, fetchPostPreview, resolveAssetRef, fetchWeatherPosts } from "../../api/client"; import { createPost, fetchPostPreview, resolveAssetRef } from "../../api/client";
import { LiveKitBroadcast, LiveKitViewerModal } from "../Live"; import { LiveKitBroadcast, LiveKitViewerModal } from "../Live";
import { WeatherModal } from "../Weather";
import { import {
FILTER_MAIN_CATEGORIES, FILTER_MAIN_CATEGORIES,
FILTER_CATEGORY_MAP, FILTER_CATEGORY_MAP,
@ -147,9 +146,11 @@ export default function MapView({
const WEATHER_VIEW_KEY = "sociowire:weatherView"; const WEATHER_VIEW_KEY = "sociowire:weatherView";
const [weatherViewEnabled, setWeatherViewEnabled] = useState(() => { const [weatherViewEnabled, setWeatherViewEnabled] = useState(() => {
try { try {
return localStorage.getItem(WEATHER_VIEW_KEY) === "true"; const saved = localStorage.getItem(WEATHER_VIEW_KEY);
// Default to true if not set
return saved === null ? true : saved === "true";
} catch { } catch {
return false; return true;
} }
}); });
@ -196,11 +197,6 @@ export default function MapView({
const [showLiveBroadcast, setShowLiveBroadcast] = useState(false); const [showLiveBroadcast, setShowLiveBroadcast] = useState(false);
const [activeLivePost, setActiveLivePost] = useState(null); const [activeLivePost, setActiveLivePost] = useState(null);
const [liveCoords, setLiveCoords] = useState(null); const [liveCoords, setLiveCoords] = useState(null);
// Weather modal state
const [activeWeatherPost, setActiveWeatherPost] = useState(null);
// Weather cities widget (top left under search)
const [weatherCities, setWeatherCities] = useState([]);
const [nearestWeather, setNearestWeather] = useState(null);
const openedPostRef = useRef(null); const openedPostRef = useRef(null);
const queryPostRef = useRef(false); const queryPostRef = useRef(false);
const overlayTimerRef = useRef(null); const overlayTimerRef = useRef(null);
@ -1210,82 +1206,6 @@ export default function MapView({
return () => map.off("movestart", handleMove); return () => map.off("movestart", handleMove);
}, [mapRef, searchQuery]); }, [mapRef, searchQuery]);
// Fetch weather cities on mount
useEffect(() => {
const loadWeatherCities = async () => {
try {
const posts = await fetchWeatherPosts();
if (Array.isArray(posts) && posts.length > 0) {
// Parse weather data from posts
const cities = posts.map(p => {
const title = p.title || '';
const tempMatch = title.match(/:\s*(-?\d+)°/);
const cityMatch = title.match(/^[^\w]*([A-Za-zÀ-ÿ\s]+):/);
const temp = tempMatch ? parseInt(tempMatch[1], 10) : null;
const city = cityMatch ? cityMatch[1].trim() : '';
// Detect weather icon from emoji in title
let icon = '🌡️';
if (title.includes('☀️')) icon = '☀️';
else if (title.includes('🌙')) icon = '🌙';
else if (title.includes('⛅')) icon = '⛅';
else if (title.includes('☁️')) icon = '☁️';
else if (title.includes('🌫️')) icon = '🌫️';
else if (title.includes('🌧️')) icon = '🌧️';
else if (title.includes('❄️')) icon = '❄️';
else if (title.includes('🌦️')) icon = '🌦️';
else if (title.includes('🌨️')) icon = '🌨️';
else if (title.includes('⛈️')) icon = '⛈️';
return { ...p, city, temp, icon };
}).filter(c => c.city && c.temp !== null);
setWeatherCities(cities);
}
} catch (err) {
console.warn('[Weather] Failed to load cities:', err);
}
};
loadWeatherCities();
// Refresh every 10 minutes
const interval = setInterval(loadWeatherCities, 10 * 60 * 1000);
return () => clearInterval(interval);
}, []);
// Find nearest weather city when map moves
useEffect(() => {
const map = mapRef.current;
if (!map || weatherCities.length === 0) return;
const updateNearest = () => {
try {
const center = map.getCenter();
if (!center) return;
let nearest = null;
let minDist = Infinity;
for (const w of weatherCities) {
if (w.lat == null || w.lon == null) continue;
const dist = Math.sqrt(
Math.pow(center.lat - w.lat, 2) + Math.pow(center.lng - w.lon, 2)
);
if (dist < minDist) {
minDist = dist;
nearest = w;
}
}
if (nearest) setNearestWeather(nearest);
} catch {}
};
updateNearest();
map.on("idle", updateNearest);
return () => map.off("idle", updateNearest);
}, [mapRef, weatherCities]);
const handleProfileVisitIsland = (island) => { const handleProfileVisitIsland = (island) => {
console.log('[MapView] Visiting island from profile:', island.username); console.log('[MapView] Visiting island from profile:', island.username);
setSelectedProfile(null); // Close profile modal setSelectedProfile(null); // Close profile modal
@ -1801,7 +1721,7 @@ export default function MapView({
<div className="map-page"> <div className="map-page">
<div className="map-stage" ref={stageRef}> <div className="map-stage" ref={stageRef}>
<div ref={containerRef} className="map-container" /> <div ref={containerRef} className="map-container" />
<DayNightTerminator map={mapRef.current} enabled={weatherViewEnabled} opacity={0.3} /> <DayNightTerminator map={mapRef.current} enabled={weatherViewEnabled} opacity={0.15} />
{status && <div className="map-status">{status}</div>} {status && <div className="map-status">{status}</div>}
{debugEnabled && ( {debugEnabled && (
<> <>
@ -1885,60 +1805,9 @@ export default function MapView({
> >
<i className="fa-solid fa-umbrella-beach"></i> <i className="fa-solid fa-umbrella-beach"></i>
</button> </button>
<button
type="button"
className={"sw-search__iconBtn" + (weatherViewEnabled ? " is-active" : "")}
title="Météo & Ensoleillement"
onClick={() => setWeatherViewEnabled((prev) => !prev)}
>
<i className="fa-solid fa-cloud-sun"></i>
</button>
</div> </div>
</div> </div>
</div> </div>
{/* Weather widget - single nearest city - BELOW search bar */}
{nearestWeather && (() => {
const w = nearestWeather;
const isSunny = w.icon === '☀️' || w.icon === '⛅';
const isNight = w.icon === '🌙';
const isRainy = w.icon === '🌧️' || w.icon === '🌦️' || w.icon === '⛈️';
const isSnow = w.icon === '❄️' || w.icon === '🌨️';
const bg = isNight
? 'linear-gradient(135deg, rgba(30, 41, 59, 0.9), rgba(15, 23, 42, 0.9))'
: isSunny
? 'linear-gradient(135deg, rgba(56, 189, 248, 0.85), rgba(14, 165, 233, 0.85))'
: isRainy
? 'linear-gradient(135deg, rgba(71, 85, 105, 0.9), rgba(51, 65, 85, 0.9))'
: isSnow
? 'linear-gradient(135deg, rgba(148, 163, 184, 0.9), rgba(203, 213, 225, 0.9))'
: 'linear-gradient(135deg, rgba(100, 116, 139, 0.85), rgba(71, 85, 105, 0.85))';
return (
<div
onClick={() => setActiveWeatherPost(w)}
style={{
display: 'inline-flex',
alignItems: 'center',
gap: '5px',
marginTop: '8px',
padding: '5px 12px',
borderRadius: '16px',
background: bg,
border: '1px solid rgba(255,255,255,0.25)',
color: isSnow ? '#1e293b' : '#fff',
fontSize: '13px',
fontWeight: '600',
cursor: 'pointer',
backdropFilter: 'blur(8px)',
boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
}}
>
<span style={{ fontSize: '16px' }}>{w.icon}</span>
<span>{w.city}:</span>
<span style={{ fontWeight: '700' }}>{w.temp}°</span>
</div>
);
})()}
</div> </div>
<div className="map-overlay map-overlay-left"> <div className="map-overlay map-overlay-left">
@ -2235,15 +2104,6 @@ export default function MapView({
/> />
)} )}
{activeWeatherPost && (
<WeatherModal
postId={activeWeatherPost.id || activeWeatherPost.ID}
city={activeWeatherPost.city}
lat={activeWeatherPost.lat}
lon={activeWeatherPost.lon}
onClose={() => setActiveWeatherPost(null)}
/>
)}
</div> </div>
); );
} }

View File

@ -9,7 +9,7 @@ body[data-theme="blue"] .post-pin--compact .post-pin-bubble {
border-color: rgba(96, 165, 250, 0.95); border-color: rgba(96, 165, 250, 0.95);
} }
body[data-theme="light"] { background:#f8fafc; color:#111827; } body[data-theme="light"] { background:#e5e7eb; color:#111827; }
body[data-theme="light"] .sociowall-panel, body[data-theme="light"] .sociowall-panel,
body[data-theme="light"] .chat-panel, body[data-theme="light"] .chat-panel,