mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 02:35:42 +00:00
fix(Map): Added migration mechanism
This commit is contained in:
@@ -1,11 +1,10 @@
|
|||||||
import { NodeSelectionMouseHandler } from '@/hooks/Mapper/components/contexts/types.ts';
|
import { NodeSelectionMouseHandler } from '@/hooks/Mapper/components/contexts/types.ts';
|
||||||
import { SESSION_KEY } from '@/hooks/Mapper/constants.ts';
|
|
||||||
import { PingData, SolarSystemConnection, SolarSystemRawType } from '@/hooks/Mapper/types';
|
import { PingData, SolarSystemConnection, SolarSystemRawType } from '@/hooks/Mapper/types';
|
||||||
import { MapHandlers, OutCommand, OutCommandHandler } from '@/hooks/Mapper/types/mapHandlers.ts';
|
import { MapHandlers, OutCommand, OutCommandHandler } from '@/hooks/Mapper/types/mapHandlers.ts';
|
||||||
import { ctxManager } from '@/hooks/Mapper/utils/contextManager.ts';
|
import { ctxManager } from '@/hooks/Mapper/utils/contextManager.ts';
|
||||||
import type { PanelPosition } from '@reactflow/core';
|
import type { PanelPosition } from '@reactflow/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { ForwardedRef, forwardRef, MouseEvent, useCallback, useEffect, useMemo } from 'react';
|
import { ForwardedRef, forwardRef, MouseEvent, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
Background,
|
Background,
|
||||||
Edge,
|
Edge,
|
||||||
@@ -33,19 +32,9 @@ import {
|
|||||||
import { getBehaviorForTheme } from './helpers/getThemeBehavior';
|
import { getBehaviorForTheme } from './helpers/getThemeBehavior';
|
||||||
import { useEdgesState, useMapHandlers, useNodesState, useUpdateNodes } from './hooks';
|
import { useEdgesState, useMapHandlers, useNodesState, useUpdateNodes } from './hooks';
|
||||||
import { useBackgroundVars } from './hooks/useBackgroundVars';
|
import { useBackgroundVars } from './hooks/useBackgroundVars';
|
||||||
import { OnMapAddSystemCallback, OnMapSelectionChange } from './map.types';
|
import { MapViewport, OnMapAddSystemCallback, OnMapSelectionChange } from './map.types';
|
||||||
|
import type { Viewport } from '@reactflow/core/dist/esm/types';
|
||||||
const DEFAULT_VIEW_PORT = { zoom: 1, x: 0, y: 0 };
|
import { usePrevious } from 'primereact/hooks';
|
||||||
|
|
||||||
const getViewPortFromStore = () => {
|
|
||||||
const restored = localStorage.getItem(SESSION_KEY.viewPort);
|
|
||||||
|
|
||||||
if (!restored) {
|
|
||||||
return { ...DEFAULT_VIEW_PORT };
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.parse(restored);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialNodes: Node<SolarSystemRawType>[] = [
|
const initialNodes: Node<SolarSystemRawType>[] = [
|
||||||
// {
|
// {
|
||||||
@@ -88,6 +77,7 @@ interface MapCompProps {
|
|||||||
onConnectionInfoClick?(e: SolarSystemConnection): void;
|
onConnectionInfoClick?(e: SolarSystemConnection): void;
|
||||||
onAddSystem?: OnMapAddSystemCallback;
|
onAddSystem?: OnMapAddSystemCallback;
|
||||||
onSelectionContextMenu?: NodeSelectionMouseHandler;
|
onSelectionContextMenu?: NodeSelectionMouseHandler;
|
||||||
|
onChangeViewport?: (viewport: MapViewport) => void;
|
||||||
minimapClasses?: string;
|
minimapClasses?: string;
|
||||||
isShowMinimap?: boolean;
|
isShowMinimap?: boolean;
|
||||||
onSystemContextMenu: (event: MouseEvent<Element>, systemId: string) => void;
|
onSystemContextMenu: (event: MouseEvent<Element>, systemId: string) => void;
|
||||||
@@ -99,6 +89,7 @@ interface MapCompProps {
|
|||||||
pings: PingData[];
|
pings: PingData[];
|
||||||
minimapPlacement?: PanelPosition;
|
minimapPlacement?: PanelPosition;
|
||||||
localShowShipName?: boolean;
|
localShowShipName?: boolean;
|
||||||
|
defaultViewport?: Viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapComp = ({
|
const MapComp = ({
|
||||||
@@ -119,19 +110,25 @@ const MapComp = ({
|
|||||||
pings,
|
pings,
|
||||||
minimapPlacement = 'bottom-right',
|
minimapPlacement = 'bottom-right',
|
||||||
localShowShipName = false,
|
localShowShipName = false,
|
||||||
|
onChangeViewport,
|
||||||
|
defaultViewport,
|
||||||
}: MapCompProps) => {
|
}: MapCompProps) => {
|
||||||
const { getNodes } = useReactFlow();
|
const { getNodes, setViewport } = useReactFlow();
|
||||||
const [nodes, , onNodesChange] = useNodesState<Node<SolarSystemRawType>>(initialNodes);
|
const [nodes, , onNodesChange] = useNodesState<Node<SolarSystemRawType>>(initialNodes);
|
||||||
const [edges, , onEdgesChange] = useEdgesState<Edge<SolarSystemConnection>>(initialEdges);
|
const [edges, , onEdgesChange] = useEdgesState<Edge<SolarSystemConnection>>(initialEdges);
|
||||||
|
|
||||||
useMapHandlers(refn, onSelectionChange);
|
useMapHandlers(refn, onSelectionChange);
|
||||||
useUpdateNodes(nodes);
|
useUpdateNodes(nodes);
|
||||||
|
|
||||||
const { handleRootContext, ...rootCtxProps } = useContextMenuRootHandlers({ onAddSystem });
|
const { handleRootContext, ...rootCtxProps } = useContextMenuRootHandlers({ onAddSystem });
|
||||||
const { handleConnectionContext, ...connectionCtxProps } = useContextMenuConnectionHandlers();
|
const { handleConnectionContext, ...connectionCtxProps } = useContextMenuConnectionHandlers();
|
||||||
const { update } = useMapState();
|
const { update } = useMapState();
|
||||||
const { variant, gap, size, color } = useBackgroundVars(theme);
|
const { variant, gap, size, color } = useBackgroundVars(theme);
|
||||||
const { isPanAndDrag, nodeComponent, connectionMode } = getBehaviorForTheme(theme || 'default');
|
const { isPanAndDrag, nodeComponent, connectionMode } = getBehaviorForTheme(theme || 'default');
|
||||||
|
|
||||||
|
const refVars = useRef({ onChangeViewport });
|
||||||
|
refVars.current = { onChangeViewport };
|
||||||
|
|
||||||
const nodeTypes = useMemo(() => {
|
const nodeTypes = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
custom: nodeComponent,
|
custom: nodeComponent,
|
||||||
@@ -187,9 +184,13 @@ const MapComp = ({
|
|||||||
[onSelectionChange],
|
[onSelectionChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMoveEnd: OnMoveEnd = (_, viewport) => {
|
const handleMoveEnd: OnMoveEnd = useCallback((_, viewport) => {
|
||||||
localStorage.setItem(SESSION_KEY.viewPort, JSON.stringify(viewport));
|
// @ts-ignore
|
||||||
};
|
refVars.current.onChangeViewport?.(viewport);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('JOipP', `defaultViewport`, defaultViewport);
|
||||||
|
|
||||||
const handleNodesChange = useCallback(
|
const handleNodesChange = useCallback(
|
||||||
(changes: NodeChange[]) => {
|
(changes: NodeChange[]) => {
|
||||||
@@ -218,6 +219,19 @@ const MapComp = ({
|
|||||||
}));
|
}));
|
||||||
}, [showKSpaceBG, isThickConnections, pings, update, localShowShipName]);
|
}, [showKSpaceBG, isThickConnections, pings, update, localShowShipName]);
|
||||||
|
|
||||||
|
const prevViewport = usePrevious(defaultViewport);
|
||||||
|
useEffect(() => {
|
||||||
|
if (defaultViewport == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevViewport == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setViewport(defaultViewport);
|
||||||
|
}, [defaultViewport, prevViewport, setViewport]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@@ -232,7 +246,7 @@ const MapComp = ({
|
|||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
// TODO we need save into session all of this
|
// TODO we need save into session all of this
|
||||||
// and on any action do either
|
// and on any action do either
|
||||||
defaultViewport={getViewPortFromStore()}
|
defaultViewport={defaultViewport}
|
||||||
edgeTypes={edgeTypes}
|
edgeTypes={edgeTypes}
|
||||||
nodeTypes={nodeTypes}
|
nodeTypes={nodeTypes}
|
||||||
connectionMode={connectionMode}
|
connectionMode={connectionMode}
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ export type OnMapSelectionChange = (event: {
|
|||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
export type OnMapAddSystemCallback = (props: { coordinates: XYPosition | null }) => void;
|
export type OnMapAddSystemCallback = (props: { coordinates: XYPosition | null }) => void;
|
||||||
|
|
||||||
|
export type MapViewport = { zoom: 1; x: 0; y: 0 };
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { saveTextFile } from '@/hooks/Mapper/utils/saveToFile.ts';
|
|||||||
import { SplitButton } from 'primereact/splitbutton';
|
import { SplitButton } from 'primereact/splitbutton';
|
||||||
import { loadTextFile } from '@/hooks/Mapper/utils';
|
import { loadTextFile } from '@/hooks/Mapper/utils';
|
||||||
import { applyMigrations } from '@/hooks/Mapper/mapRootProvider/migrations';
|
import { applyMigrations } from '@/hooks/Mapper/mapRootProvider/migrations';
|
||||||
|
import { createDefaultStoredSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultStoredSettings.ts';
|
||||||
|
|
||||||
export const ImportExport = () => {
|
export const ImportExport = () => {
|
||||||
const {
|
const {
|
||||||
@@ -25,7 +26,7 @@ export const ImportExport = () => {
|
|||||||
try {
|
try {
|
||||||
// INFO: WE NOT SUPPORT MIGRATIONS FOR OLD FILES AND Clipboard
|
// INFO: WE NOT SUPPORT MIGRATIONS FOR OLD FILES AND Clipboard
|
||||||
const parsed = parseMapUserSettings(text);
|
const parsed = parseMapUserSettings(text);
|
||||||
if (applySettings(applyMigrations(parsed))) {
|
if (applySettings(applyMigrations(parsed) || createDefaultStoredSettings())) {
|
||||||
toast.current?.show({
|
toast.current?.show({
|
||||||
severity: 'success',
|
severity: 'success',
|
||||||
summary: 'Import',
|
summary: 'Import',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { OutCommand } from '@/hooks/Mapper/types';
|
import { OutCommand } from '@/hooks/Mapper/types';
|
||||||
import { createDefaultWidgetSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultWidgetSettings.ts';
|
import { createDefaultStoredSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultStoredSettings.ts';
|
||||||
import { callToastSuccess } from '@/hooks/Mapper/helpers';
|
import { callToastSuccess } from '@/hooks/Mapper/helpers';
|
||||||
import { ConfirmPopup } from 'primereact/confirmpopup';
|
import { ConfirmPopup } from 'primereact/confirmpopup';
|
||||||
import { useConfirmPopup } from '@/hooks/Mapper/hooks';
|
import { useConfirmPopup } from '@/hooks/Mapper/hooks';
|
||||||
@@ -29,7 +29,7 @@ export const ServerSettings = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res?.default_settings == null) {
|
if (res?.default_settings == null) {
|
||||||
applySettings(createDefaultWidgetSettings());
|
applySettings(createDefaultStoredSettings());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export const ServerSettings = () => {
|
|||||||
applySettings(applyMigrations(JSON.parse(res.default_settings)));
|
applySettings(applyMigrations(JSON.parse(res.default_settings)));
|
||||||
callToastSuccess(toast.current, 'Settings synchronized successfully');
|
callToastSuccess(toast.current, 'Settings synchronized successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
applySettings(createDefaultWidgetSettings());
|
applySettings(createDefaultStoredSettings());
|
||||||
}
|
}
|
||||||
}, [applySettings, outCommand]);
|
}, [applySettings, outCommand]);
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { Connections } from '@/hooks/Mapper/components/mapRootContent/components
|
|||||||
import { ContextMenuSystemMultiple, useContextMenuSystemMultipleHandlers } from '../contexts/ContextMenuSystemMultiple';
|
import { ContextMenuSystemMultiple, useContextMenuSystemMultipleHandlers } from '../contexts/ContextMenuSystemMultiple';
|
||||||
import { getSystemById } from '@/hooks/Mapper/helpers';
|
import { getSystemById } from '@/hooks/Mapper/helpers';
|
||||||
import { Commands } from '@/hooks/Mapper/types/mapHandlers.ts';
|
import { Commands } from '@/hooks/Mapper/types/mapHandlers.ts';
|
||||||
import { Node, useReactFlow, XYPosition } from 'reactflow';
|
import { Node, useReactFlow, Viewport, XYPosition } from 'reactflow';
|
||||||
|
|
||||||
import { useCommandsSystems } from '@/hooks/Mapper/mapRootProvider/hooks/api';
|
import { useCommandsSystems } from '@/hooks/Mapper/mapRootProvider/hooks/api';
|
||||||
import { emitMapEvent, useMapEventListener } from '@/hooks/Mapper/events';
|
import { emitMapEvent, useMapEventListener } from '@/hooks/Mapper/events';
|
||||||
@@ -48,7 +48,7 @@ export const MapWrapper = () => {
|
|||||||
linkSignatureToSystem,
|
linkSignatureToSystem,
|
||||||
systemSignatures,
|
systemSignatures,
|
||||||
},
|
},
|
||||||
storedSettings: { interfaceSettings, settingsLocal },
|
storedSettings: { interfaceSettings, settingsLocal, mapSettings, mapSettingsUpdate },
|
||||||
} = useMapRootState();
|
} = useMapRootState();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -83,8 +83,17 @@ export const MapWrapper = () => {
|
|||||||
systems,
|
systems,
|
||||||
systemSignatures,
|
systemSignatures,
|
||||||
deleteSystems,
|
deleteSystems,
|
||||||
|
mapSettingsUpdate,
|
||||||
});
|
});
|
||||||
ref.current = { selectedConnections, selectedSystems, systemContextProps, systems, systemSignatures, deleteSystems };
|
ref.current = {
|
||||||
|
selectedConnections,
|
||||||
|
selectedSystems,
|
||||||
|
systemContextProps,
|
||||||
|
systems,
|
||||||
|
systemSignatures,
|
||||||
|
deleteSystems,
|
||||||
|
mapSettingsUpdate,
|
||||||
|
};
|
||||||
|
|
||||||
useMapEventListener(event => {
|
useMapEventListener(event => {
|
||||||
runCommand(event);
|
runCommand(event);
|
||||||
@@ -121,6 +130,10 @@ export const MapWrapper = () => {
|
|||||||
[update],
|
[update],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleChangeViewport = useCallback((viewport: Viewport) => {
|
||||||
|
ref.current.mapSettingsUpdate({ viewport });
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleCommand: OutCommandHandler = useCallback(
|
const handleCommand: OutCommandHandler = useCallback(
|
||||||
event => {
|
event => {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@@ -259,6 +272,7 @@ export const MapWrapper = () => {
|
|||||||
onConnectionInfoClick={handleConnectionDbClick}
|
onConnectionInfoClick={handleConnectionDbClick}
|
||||||
onSystemContextMenu={handleSystemContextMenu}
|
onSystemContextMenu={handleSystemContextMenu}
|
||||||
onSelectionContextMenu={handleSystemMultipleContext}
|
onSelectionContextMenu={handleSystemMultipleContext}
|
||||||
|
onChangeViewport={handleChangeViewport}
|
||||||
minimapClasses={minimapClasses}
|
minimapClasses={minimapClasses}
|
||||||
isShowMinimap={showMinimap}
|
isShowMinimap={showMinimap}
|
||||||
showKSpaceBG={isShowKSpace}
|
showKSpaceBG={isShowKSpace}
|
||||||
@@ -270,6 +284,7 @@ export const MapWrapper = () => {
|
|||||||
onAddSystem={onAddSystem}
|
onAddSystem={onAddSystem}
|
||||||
minimapPlacement={minimapPosition}
|
minimapPlacement={minimapPosition}
|
||||||
localShowShipName={settingsLocal.showShipName}
|
localShowShipName={settingsLocal.showShipName}
|
||||||
|
defaultViewport={mapSettings.viewport}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{openSettings != null && (
|
{openSettings != null && (
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ import {
|
|||||||
InterfaceStoredSettings,
|
InterfaceStoredSettings,
|
||||||
KillsWidgetSettings,
|
KillsWidgetSettings,
|
||||||
LocalWidgetSettings,
|
LocalWidgetSettings,
|
||||||
|
MapSettings,
|
||||||
MapUserSettings,
|
MapUserSettings,
|
||||||
OnTheMapSettingsType,
|
OnTheMapSettingsType,
|
||||||
RoutesType,
|
RoutesType,
|
||||||
} from '@/hooks/Mapper/mapRootProvider/types.ts';
|
} from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||||
import {
|
import {
|
||||||
DEFAULT_KILLS_WIDGET_SETTINGS,
|
DEFAULT_KILLS_WIDGET_SETTINGS,
|
||||||
|
DEFAULT_MAP_SETTINGS,
|
||||||
DEFAULT_ON_THE_MAP_SETTINGS,
|
DEFAULT_ON_THE_MAP_SETTINGS,
|
||||||
DEFAULT_ROUTES_SETTINGS,
|
DEFAULT_ROUTES_SETTINGS,
|
||||||
DEFAULT_WIDGET_LOCAL_SETTINGS,
|
DEFAULT_WIDGET_LOCAL_SETTINGS,
|
||||||
@@ -127,6 +129,8 @@ export interface MapRootContextProps {
|
|||||||
settingsOnTheMapUpdate: Dispatch<SetStateAction<OnTheMapSettingsType>>;
|
settingsOnTheMapUpdate: Dispatch<SetStateAction<OnTheMapSettingsType>>;
|
||||||
settingsKills: KillsWidgetSettings;
|
settingsKills: KillsWidgetSettings;
|
||||||
settingsKillsUpdate: Dispatch<SetStateAction<KillsWidgetSettings>>;
|
settingsKillsUpdate: Dispatch<SetStateAction<KillsWidgetSettings>>;
|
||||||
|
mapSettings: MapSettings;
|
||||||
|
mapSettingsUpdate: Dispatch<SetStateAction<MapSettings>>;
|
||||||
isReady: boolean;
|
isReady: boolean;
|
||||||
hasOldSettings: boolean;
|
hasOldSettings: boolean;
|
||||||
getSettingsForExport(): string | undefined;
|
getSettingsForExport(): string | undefined;
|
||||||
@@ -172,6 +176,8 @@ const MapRootContext = createContext<MapRootContextProps>({
|
|||||||
settingsOnTheMapUpdate: () => null,
|
settingsOnTheMapUpdate: () => null,
|
||||||
settingsKills: DEFAULT_KILLS_WIDGET_SETTINGS,
|
settingsKills: DEFAULT_KILLS_WIDGET_SETTINGS,
|
||||||
settingsKillsUpdate: () => null,
|
settingsKillsUpdate: () => null,
|
||||||
|
mapSettings: DEFAULT_MAP_SETTINGS,
|
||||||
|
mapSettingsUpdate: () => null,
|
||||||
isReady: false,
|
isReady: false,
|
||||||
hasOldSettings: false,
|
hasOldSettings: false,
|
||||||
getSettingsForExport: () => '',
|
getSettingsForExport: () => '',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
InterfaceStoredSettings,
|
InterfaceStoredSettings,
|
||||||
KillsWidgetSettings,
|
KillsWidgetSettings,
|
||||||
LocalWidgetSettings,
|
LocalWidgetSettings,
|
||||||
|
MapSettings,
|
||||||
MiniMapPlacement,
|
MiniMapPlacement,
|
||||||
OnTheMapSettingsType,
|
OnTheMapSettingsType,
|
||||||
PingsPlacement,
|
PingsPlacement,
|
||||||
@@ -53,6 +54,10 @@ export const DEFAULT_KILLS_WIDGET_SETTINGS: KillsWidgetSettings = {
|
|||||||
timeRange: 4,
|
timeRange: 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DEFAULT_MAP_SETTINGS: MapSettings = {
|
||||||
|
viewport: { zoom: 1, x: 0, y: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
export const getDefaultWidgetProps = () => ({
|
export const getDefaultWidgetProps = () => ({
|
||||||
visible: STORED_VISIBLE_WIDGETS_DEFAULT,
|
visible: STORED_VISIBLE_WIDGETS_DEFAULT,
|
||||||
windows: DEFAULT_WIDGETS,
|
windows: DEFAULT_WIDGETS,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MapUserSettings, SettingsTypes, SettingsWrapper } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
import { MapUserSettings, SettingsTypes, SettingsWrapper } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||||
import {
|
import {
|
||||||
DEFAULT_KILLS_WIDGET_SETTINGS,
|
DEFAULT_KILLS_WIDGET_SETTINGS,
|
||||||
|
DEFAULT_MAP_SETTINGS,
|
||||||
DEFAULT_ON_THE_MAP_SETTINGS,
|
DEFAULT_ON_THE_MAP_SETTINGS,
|
||||||
DEFAULT_ROUTES_SETTINGS,
|
DEFAULT_ROUTES_SETTINGS,
|
||||||
DEFAULT_WIDGET_LOCAL_SETTINGS,
|
DEFAULT_WIDGET_LOCAL_SETTINGS,
|
||||||
@@ -15,7 +16,7 @@ export const createWidgetSettings = <T>(settings: T) => {
|
|||||||
return settings;
|
return settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createDefaultWidgetSettings = (): MapUserSettings => {
|
export const createDefaultStoredSettings = (): MapUserSettings => {
|
||||||
return {
|
return {
|
||||||
version: STORED_SETTINGS_VERSION,
|
version: STORED_SETTINGS_VERSION,
|
||||||
migratedFromOld: true,
|
migratedFromOld: true,
|
||||||
@@ -26,6 +27,7 @@ export const createDefaultWidgetSettings = (): MapUserSettings => {
|
|||||||
onTheMap: createWidgetSettings(DEFAULT_ON_THE_MAP_SETTINGS),
|
onTheMap: createWidgetSettings(DEFAULT_ON_THE_MAP_SETTINGS),
|
||||||
signaturesWidget: createWidgetSettings(DEFAULT_SIGNATURE_SETTINGS),
|
signaturesWidget: createWidgetSettings(DEFAULT_SIGNATURE_SETTINGS),
|
||||||
interface: createWidgetSettings(STORED_INTERFACE_DEFAULT_VALUES),
|
interface: createWidgetSettings(STORED_INTERFACE_DEFAULT_VALUES),
|
||||||
|
map: createWidgetSettings(DEFAULT_MAP_SETTINGS),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,5 +49,7 @@ export const getDefaultSettingsByType = (type: SettingsTypes): SettingsWrapper<a
|
|||||||
return createWidgetSettings(DEFAULT_SIGNATURE_SETTINGS);
|
return createWidgetSettings(DEFAULT_SIGNATURE_SETTINGS);
|
||||||
case SettingsTypes.interface:
|
case SettingsTypes.interface:
|
||||||
return createWidgetSettings(STORED_INTERFACE_DEFAULT_VALUES);
|
return createWidgetSettings(STORED_INTERFACE_DEFAULT_VALUES);
|
||||||
|
case SettingsTypes.map:
|
||||||
|
return createWidgetSettings(DEFAULT_MAP_SETTINGS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
MapUserSettingsStructure,
|
MapUserSettingsStructure,
|
||||||
RemoteAdminSettingsResponse,
|
RemoteAdminSettingsResponse,
|
||||||
} from '@/hooks/Mapper/mapRootProvider/types.ts';
|
} from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||||
import { createDefaultWidgetSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultWidgetSettings.ts';
|
import { createDefaultStoredSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultStoredSettings.ts';
|
||||||
import { applyMigrations } from '@/hooks/Mapper/mapRootProvider/migrations';
|
import { applyMigrations } from '@/hooks/Mapper/mapRootProvider/migrations';
|
||||||
|
|
||||||
interface UseActualizeRemoteMapSettingsProps {
|
interface UseActualizeRemoteMapSettingsProps {
|
||||||
@@ -37,14 +37,14 @@ export const useActualizeRemoteMapSettings = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res?.default_settings == null) {
|
if (res?.default_settings == null) {
|
||||||
applySettings(createDefaultWidgetSettings());
|
applySettings(createDefaultStoredSettings());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
applySettings(applyMigrations(JSON.parse(res.default_settings)));
|
applySettings(applyMigrations(JSON.parse(res.default_settings)));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
applySettings(createDefaultWidgetSettings());
|
applySettings(createDefaultStoredSettings());
|
||||||
}
|
}
|
||||||
}, [outCommand]);
|
}, [outCommand]);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { useSettingsValueAndSetter } from '@/hooks/Mapper/mapRootProvider/hooks/
|
|||||||
import fastDeepEqual from 'fast-deep-equal';
|
import fastDeepEqual from 'fast-deep-equal';
|
||||||
import { OutCommandHandler } from '@/hooks/Mapper/types';
|
import { OutCommandHandler } from '@/hooks/Mapper/types';
|
||||||
import { useActualizeRemoteMapSettings } from '@/hooks/Mapper/mapRootProvider/hooks/useActualizeRemoteMapSettings.ts';
|
import { useActualizeRemoteMapSettings } from '@/hooks/Mapper/mapRootProvider/hooks/useActualizeRemoteMapSettings.ts';
|
||||||
import { createDefaultWidgetSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultWidgetSettings.ts';
|
import { createDefaultStoredSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultStoredSettings.ts';
|
||||||
import { applyMigrations, extractData } from '@/hooks/Mapper/mapRootProvider/migrations';
|
import { applyMigrations, extractData } from '@/hooks/Mapper/mapRootProvider/migrations';
|
||||||
import { LS_KEY, LS_KEY_LEGASY } from '@/hooks/Mapper/mapRootProvider/version.ts';
|
import { LS_KEY, LS_KEY_LEGASY } from '@/hooks/Mapper/mapRootProvider/version.ts';
|
||||||
|
|
||||||
@@ -85,13 +85,20 @@ export const useMapUserSettings = ({ map_slug }: MapRootData, outCommand: OutCom
|
|||||||
'killsWidget',
|
'killsWidget',
|
||||||
);
|
);
|
||||||
|
|
||||||
const [windowsSettings, setWindowsSettings] = useSettingsValueAndSetter(
|
const [windowsSettings, windowsSettingsUpdate] = useSettingsValueAndSetter(
|
||||||
mapUserSettings,
|
mapUserSettings,
|
||||||
setMapUserSettings,
|
setMapUserSettings,
|
||||||
map_slug,
|
map_slug,
|
||||||
'widgets',
|
'widgets',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [mapSettings, mapSettingsUpdate] = useSettingsValueAndSetter(
|
||||||
|
mapUserSettings,
|
||||||
|
setMapUserSettings,
|
||||||
|
map_slug,
|
||||||
|
'map',
|
||||||
|
);
|
||||||
|
|
||||||
// HERE we MUST work with migrations
|
// HERE we MUST work with migrations
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isReady) {
|
if (isReady) {
|
||||||
@@ -151,7 +158,7 @@ export const useMapUserSettings = ({ map_slug }: MapRootData, outCommand: OutCom
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const resetSettings = useCallback(() => {
|
const resetSettings = useCallback(() => {
|
||||||
applySettings(createDefaultWidgetSettings());
|
applySettings(createDefaultStoredSettings());
|
||||||
}, [applySettings]);
|
}, [applySettings]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -171,7 +178,9 @@ export const useMapUserSettings = ({ map_slug }: MapRootData, outCommand: OutCom
|
|||||||
settingsKills,
|
settingsKills,
|
||||||
settingsKillsUpdate,
|
settingsKillsUpdate,
|
||||||
windowsSettings,
|
windowsSettings,
|
||||||
setWindowsSettings,
|
windowsSettingsUpdate,
|
||||||
|
mapSettings,
|
||||||
|
mapSettingsUpdate,
|
||||||
|
|
||||||
getSettingsForExport,
|
getSettingsForExport,
|
||||||
applySettings,
|
applySettings,
|
||||||
|
|||||||
@@ -15,17 +15,17 @@ export type ToggleWidgetVisibility = (widgetId: WidgetsIds) => void;
|
|||||||
|
|
||||||
interface UseStoreWidgetsProps {
|
interface UseStoreWidgetsProps {
|
||||||
windowsSettings: WindowStoreInfo;
|
windowsSettings: WindowStoreInfo;
|
||||||
setWindowsSettings: Dispatch<SetStateAction<WindowStoreInfo>>;
|
windowsSettingsUpdate: Dispatch<SetStateAction<WindowStoreInfo>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useStoreWidgets = ({ windowsSettings, setWindowsSettings }: UseStoreWidgetsProps) => {
|
export const useStoreWidgets = ({ windowsSettings, windowsSettingsUpdate }: UseStoreWidgetsProps) => {
|
||||||
const ref = useRef({ windowsSettings, setWindowsSettings });
|
const ref = useRef({ windowsSettings, windowsSettingsUpdate });
|
||||||
ref.current = { windowsSettings, setWindowsSettings };
|
ref.current = { windowsSettings, windowsSettingsUpdate };
|
||||||
|
|
||||||
const updateWidgetSettings: WindowsManagerOnChange = useCallback(({ windows, viewPort }) => {
|
const updateWidgetSettings: WindowsManagerOnChange = useCallback(({ windows, viewPort }) => {
|
||||||
const { setWindowsSettings } = ref.current;
|
const { windowsSettingsUpdate } = ref.current;
|
||||||
|
|
||||||
setWindowsSettings(({ visible /*, windows*/ }: WindowStoreInfo) => {
|
windowsSettingsUpdate(({ visible /*, windows*/ }: WindowStoreInfo) => {
|
||||||
return {
|
return {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
windows: DEFAULT_WIDGETS.map(({ content, ...x }) => {
|
windows: DEFAULT_WIDGETS.map(({ content, ...x }) => {
|
||||||
@@ -43,9 +43,9 @@ export const useStoreWidgets = ({ windowsSettings, setWindowsSettings }: UseStor
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const toggleWidgetVisibility: ToggleWidgetVisibility = useCallback(widgetId => {
|
const toggleWidgetVisibility: ToggleWidgetVisibility = useCallback(widgetId => {
|
||||||
const { setWindowsSettings } = ref.current;
|
const { windowsSettingsUpdate } = ref.current;
|
||||||
|
|
||||||
setWindowsSettings(({ visible, windows, ...x }) => {
|
windowsSettingsUpdate(({ visible, windows, ...x }) => {
|
||||||
const isCheckedPrev = visible.includes(widgetId);
|
const isCheckedPrev = visible.includes(widgetId);
|
||||||
if (!isCheckedPrev) {
|
if (!isCheckedPrev) {
|
||||||
const maxZIndex = Math.max(...windows.map(w => w.zIndex));
|
const maxZIndex = Math.max(...windows.map(w => w.zIndex));
|
||||||
@@ -70,7 +70,7 @@ export const useStoreWidgets = ({ windowsSettings, setWindowsSettings }: UseStor
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const resetWidgets = useCallback(() => ref.current.setWindowsSettings(getDefaultWidgetProps()), []);
|
const resetWidgets = useCallback(() => ref.current.windowsSettingsUpdate(getDefaultWidgetProps()), []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
windowsSettings,
|
windowsSettings,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MapUserSettingsStructure } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
import { MapUserSettingsStructure } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||||
import { STORED_SETTINGS_VERSION } from '@/hooks/Mapper/mapRootProvider/version.ts';
|
import { STORED_SETTINGS_VERSION } from '@/hooks/Mapper/mapRootProvider/version.ts';
|
||||||
import { migrations } from '@/hooks/Mapper/mapRootProvider/migrations/index.ts';
|
import { migrations } from '@/hooks/Mapper/mapRootProvider/migrations/index.ts';
|
||||||
|
import { createDefaultStoredSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultStoredSettings.ts';
|
||||||
|
|
||||||
export const extractData = (localStoreKey = 'map-user-settings'): MapUserSettingsStructure | null => {
|
export const extractData = (localStoreKey = 'map-user-settings'): MapUserSettingsStructure | null => {
|
||||||
const val = localStorage.getItem(localStoreKey);
|
const val = localStorage.getItem(localStoreKey);
|
||||||
@@ -28,28 +29,29 @@ export const applyMigrations = (mapSettings: any) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade
|
const cmVersion = currentMapSettings.version || 0;
|
||||||
if (direction > 0) {
|
|
||||||
const preparedMigrations = migrations.sort((a, b) => a.to - b.to).filter(x => x.to <= STORED_SETTINGS_VERSION);
|
|
||||||
|
|
||||||
for (const migration of preparedMigrations) {
|
// downgrade
|
||||||
const { to, up } = migration;
|
// INFO: when we downgrading - if diff between >= 1 it means was major version
|
||||||
|
if (direction < 0) {
|
||||||
const next = up(currentMapSettings);
|
// If was minor version - we do nothing
|
||||||
currentMapSettings = { ...next, version: to, migratedFromOld: true };
|
if (Math.abs(direction) < 1) {
|
||||||
|
return currentMapSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentMapSettings;
|
// if was major version - we set default settings
|
||||||
|
return createDefaultStoredSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOWNGRADE
|
const preparedMigrations = migrations
|
||||||
const preparedMigrations = migrations.sort((a, b) => b.to - a.to).filter(x => x.to - 1 >= STORED_SETTINGS_VERSION);
|
.sort((a, b) => a.to - b.to)
|
||||||
|
.filter(x => x.to > cmVersion && x.to <= STORED_SETTINGS_VERSION);
|
||||||
|
|
||||||
for (const migration of preparedMigrations) {
|
for (const migration of preparedMigrations) {
|
||||||
const { to, down } = migration;
|
const { to, up } = migration;
|
||||||
|
|
||||||
const next = down(currentMapSettings);
|
const next = up(currentMapSettings);
|
||||||
currentMapSettings = { ...next, version: to - 1, migratedFromOld: true };
|
currentMapSettings = { ...next, version: to, migratedFromOld: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentMapSettings;
|
return currentMapSettings;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { to_1 } from './to_1.ts';
|
import { to_1 } from './to_1.ts';
|
||||||
|
import { to_2 } from './to_2.ts';
|
||||||
import { MigrationStructure } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
import { MigrationStructure } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||||
|
|
||||||
export default [to_1 /*to_2, to_3*/] as MigrationStructure[];
|
export default [to_1, to_2] as MigrationStructure[];
|
||||||
|
|||||||
@@ -7,9 +7,4 @@ export const to_1: MigrationStructure = {
|
|||||||
return { ...acc, [k]: prev[k].settings };
|
return { ...acc, [k]: prev[k].settings };
|
||||||
}, Object.create(null));
|
}, Object.create(null));
|
||||||
},
|
},
|
||||||
down: (prev: any) => {
|
|
||||||
return Object.keys(prev).reduce((acc, k) => {
|
|
||||||
return { ...acc, [k]: { version: 0, settings: prev[k] } };
|
|
||||||
}, Object.create(null));
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { MigrationStructure } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||||
|
|
||||||
|
const IN_V1_STORE_KEY = 'viewPort';
|
||||||
|
const IN_V1_DEFAULT_VIEWPORT = { zoom: 1, x: 0, y: 0 };
|
||||||
|
|
||||||
|
export const to_2: MigrationStructure = {
|
||||||
|
to: 2,
|
||||||
|
up: (prev: any) => {
|
||||||
|
const restored = localStorage.getItem(IN_V1_STORE_KEY);
|
||||||
|
let current = IN_V1_DEFAULT_VIEWPORT;
|
||||||
|
if (restored != null) {
|
||||||
|
try {
|
||||||
|
current = JSON.parse(restored);
|
||||||
|
} catch (err) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.removeItem(IN_V1_STORE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
map: {
|
||||||
|
viewport: current,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -64,6 +64,12 @@ export type KillsWidgetSettings = {
|
|||||||
timeRange: number;
|
timeRange: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MapViewPort = { zoom: number; x: number; y: number };
|
||||||
|
|
||||||
|
export type MapSettings = {
|
||||||
|
viewport: MapViewPort;
|
||||||
|
};
|
||||||
|
|
||||||
export type SettingsWrapper<T> = T;
|
export type SettingsWrapper<T> = T;
|
||||||
|
|
||||||
export type MapUserSettings = {
|
export type MapUserSettings = {
|
||||||
@@ -76,6 +82,7 @@ export type MapUserSettings = {
|
|||||||
localWidget: SettingsWrapper<LocalWidgetSettings>;
|
localWidget: SettingsWrapper<LocalWidgetSettings>;
|
||||||
signaturesWidget: SettingsWrapper<SignatureSettingsType>;
|
signaturesWidget: SettingsWrapper<SignatureSettingsType>;
|
||||||
killsWidget: SettingsWrapper<KillsWidgetSettings>;
|
killsWidget: SettingsWrapper<KillsWidgetSettings>;
|
||||||
|
map: SettingsWrapper<MapSettings>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MapUserSettingsStructure = {
|
export type MapUserSettingsStructure = {
|
||||||
@@ -94,11 +101,11 @@ export enum SettingsTypes {
|
|||||||
onTheMap = 'onTheMap',
|
onTheMap = 'onTheMap',
|
||||||
signaturesWidget = 'signaturesWidget',
|
signaturesWidget = 'signaturesWidget',
|
||||||
interface = 'interface',
|
interface = 'interface',
|
||||||
|
map = 'map',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MigrationFunc = (prev: any) => any;
|
export type MigrationFunc = (prev: any) => any;
|
||||||
export type MigrationStructure = {
|
export type MigrationStructure = {
|
||||||
to: number;
|
to: number;
|
||||||
up: MigrationFunc;
|
up: MigrationFunc;
|
||||||
down: MigrationFunc;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export const STORED_SETTINGS_VERSION = 1;
|
export const STORED_SETTINGS_VERSION = 2;
|
||||||
|
|
||||||
export const LS_KEY_LEGASY = 'map-user-settings';
|
export const LS_KEY_LEGASY = 'map-user-settings';
|
||||||
export const LS_KEY = 'map-user-settings-v2';
|
export const LS_KEY = 'map-user-settings-v2';
|
||||||
|
|||||||
Reference in New Issue
Block a user