init: replay mode
This commit is contained in:
@@ -7,7 +7,8 @@ export type EditorMode =
|
||||
| "add-point"
|
||||
| "add-line"
|
||||
| "add-path"
|
||||
| "add-circle";
|
||||
| "add-circle"
|
||||
| "replay";
|
||||
|
||||
export type TimelineRange = {
|
||||
min: number;
|
||||
|
||||
@@ -7,7 +7,8 @@ export function initSelect(
|
||||
getMode: ModeGetter,
|
||||
onDelete?: (id: string | number) => void,
|
||||
onEdit?: (feature: maplibregl.MapGeoJSONFeature) => void,
|
||||
onSelectIds?: (ids: (string | number)[]) => void
|
||||
onSelectIds?: (ids: (string | number)[]) => void,
|
||||
onReplayEdit?: (id: string | number) => void
|
||||
) {
|
||||
|
||||
const FEATURE_STATE_SOURCES = [
|
||||
@@ -16,7 +17,7 @@ export function initSelect(
|
||||
"path-arrow-shapes",
|
||||
] as const;
|
||||
const selectedIds = new Set<number | string>();
|
||||
const hasContextActions = Boolean(onDelete || onEdit);
|
||||
const hasContextActions = Boolean(onDelete || onEdit || onReplayEdit);
|
||||
let contextMenu: HTMLDivElement | null = null;
|
||||
let docClickHandler: ((ev: MouseEvent) => void) | null = null;
|
||||
|
||||
@@ -54,7 +55,7 @@ export function initSelect(
|
||||
|
||||
// Chọn feature theo click trái, hỗ trợ additive bằng Alt.
|
||||
function onClick(e: maplibregl.MapLayerMouseEvent) {
|
||||
if (getMode() !== "select") return;
|
||||
if (getMode() !== "select" && getMode() !== "replay") return;
|
||||
const selectableLayers = getSelectableLayers();
|
||||
if (!selectableLayers.length) return;
|
||||
|
||||
@@ -74,11 +75,12 @@ export function initSelect(
|
||||
// Hiển thị menu ngữ cảnh (sửa/xóa) khi click chuột phải.
|
||||
// Mở menu thao tác khi click phải lên feature.
|
||||
function onRightClick(e: maplibregl.MapLayerMouseEvent) {
|
||||
if (getMode() !== "select") return;
|
||||
if (getMode() !== "select" && getMode() !== "replay") return;
|
||||
const selectableLayers = getSelectableLayers();
|
||||
if (!selectableLayers.length) return;
|
||||
|
||||
e.preventDefault(); // block browser menu
|
||||
if (getMode() === "replay") return;
|
||||
|
||||
const features = map.queryRenderedFeatures(e.point, {
|
||||
layers: selectableLayers,
|
||||
@@ -105,7 +107,7 @@ export function initSelect(
|
||||
|
||||
// Đổi cursor pointer khi hover lên đối tượng có thể chọn.
|
||||
function onMove(e: maplibregl.MapLayerMouseEvent) {
|
||||
if (getMode() !== "select") return;
|
||||
if (getMode() !== "select" && getMode() !== "replay") return;
|
||||
const selectableLayers = getSelectableLayers();
|
||||
if (!selectableLayers.length) {
|
||||
map.getCanvas().style.cursor = "";
|
||||
@@ -218,6 +220,17 @@ export function initSelect(
|
||||
hasMenuItems = true;
|
||||
}
|
||||
|
||||
if (
|
||||
selectedCount === 1 &&
|
||||
onReplayEdit
|
||||
) {
|
||||
const featureId = clickedFeature.id ?? clickedFeature.properties?.id;
|
||||
if (featureId) {
|
||||
menu.appendChild(createItem("Replay Edit", () => onReplayEdit(featureId)));
|
||||
hasMenuItems = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (onDelete) {
|
||||
menu.appendChild(
|
||||
createItem(
|
||||
|
||||
+30
-30
@@ -1,36 +1,36 @@
|
||||
import maplibregl from "maplibre-gl";
|
||||
export const TYPE_MATCH_EXPR: maplibregl.ExpressionSpecification = ["coalesce", ["get", "type"], ["get", "entity_type_id"], ""];
|
||||
export { ensurePointGeotypeIcons } from "./pointStyle";
|
||||
export { ensurePointGeotypeIcons } from "./shared/pointStyle";
|
||||
|
||||
import { getDefenseLineLayers } from "./defense_line";
|
||||
import { getAttackRouteLayers } from "./attack_route";
|
||||
import { getRetreatRouteLayers } from "./retreat_route";
|
||||
import { getInvasionRouteLayers } from "./invasion_route";
|
||||
import { getMigrationRouteLayers } from "./migration_route";
|
||||
import { getRefugeeRouteLayers } from "./refugee_route";
|
||||
import { getTradeRouteLayers } from "./trade_route";
|
||||
import { getShippingRouteLayers } from "./shipping_route";
|
||||
import { getCountryLayers } from "./country";
|
||||
import { getStateLayers } from "./state";
|
||||
import { getEmpireLayers } from "./empire";
|
||||
import { getKingdomLayers } from "./kingdom";
|
||||
import { getWarLayers } from "./war";
|
||||
import { getBattleLayers } from "./battle";
|
||||
import { getCivilizationLayers } from "./civilization";
|
||||
import { getRebellionZoneLayers } from "./rebellion_zone";
|
||||
import { getPersonDeathplaceLayers } from "./person_deathplace";
|
||||
import { getPersonBirthplaceLayers } from "./person_birthplace";
|
||||
import { getPersonActivityLayers } from "./person_activity";
|
||||
import { getTempleLayers } from "./temple";
|
||||
import { getCapitalLayers } from "./capital";
|
||||
import { getCityLayers } from "./city";
|
||||
import { getFortressLayers } from "./fortress";
|
||||
import { getCastleLayers } from "./castle";
|
||||
import { getRuinLayers } from "./ruin";
|
||||
import { getPortLayers } from "./port";
|
||||
import { getBridgeLayers } from "./bridge";
|
||||
import { getLineLabelLayers } from "./lineLabels";
|
||||
import { getPolygonLabelLayers } from "./polygonLabels";
|
||||
import { getDefenseLineLayers } from "./geotypes/defense_line";
|
||||
import { getAttackRouteLayers } from "./geotypes/attack_route";
|
||||
import { getRetreatRouteLayers } from "./geotypes/retreat_route";
|
||||
import { getInvasionRouteLayers } from "./geotypes/invasion_route";
|
||||
import { getMigrationRouteLayers } from "./geotypes/migration_route";
|
||||
import { getRefugeeRouteLayers } from "./geotypes/refugee_route";
|
||||
import { getTradeRouteLayers } from "./geotypes/trade_route";
|
||||
import { getShippingRouteLayers } from "./geotypes/shipping_route";
|
||||
import { getCountryLayers } from "./geotypes/country";
|
||||
import { getStateLayers } from "./geotypes/state";
|
||||
import { getEmpireLayers } from "./geotypes/empire";
|
||||
import { getKingdomLayers } from "./geotypes/kingdom";
|
||||
import { getWarLayers } from "./geotypes/war";
|
||||
import { getBattleLayers } from "./geotypes/battle";
|
||||
import { getCivilizationLayers } from "./geotypes/civilization";
|
||||
import { getRebellionZoneLayers } from "./geotypes/rebellion_zone";
|
||||
import { getPersonDeathplaceLayers } from "./geotypes/person_deathplace";
|
||||
import { getPersonBirthplaceLayers } from "./geotypes/person_birthplace";
|
||||
import { getPersonActivityLayers } from "./geotypes/person_activity";
|
||||
import { getTempleLayers } from "./geotypes/temple";
|
||||
import { getCapitalLayers } from "./geotypes/capital";
|
||||
import { getCityLayers } from "./geotypes/city";
|
||||
import { getFortressLayers } from "./geotypes/fortress";
|
||||
import { getCastleLayers } from "./geotypes/castle";
|
||||
import { getRuinLayers } from "./geotypes/ruin";
|
||||
import { getPortLayers } from "./geotypes/port";
|
||||
import { getBridgeLayers } from "./geotypes/bridge";
|
||||
import { getLineLabelLayers } from "./shared/lineLabels";
|
||||
import { getPolygonLabelLayers } from "./shared/polygonLabels";
|
||||
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getAttackRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getBattleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getBridgeLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getCapitalLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getCastleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getCityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getCivilizationLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getCountryLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getDefenseLineLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getEmpireLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getFortressLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getInvasionRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getKingdomLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getMigrationRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getPersonActivityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getPersonBirthplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getPersonDeathplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getPortLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getRebellionZoneLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getRefugeeRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getRetreatRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getRuinLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getShippingRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getStateLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPointGeotypeLayers } from "./pointStyle";
|
||||
import { buildPointGeotypeLayers } from "../shared/pointStyle";
|
||||
|
||||
export function getTempleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void sourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildLineGeotypeLayers } from "./styleBuilders";
|
||||
import { buildLineGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getTradeRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pointSourceId;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LayerSpecification } from "maplibre-gl";
|
||||
import { buildPolygonGeotypeLayers } from "./styleBuilders";
|
||||
import { buildPolygonGeotypeLayers } from "../shared/styleBuilders";
|
||||
|
||||
export function getWarLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||
void pathArrowSourceId;
|
||||
|
||||
Reference in New Issue
Block a user