mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-09 17:25:38 +00:00
fix(Map): New windows systems
This commit is contained in:
@@ -1,48 +1,11 @@
|
|||||||
import 'react-grid-layout/css/styles.css';
|
import 'react-grid-layout/css/styles.css';
|
||||||
import 'react-resizable/css/styles.css';
|
import 'react-resizable/css/styles.css';
|
||||||
import {
|
import { useMemo, useState } from 'react';
|
||||||
LocalCharacters,
|
|
||||||
RoutesWidget,
|
|
||||||
SystemInfo,
|
|
||||||
SystemSignatures,
|
|
||||||
} from '@/hooks/Mapper/components/mapInterface/widgets';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { SESSION_KEY } from '@/hooks/Mapper/constants.ts';
|
import { SESSION_KEY } from '@/hooks/Mapper/constants.ts';
|
||||||
import { WindowManager } from '@/hooks/Mapper/components/ui-kit/WindowManager';
|
import { WindowManager } from '@/hooks/Mapper/components/ui-kit/WindowManager';
|
||||||
import { WindowProps } from '@/hooks/Mapper/components/ui-kit/WindowManager/types.ts';
|
import { WindowProps } from '@/hooks/Mapper/components/ui-kit/WindowManager/types.ts';
|
||||||
|
import { CURRENT_WINDOWS_VERSION, DEFAULT_WIDGETS } from '@/hooks/Mapper/components/mapInterface/constants.tsx';
|
||||||
const CURRENT_WINDOWS_VERSION = 2;
|
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||||
|
|
||||||
const DEFAULT: WindowProps[] = [
|
|
||||||
{
|
|
||||||
id: 'info',
|
|
||||||
position: { x: 10, y: 10 },
|
|
||||||
size: { width: 250, height: 200 },
|
|
||||||
zIndex: 0,
|
|
||||||
content: () => <SystemInfo />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'signatures',
|
|
||||||
position: { x: 10, y: 220 },
|
|
||||||
size: { width: 250, height: 300 },
|
|
||||||
zIndex: 0,
|
|
||||||
content: () => <SystemSignatures />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'local',
|
|
||||||
position: { x: 270, y: 10 },
|
|
||||||
size: { width: 250, height: 510 },
|
|
||||||
zIndex: 0,
|
|
||||||
content: () => <LocalCharacters />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'routes',
|
|
||||||
position: { x: 10, y: 530 },
|
|
||||||
size: { width: 510, height: 200 },
|
|
||||||
zIndex: 0,
|
|
||||||
content: () => <RoutesWidget />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
type WindowsLS = {
|
type WindowsLS = {
|
||||||
windows: WindowProps[];
|
windows: WindowProps[];
|
||||||
@@ -60,19 +23,19 @@ const restoreWindowsFromLS = (): WindowProps[] => {
|
|||||||
const raw = localStorage.getItem(SESSION_KEY.windows);
|
const raw = localStorage.getItem(SESSION_KEY.windows);
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
console.warn('No windows found in local storage!!');
|
console.warn('No windows found in local storage!!');
|
||||||
return DEFAULT;
|
return DEFAULT_WIDGETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { version, windows } = JSON.parse(raw) as WindowsLS;
|
const { version, windows } = JSON.parse(raw) as WindowsLS;
|
||||||
if (!version || CURRENT_WINDOWS_VERSION > version) {
|
if (!version || CURRENT_WINDOWS_VERSION > version) {
|
||||||
return DEFAULT;
|
return DEFAULT_WIDGETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-debugger
|
// eslint-disable-next-line no-debugger
|
||||||
const out = (windows as Omit<WindowProps, 'content'>[])
|
const out = (windows as Omit<WindowProps, 'content'>[])
|
||||||
.filter(x => DEFAULT.find(def => def.id === x.id))
|
.filter(x => DEFAULT_WIDGETS.find(def => def.id === x.id))
|
||||||
.map(x => {
|
.map(x => {
|
||||||
const content = DEFAULT.find(def => def.id === x.id)?.content;
|
const content = DEFAULT_WIDGETS.find(def => def.id === x.id)?.content;
|
||||||
return { ...x, content: content! };
|
return { ...x, content: content! };
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -81,10 +44,15 @@ const restoreWindowsFromLS = (): WindowProps[] => {
|
|||||||
|
|
||||||
export const MapInterface = () => {
|
export const MapInterface = () => {
|
||||||
const [items, setItems] = useState<WindowProps[]>(restoreWindowsFromLS);
|
const [items, setItems] = useState<WindowProps[]>(restoreWindowsFromLS);
|
||||||
|
const { windowsVisible } = useMapRootState();
|
||||||
|
|
||||||
|
const itemsFiltered = useMemo(() => {
|
||||||
|
return items.filter(x => windowsVisible.some(j => x.id === j));
|
||||||
|
}, [items, windowsVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WindowManager
|
<WindowManager
|
||||||
windows={items}
|
windows={itemsFiltered}
|
||||||
dragSelector=".react-grid-dragHandleExample"
|
dragSelector=".react-grid-dragHandleExample"
|
||||||
onChange={x => {
|
onChange={x => {
|
||||||
saveWindowsToLS(x);
|
saveWindowsToLS(x);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
export * from './Widget';
|
export * from './Widget';
|
||||||
export * from './WidgetsGrid';
|
|
||||||
export * from './SystemSettingsDialog';
|
export * from './SystemSettingsDialog';
|
||||||
export * from './SystemCustomLabelDialog';
|
export * from './SystemCustomLabelDialog';
|
||||||
export * from './SystemLinkSignatureDialog';
|
export * from './SystemLinkSignatureDialog';
|
||||||
|
|||||||
71
assets/js/hooks/Mapper/components/mapInterface/constants.tsx
Normal file
71
assets/js/hooks/Mapper/components/mapInterface/constants.tsx
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { WindowProps } from '@/hooks/Mapper/components/ui-kit/WindowManager/types.ts';
|
||||||
|
import {
|
||||||
|
LocalCharacters,
|
||||||
|
RoutesWidget,
|
||||||
|
SystemInfo,
|
||||||
|
SystemSignatures,
|
||||||
|
} from '@/hooks/Mapper/components/mapInterface/widgets';
|
||||||
|
|
||||||
|
export const CURRENT_WINDOWS_VERSION = 2;
|
||||||
|
|
||||||
|
export enum WidgetsIds {
|
||||||
|
info = 'info',
|
||||||
|
signatures = 'signatures',
|
||||||
|
local = 'local',
|
||||||
|
routes = 'routes',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_WIDGETS: WindowProps[] = [
|
||||||
|
{
|
||||||
|
id: WidgetsIds.info,
|
||||||
|
position: { x: 10, y: 10 },
|
||||||
|
size: { width: 250, height: 200 },
|
||||||
|
zIndex: 0,
|
||||||
|
content: () => <SystemInfo />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: WidgetsIds.signatures,
|
||||||
|
position: { x: 10, y: 220 },
|
||||||
|
size: { width: 250, height: 300 },
|
||||||
|
zIndex: 0,
|
||||||
|
content: () => <SystemSignatures />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: WidgetsIds.local,
|
||||||
|
position: { x: 270, y: 10 },
|
||||||
|
size: { width: 250, height: 510 },
|
||||||
|
zIndex: 0,
|
||||||
|
content: () => <LocalCharacters />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: WidgetsIds.routes,
|
||||||
|
position: { x: 10, y: 530 },
|
||||||
|
size: { width: 510, height: 200 },
|
||||||
|
zIndex: 0,
|
||||||
|
content: () => <RoutesWidget />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
type WidgetsCheckboxesType = {
|
||||||
|
id: WidgetsIds;
|
||||||
|
label: string;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
export const WIDGETS_CHECKBOXES_PROPS: WidgetsCheckboxesType = [
|
||||||
|
{
|
||||||
|
id: WidgetsIds.info,
|
||||||
|
label: 'System Info',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: WidgetsIds.signatures,
|
||||||
|
label: 'Signatures',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: WidgetsIds.local,
|
||||||
|
label: 'Local',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: WidgetsIds.routes,
|
||||||
|
label: 'Routes',
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -3,13 +3,10 @@ import { Dialog } from 'primereact/dialog';
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { TabPanel, TabView } from 'primereact/tabview';
|
import { TabPanel, TabView } from 'primereact/tabview';
|
||||||
import { PrettySwitchbox } from './components';
|
import { PrettySwitchbox } from './components';
|
||||||
import {
|
import { InterfaceStoredSettingsProps, useMapRootState, InterfaceStoredSettings } from '@/hooks/Mapper/mapRootProvider';
|
||||||
InterfaceStoredSettingsProps,
|
|
||||||
useMapRootState,
|
|
||||||
InterfaceStoredSettings,
|
|
||||||
} from '@/hooks/Mapper/mapRootProvider';
|
|
||||||
import { OutCommand } from '@/hooks/Mapper/types';
|
import { OutCommand } from '@/hooks/Mapper/types';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
|
import { WidgetsSettings } from '@/hooks/Mapper/components/mapRootContent/components/MapSettings/components/WidgetsSettings/WidgetsSettings.tsx';
|
||||||
|
|
||||||
export enum UserSettingsRemoteProps {
|
export enum UserSettingsRemoteProps {
|
||||||
link_signature_on_splash = 'link_signature_on_splash',
|
link_signature_on_splash = 'link_signature_on_splash',
|
||||||
@@ -140,7 +137,6 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
|
|||||||
};
|
};
|
||||||
}, [userRemoteSettings, interfaceSettings]);
|
}, [userRemoteSettings, interfaceSettings]);
|
||||||
|
|
||||||
|
|
||||||
const handleShow = async () => {
|
const handleShow = async () => {
|
||||||
const { user_settings } = await outCommand({
|
const { user_settings } = await outCommand({
|
||||||
type: OutCommand.getUserSettings,
|
type: OutCommand.getUserSettings,
|
||||||
@@ -182,7 +178,7 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
|
|||||||
key={item.prop}
|
key={item.prop}
|
||||||
label={item.label}
|
label={item.label}
|
||||||
checked={!!currentValue}
|
checked={!!currentValue}
|
||||||
setChecked={(checked) => handleSettingChange(item.prop, checked)}
|
setChecked={checked => handleSettingChange(item.prop, checked)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -195,7 +191,7 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
|
|||||||
className="text-sm"
|
className="text-sm"
|
||||||
value={currentValue}
|
value={currentValue}
|
||||||
options={item.options}
|
options={item.options}
|
||||||
onChange={(e) => handleSettingChange(item.prop, e.value)}
|
onChange={e => handleSettingChange(item.prop, e.value)}
|
||||||
placeholder="Select a theme"
|
placeholder="Select a theme"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -227,19 +223,15 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
|
|||||||
<div className={styles.verticalTabsContainer}>
|
<div className={styles.verticalTabsContainer}>
|
||||||
<TabView
|
<TabView
|
||||||
activeIndex={activeIndex}
|
activeIndex={activeIndex}
|
||||||
onTabChange={(e) => setActiveIndex(e.index)}
|
onTabChange={e => setActiveIndex(e.index)}
|
||||||
className={styles.verticalTabView}
|
className={styles.verticalTabView}
|
||||||
>
|
>
|
||||||
<TabPanel header="Common" headerClassName={styles.verticalTabHeader}>
|
<TabPanel header="Common" headerClassName={styles.verticalTabHeader}>
|
||||||
<div className="w-full h-full flex flex-col gap-1">
|
<div className="w-full h-full flex flex-col gap-1">{renderSettingsList(COMMON_CHECKBOXES_PROPS)}</div>
|
||||||
{renderSettingsList(COMMON_CHECKBOXES_PROPS)}
|
|
||||||
</div>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel header="Systems" headerClassName={styles.verticalTabHeader}>
|
<TabPanel header="Systems" headerClassName={styles.verticalTabHeader}>
|
||||||
<div className="w-full h-full flex flex-col gap-1">
|
<div className="w-full h-full flex flex-col gap-1">{renderSettingsList(SYSTEMS_CHECKBOXES_PROPS)}</div>
|
||||||
{renderSettingsList(SYSTEMS_CHECKBOXES_PROPS)}
|
|
||||||
</div>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel header="Connections" headerClassName={styles.verticalTabHeader}>
|
<TabPanel header="Connections" headerClassName={styles.verticalTabHeader}>
|
||||||
@@ -254,6 +246,10 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
|
|||||||
{renderSettingsList(UI_CHECKBOXES_PROPS)}
|
{renderSettingsList(UI_CHECKBOXES_PROPS)}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
|
<TabPanel header="Widgets" headerClassName={styles.verticalTabHeader}>
|
||||||
|
<WidgetsSettings />
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel header="Theme" headerClassName={styles.verticalTabHeader}>
|
<TabPanel header="Theme" headerClassName={styles.verticalTabHeader}>
|
||||||
{renderSettingItem(THEME_SETTING)}
|
{renderSettingItem(THEME_SETTING)}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { PrettySwitchbox } from '@/hooks/Mapper/components/mapRootContent/components/MapSettings/components';
|
||||||
|
import { WIDGETS_CHECKBOXES_PROPS, WidgetsIds } from '@/hooks/Mapper/components/mapInterface/constants.tsx';
|
||||||
|
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
export interface WidgetsSettingsProps {}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty-pattern
|
||||||
|
export const WidgetsSettings = ({}: WidgetsSettingsProps) => {
|
||||||
|
const { windowsVisible, setWindowsVisible } = useMapRootState();
|
||||||
|
|
||||||
|
const handleWidgetSettingsChange = useCallback(
|
||||||
|
(widget: WidgetsIds, checked: boolean) => {
|
||||||
|
setWindowsVisible(prev => {
|
||||||
|
if (checked) {
|
||||||
|
return [...prev, widget];
|
||||||
|
}
|
||||||
|
|
||||||
|
return prev.filter(x => x !== widget);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setWindowsVisible],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="">
|
||||||
|
{WIDGETS_CHECKBOXES_PROPS.map(widget => (
|
||||||
|
<PrettySwitchbox
|
||||||
|
key={widget.id}
|
||||||
|
label={widget.label}
|
||||||
|
checked={windowsVisible.some(x => x === widget.id)}
|
||||||
|
setChecked={checked => handleWidgetSettingsChange(widget.id, checked)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -90,6 +90,16 @@ export const WindowManager: React.FC<WindowManagerProps> = ({ windows: initialWi
|
|||||||
zIndex: index + 1,
|
zIndex: index + 1,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setWindows(
|
||||||
|
initialWindows.map((window, index) => ({
|
||||||
|
...window,
|
||||||
|
zIndex: index + 1,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
}, [initialWindows]);
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const activeWindowIdRef = useRef<string | number | null>(null);
|
const activeWindowIdRef = useRef<string | number | null>(null);
|
||||||
const actionTypeRef = useRef<ActionType | null>(null);
|
const actionTypeRef = useRef<ActionType | null>(null);
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ export type WindowProps = {
|
|||||||
position: { x: number; y: number };
|
position: { x: number; y: number };
|
||||||
size: { width: number; height: number };
|
size: { width: number; height: number };
|
||||||
zIndex: number;
|
zIndex: number;
|
||||||
|
visible?: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export enum SESSION_KEY {
|
export enum SESSION_KEY {
|
||||||
viewPort = 'viewPort',
|
viewPort = 'viewPort',
|
||||||
windows = 'windows',
|
windows = 'windows',
|
||||||
|
windowsVisible = 'windowsVisible',
|
||||||
routes = 'routes',
|
routes = 'routes',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { MapUnionTypes, OutCommandHandler, SolarSystemConnection } from '@/hooks
|
|||||||
import { useMapRootHandlers } from '@/hooks/Mapper/mapRootProvider/hooks';
|
import { useMapRootHandlers } from '@/hooks/Mapper/mapRootProvider/hooks';
|
||||||
import { WithChildren } from '@/hooks/Mapper/types/common.ts';
|
import { WithChildren } from '@/hooks/Mapper/types/common.ts';
|
||||||
import useLocalStorageState from 'use-local-storage-state';
|
import useLocalStorageState from 'use-local-storage-state';
|
||||||
|
import { WidgetsIds } from '@/hooks/Mapper/components/mapInterface/constants.tsx';
|
||||||
|
|
||||||
export type MapRootData = MapUnionTypes & {
|
export type MapRootData = MapUnionTypes & {
|
||||||
selectedSystems: string[];
|
selectedSystems: string[];
|
||||||
@@ -60,7 +61,14 @@ export const STORED_INTERFACE_DEFAULT_VALUES: InterfaceStoredSettings = {
|
|||||||
isShowBackgroundPattern: true,
|
isShowBackgroundPattern: true,
|
||||||
isSoftBackground: false,
|
isSoftBackground: false,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export const STORED_VISIBLE_WIDGETS_DEFAULT = [
|
||||||
|
WidgetsIds.info,
|
||||||
|
WidgetsIds.local,
|
||||||
|
WidgetsIds.routes,
|
||||||
|
WidgetsIds.signatures,
|
||||||
|
];
|
||||||
|
|
||||||
export interface MapRootContextProps {
|
export interface MapRootContextProps {
|
||||||
update: ContextStoreDataUpdate<MapRootData>;
|
update: ContextStoreDataUpdate<MapRootData>;
|
||||||
@@ -68,6 +76,8 @@ export interface MapRootContextProps {
|
|||||||
outCommand: OutCommandHandler;
|
outCommand: OutCommandHandler;
|
||||||
interfaceSettings: InterfaceStoredSettings;
|
interfaceSettings: InterfaceStoredSettings;
|
||||||
setInterfaceSettings: Dispatch<SetStateAction<InterfaceStoredSettings>>;
|
setInterfaceSettings: Dispatch<SetStateAction<InterfaceStoredSettings>>;
|
||||||
|
windowsVisible: WidgetsIds[];
|
||||||
|
setWindowsVisible: Dispatch<SetStateAction<WidgetsIds[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapRootContext = createContext<MapRootContextProps>({
|
const MapRootContext = createContext<MapRootContextProps>({
|
||||||
@@ -102,6 +112,10 @@ export const MapRootProvider = ({ children, fwdRef, outCommand }: MapRootProvide
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [windowsVisible, setWindowsVisible] = useLocalStorageState<WidgetsIds[]>('windows:visible', {
|
||||||
|
defaultValue: STORED_VISIBLE_WIDGETS_DEFAULT,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let foundNew = false;
|
let foundNew = false;
|
||||||
const newVals = Object.keys(STORED_INTERFACE_DEFAULT_VALUES).reduce((acc, x) => {
|
const newVals = Object.keys(STORED_INTERFACE_DEFAULT_VALUES).reduce((acc, x) => {
|
||||||
@@ -128,6 +142,8 @@ export const MapRootProvider = ({ children, fwdRef, outCommand }: MapRootProvide
|
|||||||
outCommand: outCommand,
|
outCommand: outCommand,
|
||||||
setInterfaceSettings,
|
setInterfaceSettings,
|
||||||
interfaceSettings,
|
interfaceSettings,
|
||||||
|
windowsVisible,
|
||||||
|
setWindowsVisible,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MapRootHandlers ref={fwdRef}>{children}</MapRootHandlers>
|
<MapRootHandlers ref={fwdRef}>{children}</MapRootHandlers>
|
||||||
|
|||||||
Reference in New Issue
Block a user