Skip to content

Commit 7b5eedb

Browse files
author
OpenCode
committed
Merge remote-tracking branch 'origin/main' into chore/reconcile-main-0.18.0-to-staging
2 parents f738251 + bf9a4c0 commit 7b5eedb

3 files changed

Lines changed: 108 additions & 0 deletions

File tree

src/components/MapView.tsx

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,95 @@ export function MapView({
898898
startUserLocation();
899899
}, [startUserLocation, stopUserLocation]);
900900

901+
const stopUserLocation = useCallback(() => {
902+
if (userLocationWatchIdRef.current !== null && navigator.geolocation) {
903+
navigator.geolocation.clearWatch(userLocationWatchIdRef.current);
904+
}
905+
userLocationWatchIdRef.current = null;
906+
isUserLocationActiveRef.current = false;
907+
isUserLocationFollowingRef.current = false;
908+
setIsUserLocationActive(false);
909+
setUserLocationFix(null);
910+
}, []);
911+
912+
useEffect(() => () => stopUserLocation(), [stopUserLocation]);
913+
914+
const publishLocationNotice = useCallback(
915+
(message: string, tone: "info" | "warning" | "error" = "error") => {
916+
onPublishNotice?.({
917+
id: USER_LOCATION_NOTICE_ID,
918+
message,
919+
tone,
920+
persistent: false,
921+
});
922+
},
923+
[onPublishNotice],
924+
);
925+
926+
const startUserLocation = useCallback(() => {
927+
if (!navigator.geolocation) {
928+
publishLocationNotice("Your browser does not support location services.");
929+
return;
930+
}
931+
isUserLocationActiveRef.current = true;
932+
isUserLocationFollowingRef.current = true;
933+
setIsUserLocationActive(true);
934+
setUserLocationFix(null);
935+
try {
936+
userLocationWatchIdRef.current = navigator.geolocation.watchPosition(
937+
(position) => {
938+
const nextFix: UserLocationFix = {
939+
lat: position.coords.latitude,
940+
lon: position.coords.longitude,
941+
accuracyM: Number.isFinite(position.coords.accuracy) ? position.coords.accuracy : null,
942+
};
943+
setUserLocationFix(nextFix);
944+
if (isUserLocationFollowingRef.current) {
945+
setInteractionViewState(null);
946+
const didAnimate = animateMapToCenter(mapRef, {
947+
center: { lat: nextFix.lat, lon: nextFix.lon },
948+
zoom: USER_LOCATION_ZOOM,
949+
padding: resolveMapCameraPadding(fitChromePadding, fitBottomInset),
950+
});
951+
if (!didAnimate) {
952+
updateMapViewport({
953+
center: { lat: nextFix.lat, lon: nextFix.lon },
954+
zoom: USER_LOCATION_ZOOM,
955+
});
956+
}
957+
}
958+
},
959+
(error) => {
960+
console.error("[user-location] geolocation watch failed", error);
961+
publishLocationNotice(userLocationErrorMessage(error));
962+
stopUserLocation();
963+
},
964+
USER_LOCATION_WATCH_OPTIONS,
965+
);
966+
} catch (error) {
967+
console.error("[user-location] geolocation watch failed", error);
968+
publishLocationNotice("Could not get your location.");
969+
stopUserLocation();
970+
}
971+
}, [
972+
fitBottomInset,
973+
fitChromePadding.bottom,
974+
fitChromePadding.left,
975+
fitChromePadding.right,
976+
fitChromePadding.top,
977+
publishLocationNotice,
978+
stopUserLocation,
979+
updateMapViewport,
980+
]);
981+
982+
const toggleUserLocation = useCallback(() => {
983+
if (isUserLocationActiveRef.current) {
984+
stopUserLocation();
985+
return;
986+
}
987+
startUserLocation();
988+
}, [startUserLocation, stopUserLocation]);
989+
901990
useEffect(() => {
902991
const handleViewportChange = () => {
903992
mapRef.current?.resize();

src/components/Sidebar.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,16 @@ import type { Site } from "../types/radio";
3838
import { siGithub } from "simple-icons";
3939
import { InfoTip } from "./InfoTip";
4040
import { ActionButton } from "./ActionButton";
41+
import {
42+
AccessSettingsEditor,
43+
type AccessCollaborator,
44+
type AccessRole,
45+
type AccessVisibility,
46+
} from "./AccessSettingsEditor";
4147
import { AvatarBadge } from "./AvatarBadge";
4248
import { InlineCloseIconButton } from "./InlineCloseIconButton";
4349
import { ModalOverlay } from "./ModalOverlay";
50+
import { SiteBeamVisualizerPopover } from "./SiteBeamVisualizer";
4451
import SimulationLibraryPanel from "./SimulationLibraryPanel";
4552
import { Badge } from "./ui/Badge";
4653
import { PanelToolbar } from "./ui/PanelToolbar";
@@ -82,6 +89,7 @@ const ALL_VISIBILITY_FILTERS = VISIBILITY_FILTER_OPTIONS.map((option) => option.
8289
const ALL_SITE_SOURCE_FILTERS = SITE_SOURCE_FILTER_OPTIONS.map((option) => option.key);
8390

8491
type SiteFilterGroupKey = "role" | "visibility" | "source";
92+
type BeamPreviewFieldKey = "add" | "edit";
8593

8694
type SidebarProps = {
8795
onOpenHelp?: () => void;
@@ -1336,6 +1344,12 @@ export function Sidebar({
13361344
</div>
13371345
</ModalOverlay>
13381346
) : null}
1347+
<SiteBeamVisualizerPopover
1348+
onClose={() => setActiveBeamPreviewField(null)}
1349+
open={Boolean(activeBeamPreviewField && activeBeamPreviewTriggerRef?.current)}
1350+
triggerRef={activeBeamPreviewTriggerRef}
1351+
values={activeBeamPreviewValues}
1352+
/>
13391353
{deleteConfirm ? (
13401354
<ModalOverlay aria-label="Confirm Delete" onClose={() => setDeleteConfirm(null)} tier="raised">
13411355
<div className="library-manager-card user-profile-popup">

src/index.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,11 @@ button {
574574
width: auto;
575575
}
576576

577+
.gain-mode-toggle input {
578+
justify-self: end;
579+
width: auto;
580+
}
581+
577582
.field-grid textarea {
578583
border: 1px solid var(--border);
579584
background: var(--surface);

0 commit comments

Comments
 (0)