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:
parent
025a05063f
commit
1ff240802b
|
|
@ -59,12 +59,12 @@ export default function App() {
|
|||
setTheme(saved);
|
||||
document.body.setAttribute("data-theme", saved);
|
||||
} else {
|
||||
setTheme("light");
|
||||
document.body.setAttribute("data-theme", "light");
|
||||
setTheme("blue");
|
||||
document.body.setAttribute("data-theme", "blue");
|
||||
}
|
||||
} catch (e) {
|
||||
setTheme("light");
|
||||
document.body.setAttribute("data-theme", "light");
|
||||
setTheme("blue");
|
||||
document.body.setAttribute("data-theme", "blue");
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@ import "../../styles/mapMarkers.css";
|
|||
import "../../styles/posts.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 { WeatherModal } from "../Weather";
|
||||
import {
|
||||
FILTER_MAIN_CATEGORIES,
|
||||
FILTER_CATEGORY_MAP,
|
||||
|
|
@ -147,9 +146,11 @@ export default function MapView({
|
|||
const WEATHER_VIEW_KEY = "sociowire:weatherView";
|
||||
const [weatherViewEnabled, setWeatherViewEnabled] = useState(() => {
|
||||
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 {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -196,11 +197,6 @@ export default function MapView({
|
|||
const [showLiveBroadcast, setShowLiveBroadcast] = useState(false);
|
||||
const [activeLivePost, setActiveLivePost] = 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 queryPostRef = useRef(false);
|
||||
const overlayTimerRef = useRef(null);
|
||||
|
|
@ -1210,82 +1206,6 @@ export default function MapView({
|
|||
return () => map.off("movestart", handleMove);
|
||||
}, [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) => {
|
||||
console.log('[MapView] Visiting island from profile:', island.username);
|
||||
setSelectedProfile(null); // Close profile modal
|
||||
|
|
@ -1801,7 +1721,7 @@ export default function MapView({
|
|||
<div className="map-page">
|
||||
<div className="map-stage" ref={stageRef}>
|
||||
<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>}
|
||||
{debugEnabled && (
|
||||
<>
|
||||
|
|
@ -1885,60 +1805,9 @@ export default function MapView({
|
|||
>
|
||||
<i className="fa-solid fa-umbrella-beach"></i>
|
||||
</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>
|
||||
{/* 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 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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ body[data-theme="blue"] .post-pin--compact .post-pin-bubble {
|
|||
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"] .chat-panel,
|
||||
|
|
|
|||
Loading…
Reference in New Issue