fix ref geometry ref rerollable
This commit is contained in:
@@ -87,6 +87,10 @@ export default function SelectedGeometryPanel({
|
||||
|
||||
if (!selectedFeatures || selectedFeatures.length === 0) return null;
|
||||
const representativeFeature = selectedFeatures[0];
|
||||
const canRerollGeometryId =
|
||||
!isBulkMode &&
|
||||
representativeFeature.properties.source !== "ref" &&
|
||||
Boolean(onRerollGeometryId);
|
||||
|
||||
const groupedGeometryTypeOptions = groupGeometryTypeOptions(GEOMETRY_TYPE_OPTIONS);
|
||||
const featureGeometryPreset = resolveFeatureGeometryPreset(representativeFeature);
|
||||
@@ -225,7 +229,7 @@ export default function SelectedGeometryPanel({
|
||||
<div style={{ color: "#94a3b8", fontSize: "11px", overflowWrap: "anywhere", minWidth: 0, flex: 1 }}>
|
||||
{isBulkMode ? `Đang chọn ${selectedFeatures.length} geometries` : `ID: ${representativeFeature.properties.id}`}
|
||||
</div>
|
||||
{!isBulkMode && onRerollGeometryId && (
|
||||
{canRerollGeometryId && onRerollGeometryId && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onRerollGeometryId(representativeFeature.properties.id)}
|
||||
|
||||
@@ -23,6 +23,7 @@ type FeatureLabelInfo = {
|
||||
label: string;
|
||||
timeEnd: number | null;
|
||||
};
|
||||
const rasterBaseVisibilityGenerationByMap = new WeakMap<maplibregl.Map, number>();
|
||||
|
||||
export function applyBackgroundLayerVisibility(
|
||||
map: maplibregl.Map,
|
||||
@@ -47,19 +48,34 @@ export function applyBackgroundLayerVisibility(
|
||||
}
|
||||
|
||||
export function syncRasterBaseVisibility(map: maplibregl.Map, shouldShow: boolean) {
|
||||
const generation = nextRasterBaseVisibilityGeneration(map);
|
||||
const isCurrentRequest = () => rasterBaseVisibilityGenerationByMap.get(map) === generation;
|
||||
|
||||
if (shouldShow) {
|
||||
void ensureRasterBaseLayer(map).catch((error) => {
|
||||
void ensureRasterBaseLayer(map, isCurrentRequest).catch((error) => {
|
||||
console.error("Failed to load proxied raster background.", error);
|
||||
removeRasterBaseLayer(map);
|
||||
if (isCurrentRequest()) {
|
||||
removeRasterBaseLayer(map);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
removeRasterBaseLayer(map);
|
||||
}
|
||||
|
||||
export async function ensureRasterBaseLayer(map: maplibregl.Map) {
|
||||
function nextRasterBaseVisibilityGeneration(map: maplibregl.Map) {
|
||||
const next = (rasterBaseVisibilityGenerationByMap.get(map) || 0) + 1;
|
||||
rasterBaseVisibilityGenerationByMap.set(map, next);
|
||||
return next;
|
||||
}
|
||||
|
||||
export async function ensureRasterBaseLayer(
|
||||
map: maplibregl.Map,
|
||||
isCurrentRequest: () => boolean = () => true
|
||||
) {
|
||||
if (!map.getSource(RASTER_BASE_SOURCE_ID)) {
|
||||
const source = await createRasterBaseSource();
|
||||
if (!isCurrentRequest()) return;
|
||||
if (map.getSource(RASTER_BASE_SOURCE_ID)) {
|
||||
// Another caller already added the source while we were waiting.
|
||||
} else {
|
||||
@@ -67,6 +83,8 @@ export async function ensureRasterBaseLayer(map: maplibregl.Map) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCurrentRequest()) return;
|
||||
|
||||
const beforeId = getRasterBaseInsertBeforeLayerId(map);
|
||||
if (!map.getLayer(RASTER_BASE_LAYER_ID)) {
|
||||
map.addLayer(createRasterBaseLayer(), beforeId);
|
||||
@@ -74,6 +92,7 @@ export async function ensureRasterBaseLayer(map: maplibregl.Map) {
|
||||
map.moveLayer(RASTER_BASE_LAYER_ID, beforeId);
|
||||
}
|
||||
|
||||
if (!isCurrentRequest()) return;
|
||||
map.setLayoutProperty(RASTER_BASE_LAYER_ID, "visibility", "visible");
|
||||
}
|
||||
|
||||
|
||||
@@ -34,18 +34,18 @@ export default function TimelineBar({
|
||||
const effectiveDisabled = disabled;
|
||||
const safeYear = clampYearValue(year, lower, upper);
|
||||
|
||||
const [localYear, setLocalYear] = useState(safeYear);
|
||||
|
||||
// Đồng bộ prop year với localYear khi prop year thay đổi từ bên ngoài
|
||||
useEffect(() => {
|
||||
setLocalYear(safeYear);
|
||||
}, [safeYear]);
|
||||
|
||||
const localYearRef = useRef(localYear);
|
||||
localYearRef.current = localYear;
|
||||
|
||||
const [localYear, setLocalYear] = useState<number | null>(null);
|
||||
const displayYear = localYear ?? safeYear;
|
||||
const localYearRef = useRef(displayYear);
|
||||
const onYearChangeRef = useRef(onYearChange);
|
||||
onYearChangeRef.current = onYearChange;
|
||||
|
||||
useEffect(() => {
|
||||
localYearRef.current = displayYear;
|
||||
}, [displayYear]);
|
||||
|
||||
useEffect(() => {
|
||||
onYearChangeRef.current = onYearChange;
|
||||
}, [onYearChange]);
|
||||
|
||||
const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
||||
@@ -66,6 +66,7 @@ export default function TimelineBar({
|
||||
|
||||
const handleLocalYearChange = useCallback((nextVal: number) => {
|
||||
const clamped = clampYearValue(Math.trunc(nextVal), lower, upper);
|
||||
localYearRef.current = clamped;
|
||||
setLocalYear(clamped);
|
||||
|
||||
const now = Date.now();
|
||||
@@ -81,6 +82,11 @@ export default function TimelineBar({
|
||||
}
|
||||
}, [lower, upper, commitYearChange]);
|
||||
|
||||
const finishLocalYearChange = useCallback(() => {
|
||||
commitYearChange(localYearRef.current);
|
||||
setLocalYear(null);
|
||||
}, [commitYearChange]);
|
||||
|
||||
const startChangingYear = (direction: number) => {
|
||||
if (effectiveDisabled) return;
|
||||
const nextVal = localYearRef.current + direction;
|
||||
@@ -108,7 +114,7 @@ export default function TimelineBar({
|
||||
clearInterval(intervalRef.current);
|
||||
intervalRef.current = null;
|
||||
}
|
||||
commitYearChange(localYearRef.current);
|
||||
finishLocalYearChange();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -163,10 +169,10 @@ export default function TimelineBar({
|
||||
min={lower}
|
||||
max={upper}
|
||||
step={1}
|
||||
value={localYear}
|
||||
value={displayYear}
|
||||
onChange={(event) => handleLocalYearChange(Number(event.target.value))}
|
||||
onMouseUp={() => commitYearChange(localYearRef.current)}
|
||||
onTouchEnd={() => commitYearChange(localYearRef.current)}
|
||||
onMouseUp={finishLocalYearChange}
|
||||
onTouchEnd={finishLocalYearChange}
|
||||
disabled={effectiveDisabled}
|
||||
className={styles.slider}
|
||||
aria-label="Timeline year"
|
||||
@@ -180,12 +186,12 @@ export default function TimelineBar({
|
||||
min={lower}
|
||||
max={upper}
|
||||
step={1}
|
||||
value={localYear}
|
||||
value={displayYear}
|
||||
onChange={(event) => handleLocalYearChange(Number(event.target.value))}
|
||||
onBlur={() => commitYearChange(localYearRef.current)}
|
||||
onBlur={finishLocalYearChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
commitYearChange(localYearRef.current);
|
||||
finishLocalYearChange();
|
||||
}
|
||||
}}
|
||||
disabled={effectiveDisabled}
|
||||
|
||||
Reference in New Issue
Block a user