Skip to content

Commit

Permalink
Use early returns
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric-Arellano committed Jul 3, 2024
1 parent 0b4da10 commit 5e7a348
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 99 deletions.
55 changes: 28 additions & 27 deletions src/js/about.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,39 @@
* Set up event listeners to open and close the about popup.
*/
const setUpAbout = () => {
const aboutElement: HTMLElement | null =
document.querySelector(".about-text-popup");
const aboutElement = document.querySelector(".about-text-popup");
const infoButton = document.querySelector(".header-about-icon-container");
if (infoButton && aboutElement) {
infoButton.addEventListener("click", () => {
aboutElement.style.display =
aboutElement.style.display !== "block" ? "block" : "none";
});
if (
!(aboutElement instanceof HTMLElement) ||
!(infoButton instanceof HTMLElement)
)
return;

// closes window on clicks outside the info popup
window.addEventListener("click", (event: MouseEvent) => {
const clickTarget = event?.target as Element;
if (
!infoButton.contains(clickTarget) &&
aboutElement.style.display === "block" &&
!aboutElement.contains(clickTarget)
) {
aboutElement.style.display = "none";
infoButton.classList.toggle("active");
}
});
infoButton.addEventListener("click", () => {
aboutElement.style.display =
aboutElement.style.display !== "block" ? "block" : "none";
});

// closes window on clicks outside the info popup
window.addEventListener("click", (event) => {
if (
event.target instanceof Element &&
!infoButton.contains(event.target) &&
aboutElement.style.display === "block" &&
!aboutElement.contains(event.target)
) {
aboutElement.style.display = "none";
infoButton.classList.toggle("active");
}
});

const aboutClose = document.querySelector(".about-close");
if (!(aboutClose instanceof HTMLElement)) return;
aboutClose.addEventListener("click", () => {
// Note that the close element will only render when the about text popup is rendered.
// So, it only ever makes sense for a click to close.
const aboutClose: HTMLAnchorElement | null =
document.querySelector(".about-close");
if (aboutClose) {
aboutClose.addEventListener("click", () => {
aboutElement.style.display = "none";
});
}
}
aboutElement.style.display = "none";
});
};

export default setUpAbout;
78 changes: 36 additions & 42 deletions src/js/setUpSite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,36 +232,32 @@ const setUpCitiesLayer = async (

// Set up map to update when city selection changes.
const cityToggleElement = document.getElementById("city-dropdown");
if (cityToggleElement instanceof HTMLSelectElement) {
cityToggleElement.addEventListener("change", async () => {
const cityId = cityToggleElement.value;
const { layer } = cities[cityId];
if (layer) {
snapToCity(map, layer);
}
});
if (!(cityToggleElement instanceof HTMLSelectElement)) return;
cityToggleElement.addEventListener("change", async () => {
const cityId = cityToggleElement.value;
const { layer } = cities[cityId];
if (layer) {
snapToCity(map, layer);
}
});

// Set up map to update when user clicks within a city's boundary
allBoundaries.addEventListener("click", (e) => {
const currentZoom = map.getZoom();
if (currentZoom > 7) {
const cityId = e.sourceTarget.feature.properties.id;
cityToggleElement.value = cityId;
const { layer } = cities[cityId];
if (layer) {
snapToCity(map, layer);
}
}
});
// Set up map to update when user clicks within a city's boundary
allBoundaries.addEventListener("click", (e) => {
const currentZoom = map.getZoom();
if (currentZoom <= 7) return;
const cityId = e.sourceTarget.feature.properties.id;
cityToggleElement.value = cityId;
const { layer } = cities[cityId];
if (layer) {
snapToCity(map, layer);
}
});

// Load initial city.
const cityId = cityToggleElement.value;
setUpAutoScorecard(map, cities, parkingLayer);
snapToCity(map, cities[cityId].layer);
setScorecard(cityId, cities[cityId]);
} else {
throw new Error("#city-dropdown is not a select element");
}
// Load initial city.
const cityId = cityToggleElement.value;
setUpAutoScorecard(map, cities, parkingLayer);
snapToCity(map, cities[cityId].layer);
setScorecard(cityId, cities[cityId]);
};

/**
Expand All @@ -277,22 +273,20 @@ const setUpParkingLotsLayer = async (
},
}).addTo(map);

if (window.location.href.indexOf("#lots-toggle") === -1) return parkingLayer;

// If `#lots-toggle` is in the URL, we show buttons to toggle parking lots.
if (window.location.href.indexOf("#lots-toggle") !== -1) {
const toggle: HTMLAnchorElement | null =
document.querySelector("#lots-toggle");
if (toggle) {
toggle.style.display = "block";
}
document
.querySelector("#lots-toggle-off")
?.addEventListener("click", () => {
parkingLayer.removeFrom(map);
});
document.querySelector("#lots-toggle-on")?.addEventListener("click", () => {
parkingLayer.addTo(map);
});
const toggle: HTMLAnchorElement | null =
document.querySelector("#lots-toggle");
if (toggle) {
toggle.style.display = "block";
}
document.querySelector("#lots-toggle-off")?.addEventListener("click", () => {
parkingLayer.removeFrom(map);
});
document.querySelector("#lots-toggle-on")?.addEventListener("click", () => {
parkingLayer.addTo(map);
});
return parkingLayer;
};

Expand Down
52 changes: 22 additions & 30 deletions src/js/share.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,33 @@ const copyToClipboard = async (value: string): Promise<void> => {
};

const switchIcons = (shareIcon: HTMLAnchorElement): void => {
const linkIcon: HTMLAnchorElement | null = shareIcon.querySelector(
"svg.share-link-icon"
);
const checkIcon: HTMLAnchorElement | null = shareIcon.querySelector(
"svg.share-check-icon"
);
if (linkIcon && checkIcon) {
linkIcon.style.display = "none";
checkIcon.style.display = "inline-block";
setTimeout(() => {
linkIcon.style.display = "inline-block";
checkIcon.style.display = "none";
}, 1000);
}
const linkIcon = shareIcon.querySelector("svg.share-link-icon");
const checkIcon = shareIcon.querySelector("svg.share-check-icon");
if (!(linkIcon instanceof SVGElement) || !(checkIcon instanceof SVGElement))
return;

linkIcon.style.display = "none";
checkIcon.style.display = "inline-block";
setTimeout(() => {
linkIcon.style.display = "inline-block";
checkIcon.style.display = "none";
}, 1000);
};

const setUpShareUrlClickListener = (cityId: CityId): void => {
// We put the event listener on `map` because it is never erased, unlike the copy button
// being recreated every time the score card changes. This is called "event delegation".
const mapElement: HTMLElement | null = document.querySelector("#map");
if (mapElement) {
mapElement.addEventListener("click", async (event: MouseEvent | null) => {
const copyButton = event?.target as Element;
if (copyButton) {
const targetElement: HTMLAnchorElement | null = copyButton.closest(
"div.url-copy-button > a"
);
if (targetElement) {
const shareUrl = determineShareUrl(window.location.href, cityId);
await copyToClipboard(shareUrl);
switchIcons(targetElement);
}
}
});
}
const mapElement = document.querySelector("#map");
if (!(mapElement instanceof Element)) return;
mapElement.addEventListener("click", async (event) => {
const copyButton = event.target;
if (!(copyButton instanceof Element)) return;
const targetElement = copyButton.closest("div.url-copy-button > a");
if (!(targetElement instanceof HTMLAnchorElement)) return;
const shareUrl = determineShareUrl(window.location.href, cityId);
await copyToClipboard(shareUrl);
switchIcons(targetElement);
});
};

export default setUpShareUrlClickListener;

0 comments on commit 5e7a348

Please sign in to comment.