/** * Tài liệu schema tham chiếu cho snapshot commit. * * Lưu ý: * - Đây không phải "single source of truth" của runtime hiện tại; logic normalize/build thật nằm ở * `src/uhm/lib/editor/snapshot/editorSnapshot.ts`. * - Các phần như `replays` và nhóm `UIFunctionName` / `MapFunctionName` mô tả schema dự phòng hoặc tương lai. * Editor route `/editor/[id]` hiện có mode `replay`, nhưng chưa thực thi hệ thống scripted replay đầy đủ theo file này. * - Các field denormalized dùng cho UI như `entity_ids`, `entity_name`, `binding`, `time_start`, `time_end` * có thể xuất hiện trong editor runtime, nhưng frontend sẽ strip hoặc tái sinh chúng khi build snapshot API. */ // ---- Root request ---- export type CreateCommitRequest = { snapshot_json: CommitSnapshot; edit_summary: string; }; // ---- Snapshot root ---- export type CommitSnapshot = { editor_feature_collection: FeatureCollection; entities: EntitySnapshot[]; geometries: GeometrySnapshot[]; geometry_entity: GeometryEntitySnapshot[]; wikis: WikiSnapshot[]; entity_wiki: EntityWikiLinkSnapshot[]; replays?: BattleReplay[]; }; // ---- Replay / Scripting System ---- export type UIFunctionName = | "hide_timeline" // Ẩn thanh timeline | "hide_layer_panel" // Ẩn panel lớp bản đồ | "hide_wiki_panel" // Ẩn panel wiki (bên phải) | "hide_zoom_panel" // Ẩn các nút điều khiển zoom | "hide_all_UI" // Ẩn toàn bộ giao diện điều khiển (cinematic mode) | "open_wiki" // Mở panel wiki | "show_toast_message" // Hiển thị thông báo ngắn (toast) | "focus_wiki_header" // Cuộn đến đề mục cụ thể trong Wiki | "set_playback_speed"; // Thay đổi tốc độ phát replay export type MapFunctionName = | "zoom_to_lnglat" // Di chuyển camera đến tọa độ [lng, lat] | "zoom_scale" // Thay đổi mức zoom của bản đồ | "zoom_geometries" // Zoom bao quát danh sách các geometry | "change_geometry_color" // Thay đổi màu của một geometry | "change_geometries_color" // Thay đổi màu của danh sách geometry | "change_geometry_texture" // Thay đổi texture của một geometry | "change_geometries_texture"// Thay đổi texture của danh sách geometry | "hide_geometries" // Ẩn danh sách các geometry | "set_camera_view" // Đặt trạng thái camera (center, zoom, pitch, bearing) | "fly_to_geometry" // Di chuyển mượt mà đến một geometry | "rotate_around_point" // Xoay camera quanh một điểm | "pulse_geometry" // Hiệu ứng nhấp nháy cho geometry | "set_time_filter" // Thay đổi bộ lọc thời gian trên bản đồ | "toggle_labels"; // Bật/tắt hiển thị nhãn (labels) trên bản đồ export type NarrativeFunctionName = | "set_title" // Đặt tiêu đề cho bước replay | "set_descriptions" // Đặt mô tả/nội dung diễn giải | "show_dialog_box" // Hiển thị hộp thoại dẫn chuyện (có avatar) | "display_historical_image" // Hiển thị hình ảnh tư liệu đè lên bản đồ | "set_step_subtitle"; // Hiển thị phụ đề phía dưới màn hình export type ReplayAction = { function_name: T; params: any[]; }; export type ReplayStep = { duration: number; // Trọng số thời gian của step trong 1 stage use_UI_function: ReplayAction[]; use_map_function: ReplayAction[]; use_narrow_function: ReplayAction[]; }; export type ReplayStage = { id: number; // số đếm thứ tự từ 0 title?: string; detail_time_start: string; detail_time_stop: string; steps: ReplayStep[]; }; export type BattleReplay = { geometry_id: string; // geometry mà khi nhấn vào là có thể replay detail: ReplayStage[]; }; // ---- GeoJSON / FeatureCollection ---- export type Geometry = | ({ type: "Point"; coordinates: [number, number] } & CircleGeometryMetadata) | ({ type: "MultiPoint"; coordinates: [number, number][] } & CircleGeometryMetadata) | ({ type: "LineString"; coordinates: [number, number][] } & CircleGeometryMetadata) | ({ type: "MultiLineString"; coordinates: [number, number][][] } & CircleGeometryMetadata) | ({ type: "Polygon"; coordinates: [number, number][][] } & CircleGeometryMetadata) | ({ type: "MultiPolygon"; coordinates: [number, number][][][] } & CircleGeometryMetadata); export type CircleGeometryMetadata = { circle_center?: [number, number]; circle_radius?: number; }; export type FeatureId = string | number; export type FeatureProperties = { id: FeatureId; type?: string | null; //generate geometry_preset?: string | null; time_start?: number | null; //generate time_end?: number | null; //generate binding?: string[]; //generate // Legacy/UI-only fields should not be relied on by the backend. // FE strips these when building snapshot_json, but we keep them optional here // because older snapshots may still contain them. entity_id?: string | null; //generate entity_ids?: string[]; //generate entity_name?: string | null; //generate entity_names?: string[]; //generate entity_type_id?: string | null; //generate }; export type Feature = { type: "Feature"; properties: FeatureProperties; geometry: Geometry; }; export type FeatureCollection = { type: "FeatureCollection"; features: Feature[]; }; // ---- Snapshot rows ---- export type SnapshotSource = "inline" | "ref"; export type SnapshotOperation = "create" | "update" | "delete" | "reference"; export type EntitySnapshot = { id: string; source: SnapshotSource; operation?: SnapshotOperation; name?: string; description?: string | null; }; export type GeometrySnapshot = { id: string; source: SnapshotSource; operation?: SnapshotOperation; type?: string | null; draw_geometry?: Geometry; binding?: string[]; time_start?: number | null; time_end?: number | null; bbox?: { min_lng: number; min_lat: number; max_lng: number; max_lat: number; } | null; }; export type GeometryEntitySnapshot = { geometry_id: string; entity_id: string; operation?: "reference" | "delete" | "binding"; }; // FE stores wiki doc as a string (often HTML) or null for ref-only rows. export type WikiDoc = string | null; export type WikiSnapshot = { id: string; source: SnapshotSource; operation?: SnapshotOperation; title: string; slug?: string | null; doc: WikiDoc; }; export type EntityWikiLinkSnapshot = { entity_id: string; wiki_id: string; operation?: "reference" | "delete" | "binding"; };