Lint
This commit is contained in:
parent
4a0f00f2a4
commit
18ace123dc
13 changed files with 59 additions and 33 deletions
|
|
@ -12,13 +12,7 @@ import {
|
||||||
} from './lib/seoRoutes';
|
} from './lib/seoRoutes';
|
||||||
import Header, { type Page } from './components/ui/Header';
|
import Header, { type Page } from './components/ui/Header';
|
||||||
import type { FeatureMeta, FeatureGroup, POICategoriesResponse, POICategoryGroup } from './types';
|
import type { FeatureMeta, FeatureGroup, POICategoriesResponse, POICategoryGroup } from './types';
|
||||||
import {
|
import { fetchWithRetry, apiUrl, logNonAbortError, readDemoChoice, setDemoCenter } from './lib/api';
|
||||||
fetchWithRetry,
|
|
||||||
apiUrl,
|
|
||||||
logNonAbortError,
|
|
||||||
readDemoChoice,
|
|
||||||
setDemoCenter,
|
|
||||||
} from './lib/api';
|
|
||||||
import { trackEvent } from './lib/analytics';
|
import { trackEvent } from './lib/analytics';
|
||||||
import { parseUrlState } from './lib/url-state';
|
import { parseUrlState } from './lib/url-state';
|
||||||
import pb from './lib/pocketbase';
|
import pb from './lib/pocketbase';
|
||||||
|
|
@ -226,8 +220,7 @@ export default function App() {
|
||||||
const licensedAtMount = useMemo(
|
const licensedAtMount = useMemo(
|
||||||
() =>
|
() =>
|
||||||
pb.authStore.isValid &&
|
pb.authStore.isValid &&
|
||||||
(pb.authStore.record?.subscription === 'licensed' ||
|
(pb.authStore.record?.subscription === 'licensed' || pb.authStore.record?.is_admin === true),
|
||||||
pb.authStore.record?.is_admin === true),
|
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const initialDemoChoice = useMemo(() => {
|
const initialDemoChoice = useMemo(() => {
|
||||||
|
|
@ -255,10 +248,7 @@ export default function App() {
|
||||||
);
|
);
|
||||||
const activePageRef = useRef<Page>('home');
|
const activePageRef = useRef<Page>('home');
|
||||||
const initialViewState = useMemo(
|
const initialViewState = useMemo(
|
||||||
() =>
|
() => (mapUrlState.hasExplicitView ? mapUrlState.viewState : (demoView ?? INITIAL_VIEW_STATE)),
|
||||||
mapUrlState.hasExplicitView
|
|
||||||
? mapUrlState.viewState
|
|
||||||
: (demoView ?? INITIAL_VIEW_STATE),
|
|
||||||
[mapUrlState.hasExplicitView, mapUrlState.viewState, demoView]
|
[mapUrlState.hasExplicitView, mapUrlState.viewState, demoView]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -522,7 +522,12 @@ export default function MapPage({
|
||||||
setDemoPromptOpen(false);
|
setDemoPromptOpen(false);
|
||||||
// handleFlyTo uses map.jumpTo (instant) — no flashing 403s through
|
// handleFlyTo uses map.jumpTo (instant) — no flashing 403s through
|
||||||
// intermediate viewports; the move triggers a refetch carrying demoLat/Lon.
|
// intermediate viewports; the move triggers a refetch carrying demoLat/Lon.
|
||||||
mapFlyToRef.current?.(center.lat, center.lon, INITIAL_VIEW_STATE.zoom, getMobileMapFlyToOptions());
|
mapFlyToRef.current?.(
|
||||||
|
center.lat,
|
||||||
|
center.lon,
|
||||||
|
INITIAL_VIEW_STATE.zoom,
|
||||||
|
getMobileMapFlyToOptions()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
if (typeof navigator === 'undefined' || !navigator.geolocation) {
|
if (typeof navigator === 'undefined' || !navigator.geolocation) {
|
||||||
setDemoLocationError(t('locationSearch.geolocationUnsupported'));
|
setDemoLocationError(t('locationSearch.geolocationUnsupported'));
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ describe('buildTimelineEvents', () => {
|
||||||
{ year: 2019, status: 'Rented (private)' },
|
{ year: 2019, status: 'Rented (private)' },
|
||||||
{ year: 2023, status: 'Owner-occupied' },
|
{ year: 2023, status: 'Owner-occupied' },
|
||||||
],
|
],
|
||||||
}),
|
})
|
||||||
),
|
)
|
||||||
).toEqual(['tenure:Owner-occupied:2023', 'tenure:Rented (private):2019']);
|
).toEqual(['tenure:Owner-occupied:2023', 'tenure:Rented (private):2019']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -47,8 +47,8 @@ describe('buildTimelineEvents', () => {
|
||||||
{ year: 2024, month: 1, price: 300_000 },
|
{ year: 2024, month: 1, price: 300_000 },
|
||||||
],
|
],
|
||||||
tenure_history: [{ year: 2020, status: 'Rented (private)' }],
|
tenure_history: [{ year: 2020, status: 'Rented (private)' }],
|
||||||
}),
|
})
|
||||||
),
|
)
|
||||||
).toEqual(['tenure:Rented (private):2020', 'sale:2015']);
|
).toEqual(['tenure:Rented (private):2020', 'sale:2015']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,9 @@ describe('map utilities', () => {
|
||||||
expect(zoomToResolution(6.9)).toBe(5);
|
expect(zoomToResolution(6.9)).toBe(5);
|
||||||
expect(zoomToResolution(7)).toBe(6);
|
expect(zoomToResolution(7)).toBe(6);
|
||||||
expect(zoomToResolution(10.6)).toBe(8);
|
expect(zoomToResolution(10.6)).toBe(8);
|
||||||
expect(zoomToResolution(14)).toBe(8);
|
expect(zoomToResolution(12)).toBe(9);
|
||||||
expect(SMALLEST_VISIBLE_HEXAGON_RESOLUTION).toBe(8);
|
expect(zoomToResolution(14)).toBe(9);
|
||||||
|
expect(SMALLEST_VISIBLE_HEXAGON_RESOLUTION).toBe(9);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('computes exact viewport bounds by default', () => {
|
it('computes exact viewport bounds by default', () => {
|
||||||
|
|
|
||||||
|
|
@ -914,8 +914,7 @@ impl PropertyData {
|
||||||
|
|
||||||
// Re-key tenure_history by permuted row index
|
// Re-key tenure_history by permuted row index
|
||||||
let tenure_history: FxHashMap<u32, Vec<TenureEvent>> = {
|
let tenure_history: FxHashMap<u32, Vec<TenureEvent>> = {
|
||||||
let mut map =
|
let mut map = FxHashMap::with_capacity_and_hasher(tenure_raw.len(), Default::default());
|
||||||
FxHashMap::with_capacity_and_hasher(tenure_raw.len(), Default::default());
|
|
||||||
for (new_row, &old_row) in perm.iter().enumerate() {
|
for (new_row, &old_row) in perm.iter().enumerate() {
|
||||||
if let Some(events) = tenure_raw.remove(&old_row) {
|
if let Some(events) = tenure_raw.remove(&old_row) {
|
||||||
map.insert(new_row as u32, events);
|
map.insert(new_row as u32, events);
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@ fn demo_center_from_query(query: Option<&str>) -> Option<(f64, f64)> {
|
||||||
|
|
||||||
/// Resolve a request's demo zone from its query params, falling back to Canary Wharf.
|
/// Resolve a request's demo zone from its query params, falling back to Canary Wharf.
|
||||||
pub fn resolve_demo_zone(query: Option<&str>) -> DemoZone {
|
pub fn resolve_demo_zone(query: Option<&str>) -> DemoZone {
|
||||||
let (lat, lon) = demo_center_from_query(query)
|
let (lat, lon) =
|
||||||
.unwrap_or((FREE_ZONE_FALLBACK_LAT, FREE_ZONE_FALLBACK_LON));
|
demo_center_from_query(query).unwrap_or((FREE_ZONE_FALLBACK_LAT, FREE_ZONE_FALLBACK_LON));
|
||||||
DemoZone {
|
DemoZone {
|
||||||
free_zone: free_zone_around(lat, lon),
|
free_zone: free_zone_around(lat, lon),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ use url::form_urlencoded;
|
||||||
|
|
||||||
use crate::auth::PocketBaseUser;
|
use crate::auth::PocketBaseUser;
|
||||||
use crate::consts::{
|
use crate::consts::{
|
||||||
MAX_SHARE_LAT_SPAN, MAX_SHARE_LON_SPAN, MAX_SHARE_ZOOM, MIN_SHARE_ZOOM, SHARE_CACHE_MAX_ENTRIES,
|
MAX_SHARE_LAT_SPAN, MAX_SHARE_LON_SPAN, MAX_SHARE_ZOOM, MIN_SHARE_ZOOM,
|
||||||
SHARE_CACHE_TTL_SECS,
|
SHARE_CACHE_MAX_ENTRIES, SHARE_CACHE_TTL_SECS,
|
||||||
};
|
};
|
||||||
use crate::demo_zone::FreeZone;
|
use crate::demo_zone::FreeZone;
|
||||||
use crate::pocketbase::get_superuser_token;
|
use crate::pocketbase::get_superuser_token;
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,10 @@ fn is_internal_request(headers: &HeaderMap, peer: Option<IpAddr>) -> bool {
|
||||||
fn filter_count(query: &str) -> usize {
|
fn filter_count(query: &str) -> usize {
|
||||||
for (key, value) in form_urlencoded::parse(query.as_bytes()) {
|
for (key, value) in form_urlencoded::parse(query.as_bytes()) {
|
||||||
if key == "filters" {
|
if key == "filters" {
|
||||||
return value.split(";;").filter(|entry| !entry.trim().is_empty()).count();
|
return value
|
||||||
|
.split(";;")
|
||||||
|
.filter(|entry| !entry.trim().is_empty())
|
||||||
|
.count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
|
|
@ -157,7 +160,10 @@ pub async fn demo_guard_middleware(req: Request, next: Next) -> Response {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Licensed users and admins bypass demo guards entirely.
|
// Licensed users and admins bypass demo guards entirely.
|
||||||
let user = req.extensions().get::<OptionalUser>().and_then(|u| u.0.clone());
|
let user = req
|
||||||
|
.extensions()
|
||||||
|
.get::<OptionalUser>()
|
||||||
|
.and_then(|u| u.0.clone());
|
||||||
if let Some(u) = &user {
|
if let Some(u) = &user {
|
||||||
if u.is_admin || u.subscription == "licensed" {
|
if u.is_admin || u.subscription == "licensed" {
|
||||||
return next.run(req).await;
|
return next.run(req).await;
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,12 @@ pub async fn get_actual_listings(
|
||||||
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
||||||
|
|
||||||
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
||||||
check_license_bounds(&user.0, (south, west, north, east), geo.free_zone, share_bounds)?;
|
check_license_bounds(
|
||||||
|
&user.0,
|
||||||
|
(south, west, north, east),
|
||||||
|
geo.free_zone,
|
||||||
|
share_bounds,
|
||||||
|
)?;
|
||||||
|
|
||||||
let quant = state.data.quant_ref();
|
let quant = state.data.quant_ref();
|
||||||
let poi_quant = state.data.poi_metrics.quant_ref();
|
let poi_quant = state.data.poi_metrics.quant_ref();
|
||||||
|
|
|
||||||
|
|
@ -502,7 +502,12 @@ pub async fn get_export(
|
||||||
}
|
}
|
||||||
|
|
||||||
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
||||||
check_license_bounds(&user.0, (south, west, north, east), geo.free_zone, share_bounds)?;
|
check_license_bounds(
|
||||||
|
&user.0,
|
||||||
|
(south, west, north, east),
|
||||||
|
geo.free_zone,
|
||||||
|
share_bounds,
|
||||||
|
)?;
|
||||||
|
|
||||||
let quant = state.data.quant_ref();
|
let quant = state.data.quant_ref();
|
||||||
let poi_quant = state.data.poi_metrics.quant_ref();
|
let poi_quant = state.data.poi_metrics.quant_ref();
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,12 @@ pub async fn get_filter_counts(
|
||||||
let (south, west, north, east) =
|
let (south, west, north, east) =
|
||||||
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
||||||
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
||||||
check_license_bounds(&user.0, (south, west, north, east), geo.free_zone, share_bounds)?;
|
check_license_bounds(
|
||||||
|
&user.0,
|
||||||
|
(south, west, north, east),
|
||||||
|
geo.free_zone,
|
||||||
|
share_bounds,
|
||||||
|
)?;
|
||||||
|
|
||||||
let quant = state.data.quant_ref();
|
let quant = state.data.quant_ref();
|
||||||
let poi_quant = state.data.poi_metrics.quant_ref();
|
let poi_quant = state.data.poi_metrics.quant_ref();
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,12 @@ pub async fn get_hexagons(
|
||||||
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
||||||
|
|
||||||
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
||||||
check_license_bounds(&user.0, (south, west, north, east), geo.free_zone, share_bounds)?;
|
check_license_bounds(
|
||||||
|
&user.0,
|
||||||
|
(south, west, north, east),
|
||||||
|
geo.free_zone,
|
||||||
|
share_bounds,
|
||||||
|
)?;
|
||||||
|
|
||||||
let quant = state.data.quant_ref();
|
let quant = state.data.quant_ref();
|
||||||
let poi_quant = state.data.poi_metrics.quant_ref();
|
let poi_quant = state.data.poi_metrics.quant_ref();
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,12 @@ pub async fn get_postcodes(
|
||||||
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
require_bounds(params.bounds).map_err(IntoResponse::into_response)?;
|
||||||
|
|
||||||
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
let share_bounds = resolve_share_code(&state, params.share.as_deref()).await;
|
||||||
check_license_bounds(&user.0, (south, west, north, east), geo.free_zone, share_bounds)?;
|
check_license_bounds(
|
||||||
|
&user.0,
|
||||||
|
(south, west, north, east),
|
||||||
|
geo.free_zone,
|
||||||
|
share_bounds,
|
||||||
|
)?;
|
||||||
|
|
||||||
let quant = state.data.quant_ref();
|
let quant = state.data.quant_ref();
|
||||||
let poi_quant = state.data.poi_metrics.quant_ref();
|
let poi_quant = state.data.poi_metrics.quant_ref();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue