mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-11 18:26:04 +00:00
feat: rework wormholes reference
This commit is contained in:
@@ -35,7 +35,7 @@ export const MapRootContent = ({}: MapRootContentProps) => {
|
||||
const [showOnTheMap, setShowOnTheMap] = useState(false);
|
||||
const [showMapSettings, setShowMapSettings] = useState(false);
|
||||
const [showTrackingDialog, setShowTrackingDialog] = useState(false);
|
||||
const [showWormholeSignatures, setShowWormholeSignatures] = useState(false);
|
||||
const [showWormholeList, setShowWormholeList] = useState(false);
|
||||
|
||||
/* Important Notice - this solution needs for use one instance of MapInterface */
|
||||
const mapInterface = isReady ? <MapInterface /> : null;
|
||||
@@ -43,16 +43,13 @@ export const MapRootContent = ({}: MapRootContentProps) => {
|
||||
const handleShowOnTheMap = useCallback(() => setShowOnTheMap(true), []);
|
||||
const handleShowMapSettings = useCallback(() => setShowMapSettings(true), []);
|
||||
const handleShowTrackingDialog = useCallback(() => setShowTrackingDialog(true), []);
|
||||
const handleShowWormholesReference = useCallback(() => setShowWormholeList(true), []);
|
||||
|
||||
useMapEventListener(event => {
|
||||
if (event.name === Commands.showTracking) {
|
||||
setShowTrackingDialog(true);
|
||||
return true;
|
||||
}
|
||||
if (event.name === Commands.showWormholeSignatures) {
|
||||
setShowWormholeSignatures(true);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
useSkipContextMenu();
|
||||
@@ -71,6 +68,7 @@ export const MapRootContent = ({}: MapRootContentProps) => {
|
||||
onShowOnTheMap={handleShowOnTheMap}
|
||||
onShowMapSettings={handleShowMapSettings}
|
||||
onShowTrackingDialog={handleShowTrackingDialog}
|
||||
onShowWormholesReference={handleShowWormholesReference}
|
||||
additionalContent={<PingsInterface hasLeftOffset />}
|
||||
/>
|
||||
</div>
|
||||
@@ -85,6 +83,7 @@ export const MapRootContent = ({}: MapRootContentProps) => {
|
||||
onShowOnTheMap={handleShowOnTheMap}
|
||||
onShowMapSettings={handleShowMapSettings}
|
||||
onShowTrackingDialog={handleShowTrackingDialog}
|
||||
onShowWormholesReference={handleShowWormholesReference}
|
||||
/>
|
||||
</div>
|
||||
</Topbar>
|
||||
@@ -99,12 +98,7 @@ export const MapRootContent = ({}: MapRootContentProps) => {
|
||||
{showTrackingDialog && (
|
||||
<TrackingDialog visible={showTrackingDialog} onHide={() => setShowTrackingDialog(false)} />
|
||||
)}
|
||||
{showWormholeSignatures && (
|
||||
<WormholeSignaturesDialog
|
||||
visible={showWormholeSignatures}
|
||||
onHide={() => setShowWormholeSignatures(false)}
|
||||
/>
|
||||
)}
|
||||
<WormholeSignaturesDialog visible={showWormholeList} onHide={() => setShowWormholeList(false)} />
|
||||
|
||||
{hasOldSettings && <OldSettingsDialog />}
|
||||
</Layout>
|
||||
|
||||
@@ -12,9 +12,15 @@ export interface MapContextMenuProps {
|
||||
onShowOnTheMap?: () => void;
|
||||
onShowMapSettings?: () => void;
|
||||
onShowTrackingDialog?: () => void;
|
||||
onShowWormholesReference?: () => void;
|
||||
}
|
||||
|
||||
export const MapContextMenu = ({ onShowOnTheMap, onShowMapSettings, onShowTrackingDialog }: MapContextMenuProps) => {
|
||||
export const MapContextMenu = ({
|
||||
onShowOnTheMap,
|
||||
onShowMapSettings,
|
||||
onShowTrackingDialog,
|
||||
onShowWormholesReference,
|
||||
}: MapContextMenuProps) => {
|
||||
const {
|
||||
outCommand,
|
||||
storedSettings: { setInterfaceSettings },
|
||||
@@ -52,6 +58,12 @@ export const MapContextMenu = ({ onShowOnTheMap, onShowMapSettings, onShowTracki
|
||||
command: onShowOnTheMap,
|
||||
visible: canTrackCharacters,
|
||||
},
|
||||
{
|
||||
label: 'Wormholes Ref.',
|
||||
icon: 'pi pi-bullseye',
|
||||
command: onShowWormholesReference,
|
||||
visible: canTrackCharacters,
|
||||
},
|
||||
{ separator: true, visible: true },
|
||||
{
|
||||
label: 'Settings',
|
||||
|
||||
@@ -14,6 +14,7 @@ interface RightBarProps {
|
||||
onShowOnTheMap?: () => void;
|
||||
onShowMapSettings?: () => void;
|
||||
onShowTrackingDialog?: () => void;
|
||||
onShowWormholesReference?: () => void;
|
||||
additionalContent?: ReactNode;
|
||||
}
|
||||
|
||||
@@ -21,6 +22,7 @@ export const RightBar = ({
|
||||
onShowOnTheMap,
|
||||
onShowMapSettings,
|
||||
onShowTrackingDialog,
|
||||
onShowWormholesReference,
|
||||
additionalContent,
|
||||
}: RightBarProps) => {
|
||||
const {
|
||||
@@ -90,6 +92,16 @@ export const RightBar = ({
|
||||
<i className="pi pi-hashtag"></i>
|
||||
</button>
|
||||
</WdTooltipWrapper>
|
||||
|
||||
<WdTooltipWrapper content="Wormholes Reference" position={TooltipPosition.left}>
|
||||
<button
|
||||
className="btn bg-transparent text-gray-400 hover:text-white border-transparent hover:bg-transparent py-2 h-auto min-h-auto"
|
||||
type="button"
|
||||
onClick={onShowWormholesReference}
|
||||
>
|
||||
<i className="pi pi-bullseye"></i>
|
||||
</button>
|
||||
</WdTooltipWrapper>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DataTable } from 'primereact/datatable';
|
||||
import { Column } from 'primereact/column';
|
||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||
import { WormholeDataRaw } from '@/hooks/Mapper/types';
|
||||
import { WHClassView } from '@/hooks/Mapper/components/ui-kit';
|
||||
import { RespawnTag, WHClassView } from '@/hooks/Mapper/components/ui-kit';
|
||||
import { kgToTons } from '@/hooks/Mapper/utils/kgToTons.ts';
|
||||
import { WORMHOLE_CLASS_STYLES, WORMHOLES_ADDITIONAL_INFO } from '@/hooks/Mapper/components/map/constants.ts';
|
||||
import clsx from 'clsx';
|
||||
@@ -12,15 +12,61 @@ import { InputText } from 'primereact/inputtext';
|
||||
import { IconField } from 'primereact/iconfield';
|
||||
import { InputIcon } from 'primereact/inputicon';
|
||||
|
||||
const renderSpawns = (w: WormholeDataRaw) => (
|
||||
<div className="flex gap-1 flex-wrap">
|
||||
{w.src.map(s => {
|
||||
const group = s.split('-')[0];
|
||||
const info = WORMHOLES_ADDITIONAL_INFO[group];
|
||||
|
||||
if (!info) {
|
||||
return (
|
||||
<span
|
||||
key={s}
|
||||
className="px-[4px] py-[1px] rounded bg-stone-800 text-stone-300 text-xs border border-stone-700"
|
||||
>
|
||||
{s}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const cls = WORMHOLE_CLASS_STYLES[String(info.wormholeClassID)] || '';
|
||||
const label = `${info.shortName}`;
|
||||
return (
|
||||
<span
|
||||
key={s}
|
||||
className={clsx(cls, 'px-[4px] py-[1px] rounded text-xs border border-stone-700 bg-stone-900/40')}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderName = (w: WormholeDataRaw) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<WHClassView
|
||||
whClassName={w.name}
|
||||
noOffset
|
||||
useShortTitle
|
||||
classNameWh="overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderRespawn = (w: WormholeDataRaw) => (
|
||||
<div className="flex gap-1 flex-wrap">
|
||||
{w.respawn.map(r => (
|
||||
<RespawnTag key={r} value={r} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
export interface WormholeSignaturesDialogProps {
|
||||
visible: boolean;
|
||||
onHide: () => void;
|
||||
}
|
||||
|
||||
const RespawnTag = ({ value }: { value: string }) => (
|
||||
<span className="px-2 py-[2px] rounded bg-stone-800 text-stone-300 text-xs border border-stone-700">{value}</span>
|
||||
);
|
||||
|
||||
export const WormholeSignaturesDialog = ({ visible, onHide }: WormholeSignaturesDialogProps) => {
|
||||
const {
|
||||
data: { wormholes },
|
||||
@@ -61,49 +107,13 @@ export const WormholeSignaturesDialog = ({ visible, onHide }: WormholeSignatures
|
||||
});
|
||||
}, [wormholes, filter]);
|
||||
|
||||
const renderName = (w: WormholeDataRaw) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<WHClassView whClassName={w.name} noOffset useShortTitle />
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderRespawn = (w: WormholeDataRaw) => (
|
||||
<div className="flex gap-1 flex-wrap">
|
||||
{w.respawn.map(r => (
|
||||
<RespawnTag key={r} value={r} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderSpawns = (w: WormholeDataRaw) => (
|
||||
<div className="flex gap-1 flex-wrap">
|
||||
{w.src.map(s => {
|
||||
const group = s.split('-')[0];
|
||||
const info = WORMHOLES_ADDITIONAL_INFO[group];
|
||||
if (!info)
|
||||
return (
|
||||
<span key={s} className="px-2 py-[2px] rounded bg-stone-800 text-stone-300 text-xs border border-stone-700">
|
||||
{s}
|
||||
</span>
|
||||
);
|
||||
const cls = WORMHOLE_CLASS_STYLES[String(info.wormholeClassID)] || '';
|
||||
const label = `${info.shortName}`;
|
||||
return (
|
||||
<span key={s} className={clsx(cls, 'px-2 py-[2px] rounded text-xs border border-stone-700 bg-stone-900/40')}>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
header="Wormhole Signatures Reference"
|
||||
header="Wormholes Reference"
|
||||
visible={visible}
|
||||
draggable={true}
|
||||
draggable={false}
|
||||
resizable={false}
|
||||
style={{ width: '820px', height: '600px' }}
|
||||
className="w-[950px] h-[600px]"
|
||||
onHide={onHide}
|
||||
contentClassName="!p-0 flex flex-col h-full"
|
||||
>
|
||||
@@ -111,12 +121,10 @@ export const WormholeSignaturesDialog = ({ visible, onHide }: WormholeSignatures
|
||||
<div className="font-semibold text-sm text-stone-200">Reference list of all wormhole types</div>
|
||||
<IconField iconPosition="right">
|
||||
<InputIcon
|
||||
className={clsx(
|
||||
'pi pi-times',
|
||||
filter
|
||||
? 'cursor-pointer text-stone-400 hover:text-stone-200'
|
||||
: 'text-stone-700 opacity-50 cursor-default',
|
||||
)}
|
||||
className={clsx('pi pi-times', {
|
||||
['cursor-pointer text-stone-400 hover:text-stone-200']: filter,
|
||||
['text-stone-700 opacity-50 cursor-default']: !filter,
|
||||
})}
|
||||
onClick={() => filter && setFilter('')}
|
||||
role="button"
|
||||
aria-label="Clear search"
|
||||
@@ -127,47 +135,34 @@ export const WormholeSignaturesDialog = ({ visible, onHide }: WormholeSignatures
|
||||
</IconField>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 p-2 overflow-x-hidden">
|
||||
<DataTable
|
||||
value={filtered}
|
||||
size="small"
|
||||
scrollable
|
||||
scrollHeight="flex"
|
||||
stripedRows
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
tableStyle={{ tableLayout: 'fixed', width: '100%' }}
|
||||
>
|
||||
<Column
|
||||
header="Type"
|
||||
body={renderName}
|
||||
style={{ width: '140px' }}
|
||||
bodyClassName="whitespace-normal break-words"
|
||||
/>
|
||||
<Column
|
||||
header="Spawns In"
|
||||
body={renderSpawns}
|
||||
style={{ width: '200px' }}
|
||||
bodyClassName="whitespace-normal break-words"
|
||||
/>
|
||||
<div className="flex-1 p-3 overflow-x-hidden">
|
||||
<DataTable value={filtered} size="small" scrollable scrollHeight="flex" stripedRows>
|
||||
<Column header="Type" body={renderName} className="w-[160px]" bodyClassName="whitespace-normal break-words" />
|
||||
<Column header="Spawns In" body={renderSpawns} bodyClassName="whitespace-normal break-words text-[13px]" />
|
||||
<Column
|
||||
field="lifetime"
|
||||
header="Lifetime"
|
||||
style={{ width: '90px' }}
|
||||
bodyClassName="whitespace-normal break-words"
|
||||
className="w-[90px]"
|
||||
bodyClassName="whitespace-normal break-words text-[13px]"
|
||||
/>
|
||||
<Column
|
||||
header="Total Mass"
|
||||
style={{ width: '120px' }}
|
||||
className="w-[120px]"
|
||||
body={(w: WormholeDataRaw) => kgToTons(w.total_mass)}
|
||||
bodyClassName="whitespace-normal break-words"
|
||||
bodyClassName="whitespace-normal break-words text-[13px]"
|
||||
/>
|
||||
<Column
|
||||
header="Max/jump"
|
||||
style={{ width: '120px' }}
|
||||
className="w-[120px]"
|
||||
body={(w: WormholeDataRaw) => kgToTons(w.max_mass_per_jump)}
|
||||
bodyClassName="whitespace-normal break-words"
|
||||
bodyClassName="whitespace-normal break-words text-[13px]"
|
||||
/>
|
||||
<Column
|
||||
header="Respawn"
|
||||
className="w-[150px]"
|
||||
body={renderRespawn}
|
||||
bodyClassName="whitespace-normal break-words text-[13px]"
|
||||
/>
|
||||
<Column header="Respawn" body={renderRespawn} bodyClassName="whitespace-normal break-words" />
|
||||
</DataTable>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
20
assets/js/hooks/Mapper/components/ui-kit/RespawnTag.tsx
Normal file
20
assets/js/hooks/Mapper/components/ui-kit/RespawnTag.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Respawn } from '@/hooks/Mapper/types';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export const WORMHOLE_SPAWN_CLASSES_BG = {
|
||||
[Respawn.static]: 'bg-lime-400/80 text-stone-950',
|
||||
[Respawn.wandering]: 'bg-stone-800',
|
||||
[Respawn.reverse]: 'bg-blue-400 text-stone-950',
|
||||
};
|
||||
|
||||
type RespawnTagProps = { value: string };
|
||||
export const RespawnTag = ({ value }: RespawnTagProps) => (
|
||||
<span
|
||||
className={clsx(
|
||||
'px-[6px] py-[0px] rounded text-stone-300 text-[12px] font-[500] border border-stone-700',
|
||||
WORMHOLE_SPAWN_CLASSES_BG[value as Respawn],
|
||||
)}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
);
|
||||
@@ -23,3 +23,4 @@ export * from './MenuItemWithInfo';
|
||||
export * from './MarkdownTextViewer.tsx';
|
||||
export * from './WdButton.tsx';
|
||||
export * from './constants.ts';
|
||||
export * from './RespawnTag';
|
||||
|
||||
@@ -172,10 +172,6 @@ export const useMapRootHandlers = (ref: ForwardedRef<MapHandlers>) => {
|
||||
case Commands.pingCancelled:
|
||||
pingCancelled(data as CommandPingCancelled);
|
||||
break;
|
||||
|
||||
case Commands.showWormholeSignatures:
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(`JOipP Interface handlers: Unknown command: ${type}`, data);
|
||||
break;
|
||||
|
||||
@@ -40,7 +40,6 @@ export enum Commands {
|
||||
showTracking = 'show_tracking',
|
||||
pingAdded = 'ping_added',
|
||||
pingCancelled = 'ping_cancelled',
|
||||
showWormholeSignatures = 'show_wormhole_signatures',
|
||||
}
|
||||
|
||||
export type Command =
|
||||
@@ -76,8 +75,7 @@ export type Command =
|
||||
| Commands.updateTracking
|
||||
| Commands.showTracking
|
||||
| Commands.pingAdded
|
||||
| Commands.pingCancelled
|
||||
| Commands.showWormholeSignatures;
|
||||
| Commands.pingCancelled;
|
||||
|
||||
export type CommandInit = {
|
||||
systems: SolarSystemRawType[];
|
||||
@@ -211,7 +209,6 @@ export interface CommandData {
|
||||
[Commands.showTracking]: CommandShowTracking;
|
||||
[Commands.pingAdded]: CommandPingAdded;
|
||||
[Commands.pingCancelled]: CommandPingCancelled;
|
||||
[Commands.showWormholeSignatures]: CommandShowWormholeSignatures;
|
||||
}
|
||||
|
||||
export interface MapHandlers {
|
||||
|
||||
@@ -219,15 +219,6 @@ defmodule WandererAppWeb.MapCoreEventHandler do
|
||||
{:reply, %{user_settings: user_settings}, socket}
|
||||
end
|
||||
|
||||
def handle_ui_event("show_wormhole_signatures", _event, socket) do
|
||||
{:noreply,
|
||||
socket
|
||||
|> MapEventHandler.push_map_event(
|
||||
"show_wormhole_signatures",
|
||||
%{}
|
||||
)}
|
||||
end
|
||||
|
||||
def handle_ui_event(
|
||||
"update_user_settings",
|
||||
user_settings_form,
|
||||
|
||||
@@ -32,15 +32,6 @@
|
||||
<.icon name="hero-chart-bar-solid" class="w-6 h-6" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="show-wormhole-signatures-button"
|
||||
class="h-8 w-8 hover:text-white"
|
||||
phx-click="show_wormhole_signatures"
|
||||
title="Wormhole Signatures Reference"
|
||||
>
|
||||
<.icon name="hero-sparkles-solid" class="w-6 h-6" />
|
||||
</button>
|
||||
|
||||
<.link
|
||||
:if={(@user_permissions || %{}) |> Map.get(:delete_map, false)}
|
||||
id={"map-audit-#{@map_slug}"}
|
||||
|
||||
Reference in New Issue
Block a user