fix: Fix problems and bugs
This commit is contained in:
@ -75,6 +75,19 @@ import { makeAutoObservable } from "mobx";
|
|||||||
|
|
||||||
import { stationsStore, routeStore, sightsStore } from "@shared";
|
import { stationsStore, routeStore, sightsStore } from "@shared";
|
||||||
|
|
||||||
|
// Функция для сброса кешей карты
|
||||||
|
export const clearMapCaches = () => {
|
||||||
|
// Сброс кешей маршрутов
|
||||||
|
mapStore.routes = [];
|
||||||
|
mapStore.stations = [];
|
||||||
|
mapStore.sights = [];
|
||||||
|
|
||||||
|
// Сброс кешей MapService если он доступен
|
||||||
|
if (typeof window !== "undefined" && (window as any).mapServiceInstance) {
|
||||||
|
(window as any).mapServiceInstance.clearCaches();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
interface ApiRoute {
|
interface ApiRoute {
|
||||||
id: number;
|
id: number;
|
||||||
route_number: string;
|
route_number: string;
|
||||||
@ -328,6 +341,11 @@ class MapStore {
|
|||||||
|
|
||||||
const mapStore = new MapStore();
|
const mapStore = new MapStore();
|
||||||
|
|
||||||
|
// Делаем mapStore доступным глобально для сброса кешей
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
(window as any).mapStore = mapStore;
|
||||||
|
}
|
||||||
|
|
||||||
// --- CONFIGURATION ---
|
// --- CONFIGURATION ---
|
||||||
export const mapConfig = {
|
export const mapConfig = {
|
||||||
center: [30.311, 59.94] as [number, number],
|
center: [30.311, 59.94] as [number, number],
|
||||||
@ -453,7 +471,7 @@ class MapService {
|
|||||||
public routeLayer: VectorLayer<VectorSource<Feature<LineString>>>; // Public for deselect
|
public routeLayer: VectorLayer<VectorSource<Feature<LineString>>>; // Public for deselect
|
||||||
private clusterSource: Cluster;
|
private clusterSource: Cluster;
|
||||||
private clusterStyleCache: { [key: number]: Style };
|
private clusterStyleCache: { [key: number]: Style };
|
||||||
private unclusteredRouteIds: Set<string | number> = new Set();
|
|
||||||
private tooltipElement: HTMLElement;
|
private tooltipElement: HTMLElement;
|
||||||
private tooltipOverlay: Overlay | null;
|
private tooltipOverlay: Overlay | null;
|
||||||
private mode: string | null;
|
private mode: string | null;
|
||||||
@ -488,8 +506,7 @@ class MapService {
|
|||||||
private sightIconStyle: Style;
|
private sightIconStyle: Style;
|
||||||
private selectedSightIconStyle: Style;
|
private selectedSightIconStyle: Style;
|
||||||
private drawSightIconStyle: Style;
|
private drawSightIconStyle: Style;
|
||||||
private routeIconStyle: Style;
|
|
||||||
private selectedRouteIconStyle: Style;
|
|
||||||
private universalHoverStylePoint: Style;
|
private universalHoverStylePoint: Style;
|
||||||
private hoverSightIconStyle: Style;
|
private hoverSightIconStyle: Style;
|
||||||
private universalHoverStyleLine: Style;
|
private universalHoverStyleLine: Style;
|
||||||
@ -574,21 +591,6 @@ class MapService {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.routeIconStyle = new Style({
|
|
||||||
image: new CircleStyle({
|
|
||||||
radius: 8,
|
|
||||||
fill: new Fill({ color: "rgba(34, 197, 94, 0.8)" }), // Green
|
|
||||||
stroke: new Stroke({ color: "#ffffff", width: 1.5 }),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
this.selectedRouteIconStyle = new Style({
|
|
||||||
image: new CircleStyle({
|
|
||||||
radius: 10,
|
|
||||||
fill: new Fill({ color: "rgba(221, 107, 32, 0.9)" }), // Orange on select
|
|
||||||
stroke: new Stroke({ color: "#ffffff", width: 2 }),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sightIconStyle = new Style({
|
this.sightIconStyle = new Style({
|
||||||
image: new RegularShape({
|
image: new RegularShape({
|
||||||
fill: new Fill({ color: "rgba(139, 92, 246, 0.8)" }),
|
fill: new Fill({ color: "rgba(139, 92, 246, 0.8)" }),
|
||||||
@ -659,10 +661,7 @@ class MapService {
|
|||||||
if (!feature) return this.defaultStyle;
|
if (!feature) return this.defaultStyle;
|
||||||
const fId = feature.getId();
|
const fId = feature.getId();
|
||||||
|
|
||||||
if (fId === undefined || !this.unclusteredRouteIds.has(fId)) {
|
// Все маршруты всегда отображаются, так как они не кластеризуются
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isSelected =
|
const isSelected =
|
||||||
this.selectInteraction?.getFeatures().getArray().includes(feature) ||
|
this.selectInteraction?.getFeatures().getArray().includes(feature) ||
|
||||||
(fId !== undefined && this.selectedIds.has(fId));
|
(fId !== undefined && this.selectedIds.has(fId));
|
||||||
@ -705,8 +704,6 @@ class MapService {
|
|||||||
const originalFeature = featuresInCluster[0];
|
const originalFeature = featuresInCluster[0];
|
||||||
const fId = originalFeature.getId();
|
const fId = originalFeature.getId();
|
||||||
const featureType = originalFeature.get("featureType");
|
const featureType = originalFeature.get("featureType");
|
||||||
const isProxy = originalFeature.get("isProxy");
|
|
||||||
if (isProxy) return new Style(); // Invisible empty style
|
|
||||||
|
|
||||||
const isSelected = fId !== undefined && this.selectedIds.has(fId);
|
const isSelected = fId !== undefined && this.selectedIds.has(fId);
|
||||||
const isHovered = this.hoveredFeatureId === fId;
|
const isHovered = this.hoveredFeatureId === fId;
|
||||||
@ -719,45 +716,20 @@ class MapService {
|
|||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
if (featureType === "sight") return this.selectedSightIconStyle;
|
if (featureType === "sight") return this.selectedSightIconStyle;
|
||||||
if (featureType === "route") return this.selectedRouteIconStyle;
|
|
||||||
return this.selectedBusIconStyle;
|
return this.selectedBusIconStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (featureType === "sight") return this.sightIconStyle;
|
if (featureType === "sight") return this.sightIconStyle;
|
||||||
if (featureType === "route") return this.routeIconStyle;
|
|
||||||
return this.busIconStyle;
|
return this.busIconStyle;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.clusterSource.on("change", () => {
|
this.clusterSource.on("change", () => {
|
||||||
const newUnclusteredRouteIds = new Set<string | number>();
|
// Поскольку маршруты больше не добавляются как точки,
|
||||||
this.clusterSource
|
// нам не нужно отслеживать unclusteredRouteIds
|
||||||
.getFeatures()
|
// Все маршруты всегда отображаются как линии
|
||||||
.forEach((clusterFeature: Feature<any>) => {
|
|
||||||
const originalFeatures = clusterFeature.get(
|
|
||||||
"features"
|
|
||||||
) as Feature<Point>[];
|
|
||||||
if (originalFeatures && originalFeatures.length === 1) {
|
|
||||||
const originalFeature = originalFeatures[0];
|
|
||||||
if (originalFeature.get("featureType") === "route") {
|
|
||||||
const featureId = originalFeature.getId();
|
|
||||||
if (featureId !== undefined) {
|
|
||||||
newUnclusteredRouteIds.add(featureId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
|
||||||
newUnclusteredRouteIds.size !== this.unclusteredRouteIds.size ||
|
|
||||||
![...newUnclusteredRouteIds].every((id) =>
|
|
||||||
this.unclusteredRouteIds.has(id)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
this.unclusteredRouteIds = newUnclusteredRouteIds;
|
|
||||||
this.routeLayer.changed();
|
this.routeLayer.changed();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.boundHandlePointerMove = this.handlePointerMove.bind(this);
|
this.boundHandlePointerMove = this.handlePointerMove.bind(this);
|
||||||
@ -1209,23 +1181,7 @@ class MapService {
|
|||||||
lineFeature.set("featureType", "route");
|
lineFeature.set("featureType", "route");
|
||||||
lineFeatures.push(lineFeature);
|
lineFeatures.push(lineFeature);
|
||||||
|
|
||||||
if (route.center_longitude != null && route.center_latitude != null) {
|
// Не создаем прокси-точки для маршрутов - они должны оставаться только линиями
|
||||||
const centerPoint = new Point(
|
|
||||||
transform(
|
|
||||||
[route.center_longitude, route.center_latitude],
|
|
||||||
"EPSG:4326",
|
|
||||||
projection
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const proxyPointFeature = new Feature({
|
|
||||||
geometry: centerPoint,
|
|
||||||
name: route.route_number,
|
|
||||||
isProxy: true,
|
|
||||||
});
|
|
||||||
proxyPointFeature.setId(routeId);
|
|
||||||
proxyPointFeature.set("featureType", "route");
|
|
||||||
pointFeatures.push(proxyPointFeature);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.pointSource.addFeatures(pointFeatures);
|
this.pointSource.addFeatures(pointFeatures);
|
||||||
@ -1926,6 +1882,32 @@ class MapService {
|
|||||||
return this.map;
|
return this.map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Метод для сброса кешей карты
|
||||||
|
public clearCaches() {
|
||||||
|
this.clusterStyleCache = {};
|
||||||
|
this.history = [];
|
||||||
|
this.historyIndex = -1;
|
||||||
|
this.beforeActionState = null;
|
||||||
|
this.hoveredFeatureId = null;
|
||||||
|
this.selectedIds.clear();
|
||||||
|
|
||||||
|
// Очищаем источники данных
|
||||||
|
if (this.pointSource) {
|
||||||
|
this.pointSource.clear();
|
||||||
|
}
|
||||||
|
if (this.lineSource) {
|
||||||
|
this.lineSource.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем слои
|
||||||
|
if (this.clusterLayer) {
|
||||||
|
this.clusterLayer.changed();
|
||||||
|
}
|
||||||
|
if (this.routeLayer) {
|
||||||
|
this.routeLayer.changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public saveCurrentPosition(): void {
|
public saveCurrentPosition(): void {
|
||||||
if (!this.map) return;
|
if (!this.map) return;
|
||||||
const center = this.map.getView().getCenter();
|
const center = this.map.getView().getCenter();
|
||||||
@ -1941,20 +1923,6 @@ class MapService {
|
|||||||
const featureId = feature.getId();
|
const featureId = feature.getId();
|
||||||
if (!featureType || featureId === undefined || !this.map) return;
|
if (!featureType || featureId === undefined || !this.map) return;
|
||||||
|
|
||||||
if (
|
|
||||||
featureType === "route" &&
|
|
||||||
feature.getGeometry()?.getType() === "LineString"
|
|
||||||
) {
|
|
||||||
const proxyPoint = this.pointSource.getFeatureById(
|
|
||||||
featureId
|
|
||||||
) as Feature<Point>;
|
|
||||||
if (proxyPoint) {
|
|
||||||
const lineGeom = feature.getGeometry() as LineString;
|
|
||||||
const newCenter = getCenter(lineGeom.getExtent());
|
|
||||||
proxyPoint.getGeometry()?.setCoordinates(newCenter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof featureId === "number" || !String(featureId).includes("-")) {
|
if (typeof featureId === "number" || !String(featureId).includes("-")) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Skipping save for feature with non-standard ID:",
|
"Skipping save for feature with non-standard ID:",
|
||||||
@ -2023,22 +1991,7 @@ class MapService {
|
|||||||
);
|
);
|
||||||
feature.setGeometry(lineGeom);
|
feature.setGeometry(lineGeom);
|
||||||
|
|
||||||
// Create and add proxy point
|
// Не создаем прокси-точку для маршрута - только линия
|
||||||
const centerPointGeom = new Point(
|
|
||||||
transform(
|
|
||||||
[routeData.center_longitude, routeData.center_latitude],
|
|
||||||
"EPSG:4326",
|
|
||||||
projection
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const proxyPointFeature = new Feature({
|
|
||||||
geometry: centerPointGeom,
|
|
||||||
name: displayName,
|
|
||||||
isProxy: true,
|
|
||||||
});
|
|
||||||
proxyPointFeature.setId(newFeatureId);
|
|
||||||
proxyPointFeature.set("featureType", "route");
|
|
||||||
this.pointSource.addFeature(proxyPointFeature);
|
|
||||||
} else {
|
} else {
|
||||||
// For points: update existing
|
// For points: update existing
|
||||||
feature.setId(newFeatureId);
|
feature.setId(newFeatureId);
|
||||||
@ -2603,6 +2556,12 @@ export const MapPage: React.FC = () => {
|
|||||||
setSelectedIds
|
setSelectedIds
|
||||||
);
|
);
|
||||||
setMapServiceInstance(service);
|
setMapServiceInstance(service);
|
||||||
|
|
||||||
|
// Делаем mapServiceInstance доступным глобально для сброса кешей
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
(window as any).mapServiceInstance = service;
|
||||||
|
}
|
||||||
|
|
||||||
loadInitialData(service);
|
loadInitialData(service);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
setError(
|
setError(
|
||||||
@ -2615,6 +2574,11 @@ export const MapPage: React.FC = () => {
|
|||||||
return () => {
|
return () => {
|
||||||
service?.destroy();
|
service?.destroy();
|
||||||
setMapServiceInstance(null);
|
setMapServiceInstance(null);
|
||||||
|
|
||||||
|
// Удаляем глобальную ссылку
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
delete (window as any).mapServiceInstance;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -225,7 +225,7 @@ export const LinkedItemsContents = <
|
|||||||
if (type === "edit") {
|
if (type === "edit") {
|
||||||
setError(null);
|
setError(null);
|
||||||
authInstance
|
authInstance
|
||||||
.get(`/${childResource}/`)
|
.get(`/${childResource}`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setAllItems(response?.data || []);
|
setAllItems(response?.data || []);
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button, Paper, TextField } from "@mui/material";
|
import { Button, TextField } from "@mui/material";
|
||||||
import { snapshotStore } from "@shared";
|
import { snapshotStore } from "@shared";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { ArrowLeft, Loader2, Save } from "lucide-react";
|
import { ArrowLeft, Loader2, Save } from "lucide-react";
|
||||||
@ -20,7 +20,8 @@ export const SnapshotCreatePage = observer(() => {
|
|||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper className="w-full h-full p-3 flex flex-col gap-10">
|
<div className="w-full h-[400px] flex justify-center items-center">
|
||||||
|
<div className="w-full h-full p-3 flex flex-col gap-10">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<button
|
<button
|
||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
@ -51,11 +52,15 @@ export const SnapshotCreatePage = observer(() => {
|
|||||||
await createSnapshot(name);
|
await createSnapshot(name);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
toast.success("Снапшот успешно создан");
|
toast.success("Снапшот успешно создан");
|
||||||
|
navigate(-1);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
toast.error("Ошибка при создании снапшота");
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={isLoading}
|
disabled={isLoading || !name.trim()}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Loader2 size={20} className="animate-spin" />
|
<Loader2 size={20} className="animate-spin" />
|
||||||
@ -64,6 +69,7 @@ export const SnapshotCreatePage = observer(() => {
|
|||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Paper>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
export * from "./SnapshotListPage";
|
export * from "./SnapshotListPage";
|
||||||
|
|
||||||
export * from "./SnapshotCreatePage";
|
export * from "./SnapshotCreatePage";
|
||||||
|
@ -176,7 +176,7 @@ export const LinkedSightsContents = <
|
|||||||
if (type === "edit") {
|
if (type === "edit") {
|
||||||
setError(null);
|
setError(null);
|
||||||
authInstance
|
authInstance
|
||||||
.get(`/${childResource}/`)
|
.get(`/${childResource}`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setAllItems(response?.data || []);
|
setAllItems(response?.data || []);
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,24 @@
|
|||||||
import { authInstance } from "@shared";
|
import { authInstance } from "@shared";
|
||||||
|
|
||||||
import { makeAutoObservable, runInAction } from "mobx";
|
import { makeAutoObservable, runInAction } from "mobx";
|
||||||
|
// Импорт функции сброса кешей карты
|
||||||
|
// import { clearMapCaches } from "../../pages/MapPage";
|
||||||
|
import {
|
||||||
|
articlesStore,
|
||||||
|
cityStore,
|
||||||
|
countryStore,
|
||||||
|
carrierStore,
|
||||||
|
stationsStore,
|
||||||
|
sightsStore,
|
||||||
|
routeStore,
|
||||||
|
vehicleStore,
|
||||||
|
userStore,
|
||||||
|
mediaStore,
|
||||||
|
createSightStore,
|
||||||
|
editSightStore,
|
||||||
|
devicesStore,
|
||||||
|
authStore,
|
||||||
|
} from "@shared";
|
||||||
|
|
||||||
type Snapshot = {
|
type Snapshot = {
|
||||||
ID: string;
|
ID: string;
|
||||||
@ -17,6 +35,248 @@ class SnapshotStore {
|
|||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Функция для сброса всех кешей в приложении
|
||||||
|
private clearAllCaches = () => {
|
||||||
|
// Сброс кешей статей
|
||||||
|
articlesStore.articleList = {
|
||||||
|
ru: { data: [], loaded: false },
|
||||||
|
en: { data: [], loaded: false },
|
||||||
|
zh: { data: [], loaded: false },
|
||||||
|
};
|
||||||
|
articlesStore.articlePreview = {};
|
||||||
|
articlesStore.articleData = null;
|
||||||
|
articlesStore.articleMedia = null;
|
||||||
|
|
||||||
|
// Сброс кешей городов
|
||||||
|
cityStore.cities = {
|
||||||
|
ru: { data: [], loaded: false },
|
||||||
|
en: { data: [], loaded: false },
|
||||||
|
zh: { data: [], loaded: false },
|
||||||
|
};
|
||||||
|
cityStore.ruCities = { data: [], loaded: false };
|
||||||
|
cityStore.city = {};
|
||||||
|
|
||||||
|
// Сброс кешей стран
|
||||||
|
countryStore.countries = {
|
||||||
|
ru: { data: [], loaded: false },
|
||||||
|
en: { data: [], loaded: false },
|
||||||
|
zh: { data: [], loaded: false },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Сброс кешей перевозчиков
|
||||||
|
carrierStore.carriers = {
|
||||||
|
ru: { data: [], loaded: false },
|
||||||
|
en: { data: [], loaded: false },
|
||||||
|
zh: { data: [], loaded: false },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Сброс кешей станций
|
||||||
|
stationsStore.stationLists = {
|
||||||
|
ru: { data: [], loaded: false },
|
||||||
|
en: { data: [], loaded: false },
|
||||||
|
zh: { data: [], loaded: false },
|
||||||
|
};
|
||||||
|
stationsStore.stationPreview = {};
|
||||||
|
|
||||||
|
// Сброс кешей достопримечательностей
|
||||||
|
sightsStore.sights = [];
|
||||||
|
sightsStore.sight = null;
|
||||||
|
|
||||||
|
// Сброс кешей маршрутов
|
||||||
|
routeStore.routes = { data: [], loaded: false };
|
||||||
|
|
||||||
|
// Сброс кешей транспорта
|
||||||
|
vehicleStore.vehicles = { data: [], loaded: false };
|
||||||
|
|
||||||
|
// Сброс кешей пользователей
|
||||||
|
userStore.users = { data: [], loaded: false };
|
||||||
|
|
||||||
|
// Сброс кешей медиа
|
||||||
|
mediaStore.media = [];
|
||||||
|
mediaStore.oneMedia = null;
|
||||||
|
|
||||||
|
// Сброс кешей создания и редактирования достопримечательностей
|
||||||
|
createSightStore.sight = JSON.parse(
|
||||||
|
JSON.stringify({
|
||||||
|
city_id: 0,
|
||||||
|
city: "",
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
thumbnail: null,
|
||||||
|
watermark_lu: null,
|
||||||
|
watermark_rd: null,
|
||||||
|
left_article: 0,
|
||||||
|
preview_media: null,
|
||||||
|
video_preview: null,
|
||||||
|
ru: {
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
left: { heading: "", body: "", media: [] },
|
||||||
|
right: [],
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
left: { heading: "", body: "", media: [] },
|
||||||
|
right: [],
|
||||||
|
},
|
||||||
|
zh: {
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
left: { heading: "", body: "", media: [] },
|
||||||
|
right: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
createSightStore.uploadMediaOpen = false;
|
||||||
|
createSightStore.fileToUpload = null;
|
||||||
|
createSightStore.needLeaveAgree = false;
|
||||||
|
|
||||||
|
editSightStore.sight = {
|
||||||
|
common: {
|
||||||
|
id: 0,
|
||||||
|
city_id: 0,
|
||||||
|
city: "",
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
thumbnail: null,
|
||||||
|
watermark_lu: null,
|
||||||
|
watermark_rd: null,
|
||||||
|
left_article: 0,
|
||||||
|
preview_media: null,
|
||||||
|
video_preview: null,
|
||||||
|
},
|
||||||
|
ru: {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
left: { heading: "", body: "", media: [] },
|
||||||
|
right: [],
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
left: { heading: "", body: "", media: [] },
|
||||||
|
right: [],
|
||||||
|
},
|
||||||
|
zh: {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
left: { heading: "", body: "", media: [] },
|
||||||
|
right: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
editSightStore.hasLoadedCommon = false;
|
||||||
|
editSightStore.uploadMediaOpen = false;
|
||||||
|
editSightStore.fileToUpload = null;
|
||||||
|
editSightStore.needLeaveAgree = false;
|
||||||
|
|
||||||
|
// Сброс кешей устройств
|
||||||
|
devicesStore.devices = [];
|
||||||
|
devicesStore.uuid = null;
|
||||||
|
devicesStore.sendSnapshotModalOpen = false;
|
||||||
|
|
||||||
|
// Сброс кешей авторизации (кроме токена)
|
||||||
|
authStore.payload = null;
|
||||||
|
authStore.error = null;
|
||||||
|
authStore.isLoading = false;
|
||||||
|
|
||||||
|
// Сброс кешей карты (если они загружены)
|
||||||
|
try {
|
||||||
|
// Сбрасываем кеши mapStore если он доступен
|
||||||
|
if (typeof window !== "undefined" && (window as any).mapStore) {
|
||||||
|
(window as any).mapStore.routes = [];
|
||||||
|
(window as any).mapStore.stations = [];
|
||||||
|
(window as any).mapStore.sights = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сбрасываем кеши MapService если он доступен
|
||||||
|
if (typeof window !== "undefined" && (window as any).mapServiceInstance) {
|
||||||
|
(window as any).mapServiceInstance.clearCaches();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Не удалось сбросить кеши карты:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сброс localStorage кешей (кроме токена авторизации)
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
const rememberedEmail = localStorage.getItem("rememberedEmail");
|
||||||
|
const rememberedPassword = localStorage.getItem("rememberedPassword");
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
sessionStorage.clear();
|
||||||
|
|
||||||
|
// Восстанавливаем важные данные
|
||||||
|
if (token) localStorage.setItem("token", token);
|
||||||
|
if (rememberedEmail)
|
||||||
|
localStorage.setItem("rememberedEmail", rememberedEmail);
|
||||||
|
if (rememberedPassword)
|
||||||
|
localStorage.setItem("rememberedPassword", rememberedPassword);
|
||||||
|
|
||||||
|
// Сброс кешей карты (если они есть)
|
||||||
|
const mapPositionKey = "mapPosition";
|
||||||
|
const activeSectionKey = "mapActiveSection";
|
||||||
|
if (localStorage.getItem(mapPositionKey)) {
|
||||||
|
localStorage.removeItem(mapPositionKey);
|
||||||
|
}
|
||||||
|
if (localStorage.getItem(activeSectionKey)) {
|
||||||
|
localStorage.removeItem(activeSectionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Попытка очистить кеш браузера (если поддерживается)
|
||||||
|
if ("caches" in window) {
|
||||||
|
try {
|
||||||
|
caches
|
||||||
|
.keys()
|
||||||
|
.then((cacheNames) => {
|
||||||
|
return Promise.all(
|
||||||
|
cacheNames.map((cacheName) => {
|
||||||
|
return caches.delete(cacheName);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log("Кеш браузера очищен");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn("Не удалось очистить кеш браузера:", error);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Кеш браузера не поддерживается:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Попытка очистить IndexedDB (если поддерживается)
|
||||||
|
if ("indexedDB" in window) {
|
||||||
|
try {
|
||||||
|
indexedDB
|
||||||
|
.databases()
|
||||||
|
.then((databases) => {
|
||||||
|
return Promise.all(
|
||||||
|
databases.map((db) => {
|
||||||
|
if (db.name) {
|
||||||
|
return indexedDB.deleteDatabase(db.name);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log("IndexedDB очищен");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn("Не удалось очистить IndexedDB:", error);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("IndexedDB не поддерживается:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Все кеши приложения сброшены");
|
||||||
|
};
|
||||||
|
|
||||||
getSnapshots = async () => {
|
getSnapshots = async () => {
|
||||||
const response = await authInstance.get(`/snapshots`);
|
const response = await authInstance.get(`/snapshots`);
|
||||||
|
|
||||||
@ -42,6 +302,10 @@ class SnapshotStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
restoreSnapshot = async (id: string) => {
|
restoreSnapshot = async (id: string) => {
|
||||||
|
// Сначала сбрасываем все кеши
|
||||||
|
this.clearAllCaches();
|
||||||
|
|
||||||
|
// Затем восстанавливаем снапшот
|
||||||
await authInstance.post(`/snapshots/${id}/restore`);
|
await authInstance.post(`/snapshots/${id}/restore`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user