mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 02:35:42 +00:00
fix(Map): Remote map setting refactoring
This commit is contained in:
@@ -131,6 +131,7 @@ export interface MapRootContextProps {
|
||||
hasOldSettings: boolean;
|
||||
getSettingsForExport(): string | undefined;
|
||||
applySettings(settings: MapUserSettings): boolean;
|
||||
resetSettings(settings: MapUserSettings): void;
|
||||
checkOldSettings(): void;
|
||||
};
|
||||
}
|
||||
@@ -175,6 +176,7 @@ const MapRootContext = createContext<MapRootContextProps>({
|
||||
hasOldSettings: false,
|
||||
getSettingsForExport: () => '',
|
||||
applySettings: () => false,
|
||||
resetSettings: () => null,
|
||||
checkOldSettings: () => null,
|
||||
},
|
||||
});
|
||||
@@ -196,7 +198,7 @@ const MapRootHandlers = forwardRef(({ children }: WithChildren, fwdRef: Forwarde
|
||||
export const MapRootProvider = ({ children, fwdRef, outCommand }: MapRootProviderProps) => {
|
||||
const { update, ref } = useContextStore<MapRootData>({ ...INITIAL_DATA });
|
||||
|
||||
const storedSettings = useMapUserSettings({ ...ref, outCommand });
|
||||
const storedSettings = useMapUserSettings(ref, outCommand);
|
||||
|
||||
const { windowsSettings, toggleWidgetVisibility, updateWidgetSettings, resetWidgets } =
|
||||
useStoreWidgets(storedSettings);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { MapUserSettings } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||
import {
|
||||
DEFAULT_KILLS_WIDGET_SETTINGS,
|
||||
DEFAULT_ON_THE_MAP_SETTINGS,
|
||||
DEFAULT_ROUTES_SETTINGS,
|
||||
DEFAULT_WIDGET_LOCAL_SETTINGS,
|
||||
getDefaultWidgetProps,
|
||||
STORED_INTERFACE_DEFAULT_VALUES,
|
||||
} from '@/hooks/Mapper/mapRootProvider/constants.ts';
|
||||
import { DEFAULT_SIGNATURE_SETTINGS } from '@/hooks/Mapper/constants/signatures.ts';
|
||||
|
||||
// TODO - we need provide and compare version
|
||||
const createWidgetSettingsWithVersion = <T>(settings: T) => {
|
||||
return {
|
||||
version: 0,
|
||||
settings,
|
||||
};
|
||||
};
|
||||
|
||||
export const createDefaultWidgetSettings = (): MapUserSettings => {
|
||||
return {
|
||||
killsWidget: createWidgetSettingsWithVersion(DEFAULT_KILLS_WIDGET_SETTINGS),
|
||||
localWidget: createWidgetSettingsWithVersion(DEFAULT_WIDGET_LOCAL_SETTINGS),
|
||||
widgets: createWidgetSettingsWithVersion(getDefaultWidgetProps()),
|
||||
routes: createWidgetSettingsWithVersion(DEFAULT_ROUTES_SETTINGS),
|
||||
onTheMap: createWidgetSettingsWithVersion(DEFAULT_ON_THE_MAP_SETTINGS),
|
||||
signaturesWidget: createWidgetSettingsWithVersion(DEFAULT_SIGNATURE_SETTINGS),
|
||||
interface: createWidgetSettingsWithVersion(STORED_INTERFACE_DEFAULT_VALUES),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import { OutCommand, OutCommandHandler } from '@/hooks/Mapper/types';
|
||||
import { Dispatch, SetStateAction, useCallback, useEffect, useRef } from 'react';
|
||||
import {
|
||||
MapUserSettings,
|
||||
MapUserSettingsStructure,
|
||||
RemoteAdminSettingsResponse,
|
||||
} from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||
import { createDefaultWidgetSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultWidgetSettings.ts';
|
||||
import { parseMapUserSettings } from '@/hooks/Mapper/components/helpers';
|
||||
|
||||
interface UseActualizeRemoteMapSettingsProps {
|
||||
outCommand: OutCommandHandler;
|
||||
mapUserSettings: MapUserSettingsStructure;
|
||||
applySettings: (val: MapUserSettings) => void;
|
||||
setMapUserSettings: Dispatch<SetStateAction<MapUserSettingsStructure>>;
|
||||
map_slug: string | null;
|
||||
}
|
||||
|
||||
export const useActualizeRemoteMapSettings = ({
|
||||
outCommand,
|
||||
mapUserSettings,
|
||||
setMapUserSettings,
|
||||
applySettings,
|
||||
map_slug,
|
||||
}: UseActualizeRemoteMapSettingsProps) => {
|
||||
const refVars = useRef({ applySettings, mapUserSettings, setMapUserSettings, map_slug });
|
||||
refVars.current = { applySettings, mapUserSettings, setMapUserSettings, map_slug };
|
||||
|
||||
const actualizeRemoteMapSettings = useCallback(async () => {
|
||||
const { applySettings } = refVars.current;
|
||||
|
||||
let res: RemoteAdminSettingsResponse | undefined;
|
||||
try {
|
||||
res = await outCommand({ type: OutCommand.getDefaultSettings, data: null });
|
||||
} catch (error) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (res?.default_settings == null) {
|
||||
applySettings(createDefaultWidgetSettings());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
applySettings(parseMapUserSettings(res.default_settings));
|
||||
} catch (error) {
|
||||
applySettings(createDefaultWidgetSettings());
|
||||
}
|
||||
}, [outCommand]);
|
||||
|
||||
useEffect(() => {
|
||||
const { mapUserSettings } = refVars.current;
|
||||
|
||||
// INFO: Do nothing if slug is not set
|
||||
if (map_slug == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// INFO: Do nothing if user have already data
|
||||
if (map_slug in mapUserSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
actualizeRemoteMapSettings();
|
||||
}, [actualizeRemoteMapSettings, map_slug]);
|
||||
};
|
||||
@@ -1,129 +1,45 @@
|
||||
import useLocalStorageState from 'use-local-storage-state';
|
||||
import { MapUserSettings, MapUserSettingsStructure } from '@/hooks/Mapper/mapRootProvider/types.ts';
|
||||
import {
|
||||
DEFAULT_KILLS_WIDGET_SETTINGS,
|
||||
DEFAULT_ON_THE_MAP_SETTINGS,
|
||||
DEFAULT_ROUTES_SETTINGS,
|
||||
DEFAULT_WIDGET_LOCAL_SETTINGS,
|
||||
getDefaultWidgetProps,
|
||||
STORED_INTERFACE_DEFAULT_VALUES,
|
||||
} from '@/hooks/Mapper/mapRootProvider/constants.ts';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { DEFAULT_SIGNATURE_SETTINGS } from '@/hooks/Mapper/constants/signatures';
|
||||
import { MapRootData } from '@/hooks/Mapper/mapRootProvider';
|
||||
import { useSettingsValueAndSetter } from '@/hooks/Mapper/mapRootProvider/hooks/useSettingsValueAndSetter.ts';
|
||||
import fastDeepEqual from 'fast-deep-equal';
|
||||
import { parseMapUserSettings } from '@/hooks/Mapper/components/helpers';
|
||||
|
||||
// import { actualizeSettings } from '@/hooks/Mapper/mapRootProvider/helpers';
|
||||
|
||||
// TODO - we need provide and compare version
|
||||
const createWidgetSettingsWithVersion = <T>(settings: T) => {
|
||||
return {
|
||||
version: 0,
|
||||
settings,
|
||||
};
|
||||
};
|
||||
|
||||
const createDefaultWidgetSettings = (): MapUserSettings => {
|
||||
return {
|
||||
killsWidget: createWidgetSettingsWithVersion(DEFAULT_KILLS_WIDGET_SETTINGS),
|
||||
localWidget: createWidgetSettingsWithVersion(DEFAULT_WIDGET_LOCAL_SETTINGS),
|
||||
widgets: createWidgetSettingsWithVersion(getDefaultWidgetProps()),
|
||||
routes: createWidgetSettingsWithVersion(DEFAULT_ROUTES_SETTINGS),
|
||||
onTheMap: createWidgetSettingsWithVersion(DEFAULT_ON_THE_MAP_SETTINGS),
|
||||
signaturesWidget: createWidgetSettingsWithVersion(DEFAULT_SIGNATURE_SETTINGS),
|
||||
interface: createWidgetSettingsWithVersion(STORED_INTERFACE_DEFAULT_VALUES),
|
||||
};
|
||||
};
|
||||
|
||||
// Helper function to validate map settings structure
|
||||
const validateMapSettings = (settings: any): boolean => {
|
||||
if (!settings || typeof settings !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for required top-level properties
|
||||
const requiredProps = ['killsWidget', 'localWidget', 'widgets', 'routes', 'onTheMap', 'signaturesWidget', 'interface'];
|
||||
return requiredProps.every(prop => prop in settings);
|
||||
};
|
||||
import { OutCommandHandler } from '@/hooks/Mapper/types';
|
||||
import { useActualizeRemoteMapSettings } from '@/hooks/Mapper/mapRootProvider/hooks/useActualizeRemoteMapSettings.ts';
|
||||
import { createDefaultWidgetSettings } from '@/hooks/Mapper/mapRootProvider/helpers/createDefaultWidgetSettings.ts';
|
||||
|
||||
const EMPTY_OBJ = {};
|
||||
|
||||
export const useMapUserSettings = ({ map_slug, outCommand }: MapRootData & { outCommand?: any }) => {
|
||||
export const useMapUserSettings = ({ map_slug }: MapRootData, outCommand: OutCommandHandler) => {
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const [hasOldSettings, setHasOldSettings] = useState(false);
|
||||
const [defaultSettingsLoaded, setDefaultSettingsLoaded] = useState(false);
|
||||
|
||||
const [mapUserSettings, setMapUserSettings] = useLocalStorageState<MapUserSettingsStructure>('map-user-settings', {
|
||||
defaultValue: EMPTY_OBJ,
|
||||
});
|
||||
|
||||
const ref = useRef({ mapUserSettings, setMapUserSettings, map_slug, outCommand });
|
||||
ref.current = { mapUserSettings, setMapUserSettings, map_slug, outCommand };
|
||||
const ref = useRef({ mapUserSettings, setMapUserSettings, map_slug });
|
||||
ref.current = { mapUserSettings, setMapUserSettings, map_slug };
|
||||
|
||||
useEffect(() => {
|
||||
const { mapUserSettings, setMapUserSettings, outCommand } = ref.current;
|
||||
if (map_slug === null) {
|
||||
return;
|
||||
const applySettings = useCallback((settings: MapUserSettings) => {
|
||||
const { map_slug, mapUserSettings, setMapUserSettings } = ref.current;
|
||||
|
||||
if (map_slug == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(map_slug in mapUserSettings) && !defaultSettingsLoaded) {
|
||||
// Try to load default settings from server first
|
||||
if (outCommand) {
|
||||
setDefaultSettingsLoaded(true);
|
||||
outCommand({
|
||||
type: 'get_default_settings',
|
||||
data: null,
|
||||
}).then((response: any) => {
|
||||
if (response?.default_settings) {
|
||||
try {
|
||||
const parsedSettings = parseMapUserSettings(response.default_settings);
|
||||
// Additional validation to ensure we have valid settings
|
||||
if (validateMapSettings(parsedSettings)) {
|
||||
setMapUserSettings({
|
||||
...mapUserSettings,
|
||||
[map_slug]: parsedSettings,
|
||||
});
|
||||
} else {
|
||||
// Invalid settings structure, use defaults
|
||||
console.error('Default settings from server have invalid structure');
|
||||
setMapUserSettings({
|
||||
...mapUserSettings,
|
||||
[map_slug]: createDefaultWidgetSettings(),
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// If parsing fails, use default settings
|
||||
console.error('Failed to parse default settings from server:', e);
|
||||
setMapUserSettings({
|
||||
...mapUserSettings,
|
||||
[map_slug]: createDefaultWidgetSettings(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// No default settings from server, use local defaults
|
||||
setMapUserSettings({
|
||||
...mapUserSettings,
|
||||
[map_slug]: createDefaultWidgetSettings(),
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
// Error loading from server, use local defaults
|
||||
setMapUserSettings({
|
||||
...mapUserSettings,
|
||||
[map_slug]: createDefaultWidgetSettings(),
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// No outCommand available, use local defaults
|
||||
setMapUserSettings({
|
||||
...mapUserSettings,
|
||||
[map_slug]: createDefaultWidgetSettings(),
|
||||
});
|
||||
}
|
||||
if (fastDeepEqual(settings, mapUserSettings[map_slug])) {
|
||||
return false;
|
||||
}
|
||||
}, [map_slug, defaultSettingsLoaded]);
|
||||
|
||||
setMapUserSettings(old => ({
|
||||
...old,
|
||||
[map_slug]: settings,
|
||||
}));
|
||||
return true;
|
||||
}, []);
|
||||
|
||||
useActualizeRemoteMapSettings({ outCommand, applySettings, mapUserSettings, setMapUserSettings, map_slug });
|
||||
|
||||
const [interfaceSettings, setInterfaceSettings] = useSettingsValueAndSetter(
|
||||
mapUserSettings,
|
||||
@@ -240,23 +156,9 @@ export const useMapUserSettings = ({ map_slug, outCommand }: MapRootData & { out
|
||||
return JSON.stringify(ref.current.mapUserSettings[map_slug]);
|
||||
}, []);
|
||||
|
||||
const applySettings = useCallback((settings: MapUserSettings) => {
|
||||
const { map_slug, mapUserSettings, setMapUserSettings } = ref.current;
|
||||
|
||||
if (map_slug == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fastDeepEqual(settings, mapUserSettings[map_slug])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setMapUserSettings(old => ({
|
||||
...old,
|
||||
[map_slug]: settings,
|
||||
}));
|
||||
return true;
|
||||
}, []);
|
||||
const resetSettings = useCallback(() => {
|
||||
applySettings(createDefaultWidgetSettings());
|
||||
}, [applySettings]);
|
||||
|
||||
return {
|
||||
isReady,
|
||||
@@ -279,6 +181,7 @@ export const useMapUserSettings = ({ map_slug, outCommand }: MapRootData & { out
|
||||
|
||||
getSettingsForExport,
|
||||
applySettings,
|
||||
resetSettings,
|
||||
checkOldSettings,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -85,3 +85,7 @@ export type MapUserSettings = {
|
||||
export type MapUserSettingsStructure = {
|
||||
[mapId: string]: MapUserSettings;
|
||||
};
|
||||
|
||||
export type WdResponse<T> = T;
|
||||
|
||||
export type RemoteAdminSettingsResponse = { default_settings?: string };
|
||||
|
||||
Reference in New Issue
Block a user