Compare commits

..

1 Commits

Author SHA1 Message Date
Dmitry Popov
2809959056 feat(Core): Show tracking for new userfeat(Map): Add minimap options 2024-12-20 16:07:27 +01:00
128 changed files with 1905 additions and 5710 deletions

View File

@@ -6,4 +6,3 @@ export EVE_CLIENT_WITH_WALLET_ID="<EVE_CLIENT_WITH_WALLET_ID>"
export EVE_CLIENT_WITH_WALLET_SECRET="<EVE_CLIENT_WITH_WALLET_SECRET>"
export GIT_SHA="1111"
export WANDERER_INVITES="false"
export WANDERER_PUBLIC_API_DISABLED="false"

View File

@@ -122,8 +122,6 @@ jobs:
name: 🛠 Build Docker Images
needs: build
runs-on: ubuntu-22.04
outputs:
release-notes: ${{ steps.get-content.outputs.string }}
permissions:
checks: write
contents: write
@@ -137,7 +135,6 @@ jobs:
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Prepare
run: |
@@ -214,6 +211,12 @@ jobs:
maxLength: 500
truncationSymbol: "…"
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v5.3.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ steps.get-content.outputs.string }}
create-release:
name: 🏷 Create Release
runs-on: ubuntu-22.04
@@ -245,9 +248,3 @@ jobs:
## How to Promote?
In order to promote this to prod, edit the draft and press **"Publish release"**.
draft: true
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v5.3.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ needs.docker.outputs.release-notes }}

File diff suppressed because it is too large Load Diff

View File

@@ -9,9 +9,6 @@ WORKDIR /app
# set build ENV
ENV MIX_ENV="prod"
# Set ERL_FLAGS for ARM compatibility
ENV ERL_FLAGS="+JPperf true"
# install mix dependencies
COPY mix.exs mix.lock ./
RUN rm -Rf _build deps && mix deps.get --only $MIX_ENV

View File

@@ -3,8 +3,6 @@
@import 'primereact/resources/themes/arya-blue/theme.css' layer(primereact);
/*@import 'primereact/resources/themes/bootstrap4-dark-blue/theme.css' layer(primereact);*/
@import '../js/hooks/Mapper/components/map/styles/index.scss';
@layer tailwind-base {
@tailwind base;
}

View File

@@ -108,7 +108,3 @@
.p-dropdown-empty-message {
padding: 0.25rem 0.5rem;
}
.p-autocomplete .p-autocomplete-multiple-container .p-autocomplete-token {
margin-right: 0 !important;
}

View File

@@ -88,23 +88,6 @@ export const useContextMenuSystemHandlers = ({ systems, hubs, outCommand }: UseC
setSystem(undefined);
}, []);
const onSystemTemporaryName = useCallback((temporaryName?: string) => {
const { system, outCommand } = ref.current;
if (!system) {
return;
}
outCommand({
type: OutCommand.updateSystemTemporaryName,
data: {
system_id: system,
value: temporaryName ?? '',
},
});
setSystem(undefined);
}, []);
const onSystemStatus = useCallback((status: number) => {
const { system, outCommand } = ref.current;
if (!system) {
@@ -178,7 +161,6 @@ export const useContextMenuSystemHandlers = ({ systems, hubs, outCommand }: UseC
onLockToggle,
onHubToggle,
onSystemTag,
onSystemTemporaryName,
onSystemStatus,
onSystemLabels,
onOpenSettings,

View File

@@ -1,181 +0,0 @@
// feel free to rename these imports or the file path as you see fit
import { useMemo } from 'react';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { useMapGetOption } from '@/hooks/Mapper/mapRootProvider/hooks/api';
import { useMapState } from '@/hooks/Mapper/components/map/MapProvider.tsx';
import { useDoubleClick } from '@/hooks/Mapper/hooks/useDoubleClick.ts';
import { REGIONS_MAP, Spaces } from '@/hooks/Mapper/constants';
import { MapSolarSystemType } from '../../map.types';
import { LABELS_INFO, LABELS_ORDER, getActivityType } from '@/hooks/Mapper/components/map/constants.ts';
import { isWormholeSpace } from '@/hooks/Mapper/components/map/helpers/isWormholeSpace.ts';
import { getSystemClassStyles, prepareUnsplashedChunks } from '@/hooks/Mapper/components/map/helpers';
import { sortWHClasses } from '@/hooks/Mapper/helpers';
import { LabelsManager } from '@/hooks/Mapper/utils/labelsManager.ts';
import { OutCommand } from '@/hooks/Mapper/types';
const SpaceToClass: Record<string, string> = {
[Spaces.Caldari]: 'Caldaria',
[Spaces.Matar]: 'Mataria',
[Spaces.Amarr]: 'Amarria',
[Spaces.Gallente]: 'Gallente',
};
const sortedLabels = (labels: string[]) => {
if (!labels) return [];
return LABELS_ORDER.filter(x => labels.includes(x)).map(x => LABELS_INFO[x]);
};
interface UseSolarSystemNodeParams {
data: MapSolarSystemType;
selected: boolean;
}
export function useSolarSystemNode({ data, selected }: UseSolarSystemNodeParams) {
// 1) Bring in relevant global state
const { interfaceSettings } = useMapRootState();
const { isShowUnsplashedSignatures } = interfaceSettings;
const isTempSystemNameEnabled = useMapGetOption('show_temp_system_name') === 'true';
const isShowLinkedSigId = useMapGetOption('show_linked_signature_id') === 'true';
const {
data: {
characters,
presentCharacters,
wormholesData,
hubs,
kills,
userCharacters,
isConnecting,
hoverNodeId,
visibleNodes,
showKSpaceBG,
isThickConnections,
},
outCommand,
} = useMapState();
// 2) Extract data from the node
const {
system_class,
security,
class_title,
solar_system_id,
statics,
effect_name,
region_name,
region_id,
is_shattered,
solar_system_name,
} = data.system_static_info;
const {
locked,
name,
tag,
status,
labels,
id,
temporary_name: temporaryName,
linked_sig_eve_id: linkedSigEveId = '',
} = data || {};
const signatures = data.system_signatures;
// 3) Compute derived values
const visible = useMemo(() => visibleNodes.has(id), [id, visibleNodes]);
const charactersInSystem = useMemo(() => {
return characters.filter(c => c.location?.solar_system_id === solar_system_id).filter(c => c.online);
}, [characters, presentCharacters, solar_system_id]);
const isWormhole = isWormholeSpace(system_class);
const classTitleColor = useMemo(
() => getSystemClassStyles({ systemClass: system_class, security }),
[security, system_class],
);
const sortedStatics = useMemo(() => sortWHClasses(wormholesData, statics), [wormholesData, statics]);
const linkedSigPrefix = useMemo(() => (linkedSigEveId ? linkedSigEveId.split('-')[0] : null), [linkedSigEveId]);
const labelsManager = useMemo(() => new LabelsManager(labels ?? ''), [labels]);
const labelsInfo = useMemo(() => sortedLabels(labelsManager.list), [labelsManager]);
const labelCustom = useMemo(
() =>
isShowLinkedSigId && linkedSigPrefix
? `${linkedSigPrefix}${labelsManager.customLabel}`
: labelsManager.customLabel,
[linkedSigPrefix, isShowLinkedSigId, labelsManager],
);
const killsCount = useMemo(() => {
const systemKills = kills[solar_system_id];
if (!systemKills) return null;
return systemKills;
}, [kills, solar_system_id]);
const hasUserCharacters = useMemo(() => {
return charactersInSystem.some(x => userCharacters.includes(x.eve_id));
}, [charactersInSystem, userCharacters]);
const dbClick = useDoubleClick(() => {
outCommand({
type: OutCommand.openSettings,
data: {
system_id: solar_system_id.toString(),
},
});
});
const showHandlers = isConnecting || hoverNodeId === id;
const space = showKSpaceBG ? REGIONS_MAP[region_id] : '';
const regionClass = showKSpaceBG ? SpaceToClass[space] : null;
const systemName = (isTempSystemNameEnabled && temporaryName) || solar_system_name;
const customName = (isTempSystemNameEnabled && temporaryName && name) || (solar_system_name !== name && name);
const [unsplashedLeft, unsplashedRight] = useMemo(() => {
if (!isShowUnsplashedSignatures) {
return [[], []];
}
return prepareUnsplashedChunks(
signatures
.filter(s => s.group === 'Wormhole' && !s.linked_system)
.map(s => ({
eve_id: s.eve_id,
type: s.type,
custom_info: s.custom_info,
})),
);
}, [isShowUnsplashedSignatures, signatures]);
return {
selected,
visible,
isWormhole,
classTitleColor,
killsCount,
hasUserCharacters,
showHandlers,
regionClass,
systemName,
customName,
labelCustom,
is_shattered,
tag,
status,
labelsInfo,
dbClick,
sortedStatics,
effect_name,
region_name,
solar_system_id,
locked,
hubs,
charactersInSystem,
unsplashedLeft,
unsplashedRight,
isThickConnections,
};
}

View File

@@ -1,11 +1,8 @@
.MapRoot {
width: 100%;
height: 100%;
background-color: var(--rf-bg-color, #0C0A09);
&.BackgroundAlternateColor {
background-color: var(--rf-soft-bg-color, #171717);
--rf-node-bg-color: var(--rf-node-soft-bg-color, #202020);
}
}
.BackgroundAlternateColor {
}

View File

@@ -1,4 +1,4 @@
import { ForwardedRef, forwardRef, MouseEvent, useCallback, useEffect, useMemo } from 'react';
import { ForwardedRef, forwardRef, MouseEvent, useCallback, useEffect } from 'react';
import ReactFlow, {
Background,
ConnectionMode,
@@ -16,6 +16,8 @@ import ReactFlow, {
} from 'reactflow';
import 'reactflow/dist/style.css';
import classes from './Map.module.scss';
import './styles/neon-theme.scss';
import './styles/eve-common.scss';
import { MapProvider, useMapState } from './MapProvider';
import { useNodesState, useEdgesState, useMapHandlers, useUpdateNodes } from './hooks';
import { MapHandlers, OutCommand, OutCommandHandler } from '@/hooks/Mapper/types/mapHandlers.ts';
@@ -23,19 +25,16 @@ import {
ContextMenuConnection,
ContextMenuRoot,
SolarSystemEdge,
SolarSystemNodeDefault,
SolarSystemNodeTheme,
SolarSystemNode,
useContextMenuConnectionHandlers,
useContextMenuRootHandlers,
} from './components';
import { wrapNode } from './utils/wrapNode';
import { OnMapAddSystemCallback, OnMapSelectionChange } from './map.types';
import { OnMapSelectionChange } from './map.types';
import { SESSION_KEY } from '@/hooks/Mapper/constants.ts';
import { SolarSystemConnection, SolarSystemRawType } from '@/hooks/Mapper/types';
import { ctxManager } from '@/hooks/Mapper/utils/contextManager.ts';
import { NodeSelectionMouseHandler } from '@/hooks/Mapper/components/contexts/types.ts';
import clsx from 'clsx';
import { useBackgroundVars } from './hooks/useBackgroundVars';
const DEFAULT_VIEW_PORT = { zoom: 1, x: 0, y: 0 };
@@ -77,8 +76,11 @@ const initialEdges = [
},
];
const nodeTypes = {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
custom: SolarSystemNode,
} as never;
const edgeTypes = {
floating: SolarSystemEdge,
@@ -90,7 +92,6 @@ interface MapCompProps {
onSelectionChange: OnMapSelectionChange;
onManualDelete(systems: string[]): void;
onConnectionInfoClick?(e: SolarSystemConnection): void;
onAddSystem?: OnMapAddSystemCallback;
onSelectionContextMenu?: NodeSelectionMouseHandler;
minimapClasses?: string;
isShowMinimap?: boolean;
@@ -99,7 +100,6 @@ interface MapCompProps {
isThickConnections?: boolean;
isShowBackgroundPattern?: boolean;
isSoftBackground?: boolean;
theme?: string;
}
const MapComp = ({
@@ -116,30 +116,16 @@ const MapComp = ({
isThickConnections,
isShowBackgroundPattern,
isSoftBackground,
theme,
onAddSystem,
}: MapCompProps) => {
const { getNode, getNodes } = useReactFlow();
const { getNode } = useReactFlow();
const [nodes, , onNodesChange] = useNodesState<Node<SolarSystemRawType>>(initialNodes);
const [edges, , onEdgesChange] = useEdgesState<Edge<SolarSystemConnection>>(initialEdges);
const nodeTypes = useMemo(() => {
return {
custom:
theme !== '' && theme !== 'default'
? wrapNode(SolarSystemNodeTheme)
: wrapNode(SolarSystemNodeDefault),
};
}, [theme]);
useMapHandlers(refn, onSelectionChange);
useUpdateNodes(nodes);
const { handleRootContext, ...rootCtxProps } = useContextMenuRootHandlers({ onAddSystem });
const { handleRootContext, ...rootCtxProps } = useContextMenuRootHandlers();
const { handleConnectionContext, ...connectionCtxProps } = useContextMenuConnectionHandlers();
const { update } = useMapState();
const { variant, gap, size, color } = useBackgroundVars(theme);
const onConnect: OnConnect = useCallback(
params => {
@@ -198,12 +184,6 @@ const MapComp = ({
(changes: NodeChange[]) => {
const systemsIdsToRemove: string[] = [];
// prevents single node deselection on background / same node click
// allows deseletion of all nodes if multiple are currently selected
if (changes.length === 1 && changes[0].type == 'select' && changes[0].selected === false) {
changes[0].selected = getNodes().filter(node => node.selected).length === 1;
}
const nextChanges = changes.reduce((acc, change) => {
if (change.type !== 'remove') {
return [...acc, change];
@@ -241,7 +221,7 @@ const MapComp = ({
return (
<>
<div className={clsx(classes.MapRoot, { [classes.BackgroundAlternateColor]: isSoftBackground })}>
<div className={clsx(classes.MapRoot, { ['bg-neutral-900']: isSoftBackground })}>
<ReactFlow
nodes={nodes}
edges={edges}
@@ -288,7 +268,7 @@ const MapComp = ({
selectionMode={SelectionMode.Partial}
>
{isShowMinimap && <MiniMap pannable zoomable ariaLabel="Mini map" className={minimapClasses} />}
{isShowBackgroundPattern && <Background variant={variant} gap={gap} size={size} color={color} />}
{isShowBackgroundPattern && <Background />}
</ReactFlow>
{/* <button className="z-auto btn btn-primary absolute top-20 right-20" onClick={handleGetPassages}>
Test // DON NOT REMOVE

View File

@@ -1,17 +1,15 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
.ConnectionTimeEOL {
background-image: linear-gradient(207deg, transparent, var(--conn-time-eol));
background-image: linear-gradient(207deg, transparent, #7452c3e3);
}
.ConnectionFrigate {
background-image: linear-gradient(207deg, transparent, var(--conn-frigate));
background-image: linear-gradient(207deg, transparent, #325d88);
}
.ConnectionSave {
background-image: linear-gradient(207deg, transparent, var(--conn-save));
background-image: linear-gradient(207deg, transparent, rgba(155, 102, 45, 0.85));
}
.SelectedItem {
background-color: var(--selected-item-bg);
background-color: rgba(98, 98, 98, 0.33);
}

View File

@@ -1,16 +1,14 @@
import { useReactFlow, XYPosition } from 'reactflow';
import React, { useCallback, useRef, useState } from 'react';
import React, { useRef, useState } from 'react';
import { ContextMenu } from 'primereact/contextmenu';
import { useMapState } from '../../MapProvider.tsx';
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers.ts';
import { ctxManager } from '@/hooks/Mapper/utils/contextManager.ts';
import { OnMapAddSystemCallback } from '@/hooks/Mapper/components/map/map.types.ts';
type UseContextMenuRootHandlers = {
onAddSystem?: OnMapAddSystemCallback;
};
export const useContextMenuRootHandlers = ({ onAddSystem }: UseContextMenuRootHandlers = {}) => {
export const useContextMenuRootHandlers = () => {
const rf = useReactFlow();
const contextMenuRef = useRef<ContextMenu | null>(null);
const { outCommand } = useMapState();
const [position, setPosition] = useState<XYPosition | null>(null);
const handleRootContext = (e: React.MouseEvent<HTMLDivElement>) => {
@@ -20,17 +18,14 @@ export const useContextMenuRootHandlers = ({ onAddSystem }: UseContextMenuRootHa
contextMenuRef.current?.show(e);
};
const ref = useRef({ onAddSystem, position });
ref.current = { onAddSystem, position };
const onAddSystemCallback = useCallback(() => {
ref.current.onAddSystem?.({ coordinates: position });
}, [position]);
const onAddSystem = () => {
outCommand({ type: OutCommand.manualAddSystem, data: { coordinates: position } });
};
return {
handleRootContext,
contextMenuRef,
onAddSystem: onAddSystemCallback,
onAddSystem,
};
};

View File

@@ -1,47 +1,23 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
@import "@/hooks/Mapper/components/map/styles/neon-variables";
.EdgePathBack {
fill: none;
stroke: #80a5c5;
stroke-width: 3px;
&.TimeCrit {
stroke: #f11ab2;
stroke-width: 4px;
}
&.Hovered {
stroke: #b5c8d9;
&.TimeCrit {
stroke: #ef7dce;
}
}
&.Tick {
stroke-width: 5px;
&.TimeCrit {
stroke-width: 6px;
}
}
&.Gate {
stroke: #9aff40;
.react-flow__edge.selected {
.EdgePathBack {
stroke: $pastel-yellow;
}
}
.EdgePathFront {
fill: none;
stroke: #2c3844;
stroke-width: 2px;
&.MassVerge:not(&.Frigate) {
stroke: #af0000;
stroke: #af2900;
}
&.MassHalf:not(&.Frigate) {
stroke: #ffd700;
stroke: #a85f00;
}
&.Frigate {
@@ -78,29 +54,46 @@
}
}
.EdgePathBack {
fill: none;
stroke: #80a5c5;
stroke-width: 3px;
&.TimeCrit {
stroke: #f11ab2;
stroke-width: 4px;
}
&.Hovered {
stroke: #b5c8d9;
&.TimeCrit {
stroke: #ef7dce;
}
}
&.Tick {
stroke-width: 5px;
&.TimeCrit {
stroke-width: 6px;
}
}
&.Gate {
stroke: #9aff40;
}
}
.ClickPath {
fill: none;
stroke: none;
stroke-width: 8px;
}
.Handle {
border: 1px solid var(--pastel-blue);
width: 5px;
height: 5px;
z-index: 1001;
&.Tick {
width: 7px;
height: 7px;
}
&.Right {
margin-left: 0px;
}
}
.LinkLabel {
.LinkLabel{
font-size: 9px;
line-height: 10px;
padding: 2px 4px;
@@ -116,3 +109,22 @@
height: 8px;
font-size: 8px;
}
.Handle {
min-width: initial;
min-height: initial;
border: 1px solid #5a7d9a;
width: 5px;
height: 5px;
z-index: 1001;
&.Tick {
width: 7px;
height: 7px;
&.Right {
margin-left: 0px;
}
}
}

View File

@@ -130,7 +130,7 @@ export const SolarSystemEdge = ({ id, source, target, markerEnd, style, data }:
/>
<div
className="absolute flex items-center gap-1 pointer-events-none"
className="absolute flex items-center gap-1"
style={{
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
}}

View File

@@ -85,7 +85,7 @@ $tooltip-bg: #202020; // Dark background for tooltips
box-shadow: 0 0 10px #9a1af1c2;
}
&.tooltip {
.tooltip {
background-color: $tooltip-bg;
color: $text-color;
padding: 5px 10px;
@@ -94,59 +94,42 @@ $tooltip-bg: #202020; // Dark background for tooltips
}
&.eve-system-status-home {
border: 1px solid var(--eve-solar-system-status-color-home-dark30);
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-home),
transparent
);
border: 1px solid darken($eve-solar-system-status-color-home, 30%);
background-image: linear-gradient(275deg, $eve-solar-system-status-friendly, transparent);
&.selected {
border-color: var(--eve-solar-system-status-color-home);
border-color: $eve-solar-system-status-color-home;
}
}
&.eve-system-status-friendly {
border: 1px solid var(--eve-solar-system-status-color-friendly-dark20);
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-friendly-dark30),
transparent
);
border: 1px solid darken($eve-solar-system-status-color-friendly, 20%);
background-image: linear-gradient(275deg, darken($eve-solar-system-status-friendly, 30%), transparent);
&.selected {
border-color: var(--eve-solar-system-status-color-friendly-dark5);
border-color: darken($eve-solar-system-status-color-friendly, 5%);
}
}
&.eve-system-status-lookingFor {
border: 1px solid var(--eve-solar-system-status-color-lookingFor-dark15);
border: 1px solid darken($eve-solar-system-status-color-lookingFor, 15%);
background-image: linear-gradient(275deg, #45ff8f2f, #457fff2f);
&.selected {
border-color: $pastel-pink;
}
}
&.eve-system-status-warning {
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-warning),
transparent
);
background-image: linear-gradient(275deg, $eve-solar-system-status-warning, transparent);
}
&.eve-system-status-dangerous {
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-dangerous),
transparent
);
background-image: linear-gradient(275deg, $eve-solar-system-status-dangerous, transparent);
}
&.eve-system-status-target {
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-target),
transparent
);
background-image: linear-gradient(275deg, $eve-solar-system-status-target, transparent);
}
}
@@ -259,10 +242,10 @@ $tooltip-bg: #202020; // Dark background for tooltips
.TagTitle {
font-size: 11px;
font-weight: medium;
font-weight: bold;
text-shadow: 0 0 2px rgba(231, 146, 52, 0.73);
color: var(--rf-tag-color, #38BDF8);
color: #ffb01d;
}
/* Firefox kostyl */

View File

@@ -0,0 +1,324 @@
import { memo, useMemo } from 'react';
import { Handle, Position, WrapNodeProps } from 'reactflow';
import { MapSolarSystemType } from '../../map.types';
import classes from './SolarSystemNode.module.scss';
import clsx from 'clsx';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import {
EFFECT_BACKGROUND_STYLES,
LABELS_INFO,
LABELS_ORDER,
MARKER_BOOKMARK_BG_STYLES,
STATUS_CLASSES,
} from '@/hooks/Mapper/components/map/constants.ts';
import { isWormholeSpace } from '@/hooks/Mapper/components/map/helpers/isWormholeSpace.ts';
import { WormholeClassComp } from '@/hooks/Mapper/components/map/components/WormholeClassComp';
import { UnsplashedSignature } from '@/hooks/Mapper/components/map/components/UnsplashedSignature';
import { useMapState } from '@/hooks/Mapper/components/map/MapProvider.tsx';
import { getSystemClassStyles, prepareUnsplashedChunks } from '@/hooks/Mapper/components/map/helpers';
import { sortWHClasses } from '@/hooks/Mapper/helpers';
import { PrimeIcons } from 'primereact/api';
import { LabelsManager } from '@/hooks/Mapper/utils/labelsManager.ts';
import { OutCommand } from '@/hooks/Mapper/types';
import { useDoubleClick } from '@/hooks/Mapper/hooks/useDoubleClick.ts';
import { REGIONS_MAP, Spaces } from '@/hooks/Mapper/constants';
const SpaceToClass: Record<string, string> = {
[Spaces.Caldari]: classes.Caldaria,
[Spaces.Matar]: classes.Mataria,
[Spaces.Amarr]: classes.Amarria,
[Spaces.Gallente]: classes.Gallente,
};
const sortedLabels = (labels: string[]) => {
if (!labels) {
return [];
}
return LABELS_ORDER.filter(x => labels.includes(x)).map(x => LABELS_INFO[x]);
};
export const getActivityType = (count: number) => {
if (count <= 5) {
return 'activityNormal';
}
if (count <= 30) {
return 'activityWarn';
}
return 'activityDanger';
};
// eslint-disable-next-line react/display-name
export const SolarSystemNode = memo(({ data, selected }: WrapNodeProps<MapSolarSystemType>) => {
const { interfaceSettings } = useMapRootState();
const { isShowUnsplashedSignatures } = interfaceSettings;
const {
system_class,
security,
class_title,
solar_system_id,
statics,
effect_name,
region_name,
region_id,
is_shattered,
solar_system_name,
} = data.system_static_info;
const signatures = data.system_signatures;
const { locked, name, tag, status, labels, id } = data || {};
const customName = solar_system_name !== name ? name : undefined;
const {
data: {
characters,
presentCharacters,
wormholesData,
hubs,
kills,
userCharacters,
isConnecting,
hoverNodeId,
visibleNodes,
showKSpaceBG,
isThickConnections,
},
outCommand,
} = useMapState();
const visible = useMemo(() => visibleNodes.has(id), [id, visibleNodes]);
const charactersInSystem = useMemo(() => {
return characters.filter(c => c.location?.solar_system_id === solar_system_id).filter(c => c.online);
// eslint-disable-next-line
}, [characters, presentCharacters, solar_system_id]);
const isWormhole = isWormholeSpace(system_class);
const classTitleColor = useMemo(
() => getSystemClassStyles({ systemClass: system_class, security }),
[security, system_class],
);
const sortedStatics = useMemo(() => sortWHClasses(wormholesData, statics), [wormholesData, statics]);
const lebM = useMemo(() => new LabelsManager(labels ?? ''), [labels]);
const labelsInfo = useMemo(() => sortedLabels(lebM.list), [lebM]);
const labelCustom = useMemo(() => lebM.customLabel, [lebM]);
const killsCount = useMemo(() => {
const systemKills = kills[solar_system_id];
if (!systemKills) {
return null;
}
return systemKills;
}, [kills, solar_system_id]);
const hasUserCharacters = useMemo(() => {
return charactersInSystem.some(x => userCharacters.includes(x.eve_id));
}, [charactersInSystem, userCharacters]);
const dbClick = useDoubleClick(() => {
outCommand({
type: OutCommand.openSettings,
data: {
system_id: solar_system_id.toString(),
},
});
});
const showHandlers = isConnecting || hoverNodeId === id;
const space = showKSpaceBG ? REGIONS_MAP[region_id] : '';
const regionClass = showKSpaceBG ? SpaceToClass[space] : null;
const [unsplashedLeft, unsplashedRight] = useMemo(() => {
if (!isShowUnsplashedSignatures) {
return [[], []];
}
return prepareUnsplashedChunks(
signatures
.filter(s => s.group === 'Wormhole' && !s.linked_system)
.map(s => ({
eve_id: s.eve_id,
type: s.type,
custom_info: s.custom_info,
})),
);
}, [isShowUnsplashedSignatures, signatures]);
return (
<>
{visible && (
<div className={classes.Bookmarks}>
{labelCustom !== '' && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.custom)}>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">{labelCustom}</span>
</div>
)}
{is_shattered && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.shattered)}>
<span className={clsx('pi pi-chart-pie', classes.icon)} />
</div>
)}
{killsCount && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[getActivityType(killsCount)])}>
<div className={clsx(classes.BookmarkWithIcon)}>
<span className={clsx(PrimeIcons.BOLT, classes.icon)} />
<span className={clsx(classes.text)}>{killsCount}</span>
</div>
</div>
)}
{labelsInfo.map(x => (
<div key={x.id} className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}>
{x.shortName}
</div>
))}
</div>
)}
<div
className={clsx(classes.RootCustomNode, regionClass, classes[STATUS_CLASSES[status]], {
[classes.selected]: selected,
})}
>
{visible && (
<>
<div className={classes.HeadRow}>
<div className={clsx(classes.classTitle, classTitleColor, '[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]')}>
{class_title ?? '-'}
</div>
{tag != null && tag !== '' && (
<div className={clsx(classes.TagTitle, 'text-sky-400 font-medium')}>{tag}</div>
)}
<div
className={clsx(
classes.classSystemName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] flex-grow overflow-hidden text-ellipsis whitespace-nowrap font-sans',
)}
>
{solar_system_name}
</div>
{isWormhole && (
<div className={classes.statics}>
{sortedStatics.map(x => (
<WormholeClassComp key={x} id={x} />
))}
</div>
)}
{effect_name !== null && isWormhole && (
<div className={clsx(classes.effect, EFFECT_BACKGROUND_STYLES[effect_name])}></div>
)}
</div>
<div className={clsx(classes.BottomRow, 'flex items-center justify-between')}>
{customName && (
<div className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-blue-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5">
{customName}
</div>
)}
{!isWormhole && !customName && (
<div
className={clsx(
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-stone-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5',
)}
>
{region_name}
</div>
)}
{isWormhole && !customName && <div />}
<div className="flex items-center justify-end">
<div className="flex gap-1 items-center">
{locked && <i className={PrimeIcons.LOCK} style={{ fontSize: '0.45rem', fontWeight: 'bold' }}></i>}
{hubs.includes(solar_system_id.toString()) && (
<i className={PrimeIcons.MAP_MARKER} style={{ fontSize: '0.45rem', fontWeight: 'bold' }}></i>
)}
{charactersInSystem.length > 0 && (
<div className={clsx(classes.localCounter, { ['text-amber-300']: hasUserCharacters })}>
<i className="pi pi-users" style={{ fontSize: '0.50rem' }}></i>
<span className="font-sans">{charactersInSystem.length}</span>
</div>
)}
</div>
</div>
</div>
</>
)}
</div>
{visible && isShowUnsplashedSignatures && (
<div className={classes.Unsplashed}>
{unsplashedLeft.map(x => (
<UnsplashedSignature key={x.sig_id} signature={x} />
))}
</div>
)}
{visible && isShowUnsplashedSignatures && (
<div className={clsx([classes.Unsplashed, classes['Unsplashed--right']])}>
{unsplashedRight.map(x => (
<UnsplashedSignature key={x.sig_id} signature={x} />
))}
</div>
)}
<div onMouseDownCapture={dbClick} className={classes.Handlers}>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleTop, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Top}
id="a"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleRight, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Right}
id="b"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleBottom, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Bottom}
id="c"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleLeft, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Left}
id="d"
/>
</div>
</>
);
});

View File

@@ -1,227 +0,0 @@
import { memo } from 'react';
import { Handle, Position } from 'reactflow';
import clsx from 'clsx';
import classes from './SolarSystemNodeDefault.module.scss';
import { PrimeIcons } from 'primereact/api';
import { useSolarSystemNode } from '../../hooks/useSolarSystemNode';
import {
MARKER_BOOKMARK_BG_STYLES,
STATUS_CLASSES,
EFFECT_BACKGROUND_STYLES,
} from '@/hooks/Mapper/components/map/constants';
import { WormholeClassComp } from '@/hooks/Mapper/components/map/components/WormholeClassComp';
import { UnsplashedSignature } from '@/hooks/Mapper/components/map/components/UnsplashedSignature';
export const SolarSystemNodeDefault = memo(props => {
const {
charactersInSystem,
classTitle,
classTitleColor,
customName,
effectName,
hasUserCharacters,
hubs,
visible,
labelCustom,
labelsInfo,
locked,
isShattered,
isThickConnections,
isWormhole,
killsCount,
killsActivityType,
regionClass,
regionName,
status,
selected,
tag,
showHandlers,
systemName,
sortedStatics,
solarSystemId,
unsplashedLeft,
unsplashedRight,
dbClick: handleDbClick,
} = useSolarSystemNode(props);
return (
<>
{visible && (
<div className={classes.Bookmarks}>
{labelCustom !== '' && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.custom)}>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">{labelCustom}</span>
</div>
)}
{isShattered && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.shattered)}>
<span className={clsx('pi pi-chart-pie', classes.icon)} />
</div>
)}
{killsCount && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[killsActivityType!])}>
<div className={clsx(classes.BookmarkWithIcon)}>
<span className={clsx(PrimeIcons.BOLT, classes.icon)} />
<span className={clsx(classes.text)}>{killsCount}</span>
</div>
</div>
)}
{labelsInfo.map(x => (
<div key={x.id} className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}>
{x.shortName}
</div>
))}
</div>
)}
<div
className={clsx(classes.RootCustomNode, regionClass && classes[regionClass], classes[STATUS_CLASSES[status]], {
[classes.selected]: selected,
})}
>
{visible && (
<>
<div className={classes.HeadRow}>
<div className={clsx(classes.classTitle, classTitleColor, '[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]')}>
{classTitle ?? '-'}
</div>
{tag != null && tag !== '' && (
<div className={clsx(classes.TagTitle, 'text-sky-400 font-medium')}>{tag}</div>
)}
<div
className={clsx(
classes.classSystemName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] flex-grow overflow-hidden text-ellipsis whitespace-nowrap font-sans',
)}
>
{systemName}
</div>
{isWormhole && (
<div className={classes.statics}>
{sortedStatics.map(whClass => (
<WormholeClassComp key={whClass} id={whClass} />
))}
</div>
)}
{effectName !== null && isWormhole && (
<div className={clsx(classes.effect, EFFECT_BACKGROUND_STYLES[effectName])} />
)}
</div>
<div className={clsx(classes.BottomRow, 'flex items-center justify-between')}>
{customName && (
<div className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-blue-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5">
{customName}
</div>
)}
{!isWormhole && !customName && (
<div className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-stone-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5">
{regionName}
</div>
)}
{isWormhole && !customName && <div />}
<div className="flex items-center justify-end">
<div className="flex gap-1 items-center">
{locked && <i className={PrimeIcons.LOCK} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />}
{hubs.includes(solarSystemId.toString()) && (
<i className={PrimeIcons.MAP_MARKER} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />
)}
{charactersInSystem.length > 0 && (
<div
className={clsx(classes.localCounter, {
['text-amber-300']: hasUserCharacters,
})}
>
<i className="pi pi-users" style={{ fontSize: '0.50rem' }} />
<span className="font-sans">{charactersInSystem.length}</span>
</div>
)}
</div>
</div>
</div>
</>
)}
</div>
{visible && (
<>
{unsplashedLeft.length > 0 && (
<div className={classes.Unsplashed}>
{unsplashedLeft.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
)}
{unsplashedRight.length > 0 && (
<div className={clsx(classes.Unsplashed, classes['Unsplashed--right'])}>
{unsplashedRight.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
)}
</>
)}
<div onMouseDownCapture={handleDbClick} className={classes.Handlers}>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleTop, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Top}
id="a"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleRight, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Right}
id="b"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleBottom, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Bottom}
id="c"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleLeft, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Left}
id="d"
/>
</div>
</>
);
});
SolarSystemNodeDefault.displayName = 'SolarSystemNodeDefault';

View File

@@ -1,407 +0,0 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
$pastel-blue: #5a7d9a;
$pastel-pink: #d291bc;
$pastel-green: #88b04b;
$pastel-yellow: #ffdd59;
$dark-bg: #2d2d2d;
$text-color: #ffffff;
$tooltip-bg: #202020; // Dark background for tooltips
.RootCustomNode {
display: flex;
width: 130px;
height: 34px;
flex-direction: column;
padding: 2px 6px;
font-size: 10px;
background-color: var(--rf-node-bg-color, #202020) !important;
color: var(--rf-text-color, #ffffff);
font-family: var(--rf-node-font-family, inherit) !important;
font-weight: var(--rf-node-font-weight, inherit) !important;
box-shadow: 0 0 5px rgba($dark-bg, 0.5);
border: 1px solid darken($pastel-blue, 10%);
border-radius: 5px;
position: relative;
z-index: 1;
overflow: hidden;
&.Mataria,
&.Amarria,
&.Gallente,
&.Caldaria {
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
background-position: 50% 50%;
z-index: -1;
background-repeat: no-repeat;
border-radius: 3px;
}
}
&.Mataria {
&::before {
background-image: url('/images/mataria-180.png');
opacity: 0.6;
background-position-x: 1px;
background-position-y: -14px;
}
}
&.Caldaria {
&::before {
background-image: url('/images/caldaria-180.png');
opacity: 0.6;
background-position-x: 1px;
background-position-y: -10px;
}
}
&.Amarria {
&::before {
opacity: 0.45;
background-image: url('/images/amarr-180.png');
background-position-x: 0;
background-position-y: -13px;
}
}
&.Gallente {
&::before {
opacity: 0.5;
background-image: url('/images/gallente-180.png');
background-position-x: 1px;
background-position-y: 0;
}
}
&.selected {
border-color: $pastel-pink;
box-shadow: 0 0 10px #9a1af1c2;
}
&.tooltip {
background-color: $tooltip-bg;
color: $text-color;
padding: 5px 10px;
border-radius: 3px;
border: 1px solid $pastel-pink;
}
&.eve-system-status-home {
border: 1px solid var(--eve-solar-system-status-color-home-dark30);
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-home),
transparent
);
&.selected {
border-color: var(--eve-solar-system-status-color-home);
}
}
&.eve-system-status-friendly {
border: 1px solid var(--eve-solar-system-status-color-friendly-dark20);
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-friendly-dark30),
transparent
);
&.selected {
border-color: var(--eve-solar-system-status-color-friendly-dark5);
}
}
&.eve-system-status-lookingFor {
border: 1px solid var(--eve-solar-system-status-color-lookingFor-dark15);
background-image: linear-gradient(275deg, #45ff8f2f, #457fff2f);
&.selected {
border-color: $pastel-pink;
}
}
&.eve-system-status-warning {
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-warning),
transparent
);
}
&.eve-system-status-dangerous {
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-dangerous),
transparent
);
}
&.eve-system-status-target {
background-image: linear-gradient(
275deg,
var(--eve-solar-system-status-target),
transparent
);
}
}
.Bookmarks {
position: absolute;
width: 100%;
z-index: 1;
display: flex;
left: 4px;
& > .Bookmark {
min-width: 13px;
height: 22px;
position: relative;
top: -13px;
border-radius: 5px;
color: #ffffff;
font-size: 8px;
text-align: center;
padding-top: 2px;
font-weight: bolder;
padding-left: 3px;
padding-right: 3px;
//background-color: #833ca4;
&:not(:first-child) {
box-shadow: inset 4px -3px 4px rgba(0, 0, 0, 0.3);
}
}
.BookmarkWithIcon {
display: flex;
justify-content: center;
align-items: center;
margin-top: -2px;
text-shadow: 0 0 3px rgba(0, 0, 0, 1);
padding-right: 2px;
& > .icon {
width: 8px;
height: 8px;
font-size: 8px;
}
& > .text {
margin-top: 1px;
font-size: 9px;
}
}
}
.Unsplashed {
position: absolute;
width: calc(50% - 4px);
z-index: -1;
display: flex;
flex-wrap: wrap;
gap: 2px;
left: 2px;
&--right {
left: calc(50% + 6px);
}
& > .Signature {
width: 13px;
height: 4px;
position: relative;
top: 3px;
border-radius: 5px;
color: #ffffff;
font-size: 8px;
text-align: center;
padding-top: 2px;
font-weight: bolder;
padding-left: 3px;
padding-right: 3px;
display: block;
background-color: #833ca4;
&:not(:first-child) {
box-shadow: inset 4px -3px 4px rgba(0, 0, 0, 0.3);
}
}
}
.icon {
width: 8px;
height: 8px;
font-size: 8px;
}
.HeadRow {
display: flex;
align-items: center;
gap: 3px;
font-size: 11px;
line-height: 14px;
font-weight: 500;
position: relative;
top: 1px;
.classTitle {
font-size: 11px;
font-weight: bold;
text-shadow: 0 0 2px rgb(0 0 0 / 73%);
}
.TagTitle {
font-size: 11px;
font-weight: medium;
text-shadow: 0 0 2px rgba(231, 146, 52, 0.73);
color: var(--rf-tag-color, #38BDF8);
}
/* Firefox kostyl */
@-moz-document url-prefix() {
.classSystemName {
font-family: inherit !important;
font-weight: bold;
}
}
.classSystemName {
font-family: inherit !important;
font-weight: bold;
}
.solarSystemName {
}
}
.BottomRow {
display: flex;
justify-content: space-between;
align-items: center;
height: 19px;
.regionName {
color: var(--rf-region-name, #D6D3D1)
}
.customName {
color: var(--rf-custom-name, #93C5FD)
}
.localCounter {
display: flex;
//align-items: center;
gap: 2px;
.hasUserCharacters {
color: var(--rf-has-user-characters, #fbbf24);
}
& > i {
position: relative;
top: 1px;
}
& > span {
font-size: 9px;
line-height: 9px;
font-weight: 500;
//margin-top: 1px;
}
}
}
.effect {
width: 8px;
height: 8px;
margin-top: -2px;
box-sizing: border-box;
border-radius: 2px;
margin-left: 1px;
}
.statics {
display: flex;
gap: 2px;
font-size: 8px;
& > * {
line-height: 10px;
}
/* Firefox kostyl */
@-moz-document url-prefix() {
position: relative;
top: -1px;
}
}
.Handlers {
position: absolute;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.Handle {
min-width: initial;
min-height: initial;
border: 1px solid $pastel-blue;
width: 5px;
height: 5px;
&.selected {
border-color: $pastel-pink;
}
&.HandleTop {
top: -2px;
}
&.HandleRight {
right: -2px;
}
&.HandleBottom {
bottom: -2px;
}
&.HandleLeft {
left: -2px;
}
&.Tick {
width: 7px;
height: 7px;
&.HandleTop {
top: -3px;
}
&.HandleRight {
right: -3px;
}
&.HandleBottom {
bottom: -3px;
}
&.HandleLeft {
left: -3px;
}
}
}

View File

@@ -1,235 +0,0 @@
import { memo } from 'react';
import { Handle, Position } from 'reactflow';
import clsx from 'clsx';
import classes from './SolarSystemNodeTheme.module.scss';
import { PrimeIcons } from 'primereact/api';
import { useSolarSystemNode } from '../../hooks/useSolarSystemNode';
import {
MARKER_BOOKMARK_BG_STYLES,
STATUS_CLASSES,
EFFECT_BACKGROUND_STYLES,
} from '@/hooks/Mapper/components/map/constants';
import { WormholeClassComp } from '@/hooks/Mapper/components/map/components/WormholeClassComp';
import { UnsplashedSignature } from '@/hooks/Mapper/components/map/components/UnsplashedSignature';
export const SolarSystemNodeTheme = memo(props => {
const {
charactersInSystem,
classTitle,
classTitleColor,
customName,
effectName,
hasUserCharacters,
hubs,
visible,
labelCustom,
labelsInfo,
locked,
isShattered,
isThickConnections,
isWormhole,
killsCount,
killsActivityType,
regionClass,
regionName,
status,
selected,
tag,
showHandlers,
systemName,
sortedStatics,
solarSystemId,
unsplashedLeft,
unsplashedRight,
dbClick: handleDbClick,
} = useSolarSystemNode(props);
return (
<>
{visible && (
<div className={classes.Bookmarks}>
{labelCustom !== '' && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.custom)}>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">{labelCustom}</span>
</div>
)}
{isShattered && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.shattered)}>
<span className={clsx('pi pi-chart-pie', classes.icon)} />
</div>
)}
{killsCount && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[killsActivityType!])}>
<div className={clsx(classes.BookmarkWithIcon)}>
<span className={clsx(PrimeIcons.BOLT, classes.icon)} />
<span className={clsx(classes.text)}>{killsCount}</span>
</div>
</div>
)}
{labelsInfo.map(x => (
<div key={x.id} className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}>
{x.shortName}
</div>
))}
</div>
)}
<div
className={clsx(classes.RootCustomNode, regionClass && classes[regionClass], classes[STATUS_CLASSES[status]], {
[classes.selected]: selected,
})}
>
{visible && (
<>
<div className={classes.HeadRow}>
<div className={clsx(classes.classTitle, classTitleColor, '[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]')}>
{classTitle ?? '-'}
</div>
{tag != null && tag !== '' && <div className={clsx(classes.TagTitle)}>{tag}</div>}
<div
className={clsx(
classes.classSystemName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] flex-grow overflow-hidden text-ellipsis whitespace-nowrap',
)}
>
{systemName}
</div>
{isWormhole && (
<div className={classes.statics}>
{sortedStatics.map(whClass => (
<WormholeClassComp key={whClass} id={whClass} />
))}
</div>
)}
{effectName !== null && isWormhole && (
<div className={clsx(classes.effect, EFFECT_BACKGROUND_STYLES[effectName])} />
)}
</div>
<div className={clsx(classes.BottomRow, 'flex items-center justify-between')}>
{customName && (
<div
className={clsx(
classes.CustomName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] whitespace-nowrap overflow-hidden text-ellipsis mr-0.5',
)}
>
{customName}
</div>
)}
{!isWormhole && !customName && (
<div
className={clsx(
classes.RegionName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] whitespace-nowrap overflow-hidden text-ellipsis mr-0.5',
)}
>
{regionName}
</div>
)}
{isWormhole && !customName && <div />}
<div className="flex items-center justify-end">
<div className="flex gap-1 items-center">
{locked && <i className={PrimeIcons.LOCK} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />}
{hubs.includes(solarSystemId.toString()) && (
<i className={PrimeIcons.MAP_MARKER} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />
)}
{charactersInSystem.length > 0 && (
<div
className={clsx(classes.localCounter, {
[classes.hasUserCharacters]: hasUserCharacters,
})}
>
<i className="pi pi-users" style={{ fontSize: '0.50rem' }} />
<span className="font-sans">{charactersInSystem.length}</span>
</div>
)}
</div>
</div>
</div>
</>
)}
</div>
{visible && (
<>
{unsplashedLeft.length > 0 && (
<div className={classes.Unsplashed}>
{unsplashedLeft.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
)}
{unsplashedRight.length > 0 && (
<div className={clsx(classes.Unsplashed, classes['Unsplashed--right'])}>
{unsplashedRight.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
)}
</>
)}
<div onMouseDownCapture={handleDbClick} className={classes.Handlers}>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleTop, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Top}
id="a"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleRight, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Right}
id="b"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleBottom, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Bottom}
id="c"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleLeft, {
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Left}
id="d"
/>
</div>
</>
);
});
SolarSystemNodeTheme.displayName = 'SolarSystemNodeTheme';

View File

@@ -1,2 +1 @@
export * from './SolarSystemNodeDefault';
export * from './SolarSystemNodeTheme';
export * from './SolarSystemNode';

View File

@@ -9,7 +9,7 @@
width: 13px;
height: 4px;
border-radius: 4px;
color: var(--text-color);
color: #ffffff;
font-size: 8px;
text-align: center;
font-weight: bolder;

View File

@@ -1,44 +0,0 @@
import { useEffect, useState } from 'react';
import { BackgroundVariant } from 'reactflow';
export function useBackgroundVars(themeName?: string) {
const [variant, setVariant] = useState<BackgroundVariant>(BackgroundVariant.Dots);
const [gap, setGap] = useState<number>(16);
const [size, setSize] = useState<number>(1);
const [color, setColor] = useState('#81818b');
useEffect(() => {
// match any element whose entire `class` attribute ends with "-theme"
let themeEl = document.querySelector('[class$="-theme"]');
// If none is found, fall back to the <html> element
if (!themeEl) {
themeEl = document.documentElement;
}
const style = getComputedStyle(themeEl as HTMLElement);
const rawVariant = style.getPropertyValue('--rf-bg-variant').replace(/['"]/g, '').trim().toLowerCase();
let finalVariant: BackgroundVariant = BackgroundVariant.Dots;
if (rawVariant === 'lines') {
finalVariant = BackgroundVariant.Lines;
} else if (rawVariant === 'cross') {
finalVariant = BackgroundVariant.Cross;
}
const cssVarGap = style.getPropertyValue('--rf-bg-gap');
const cssVarSize = style.getPropertyValue('--rf-bg-size');
const cssColor = style.getPropertyValue('--rf-bg-pattern-color');
const gapNum = parseInt(cssVarGap, 10) || 16;
const sizeNum = parseInt(cssVarSize, 10) || 1;
setVariant(finalVariant);
setGap(gapNum);
setSize(sizeNum);
setColor(cssColor);
}, [themeName]);
return { variant, gap, size, color };
}

View File

@@ -1,189 +0,0 @@
import { useMemo } from 'react';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { useMapGetOption } from '@/hooks/Mapper/mapRootProvider/hooks/api';
import { useMapState } from '@/hooks/Mapper/components/map/MapProvider';
import { useDoubleClick } from '@/hooks/Mapper/hooks/useDoubleClick';
import { REGIONS_MAP, Spaces } from '@/hooks/Mapper/constants';
import { isWormholeSpace } from '@/hooks/Mapper/components/map/helpers/isWormholeSpace';
import { getSystemClassStyles, prepareUnsplashedChunks } from '@/hooks/Mapper/components/map/helpers';
import { sortWHClasses } from '@/hooks/Mapper/helpers';
import { LabelsManager } from '@/hooks/Mapper/utils/labelsManager';
import { OutCommand } from '@/hooks/Mapper/types';
import { LABELS_INFO, LABELS_ORDER } from '@/hooks/Mapper/components/map/constants';
function getActivityType(count: number) {
if (count <= 5) return 'activityNormal';
if (count <= 30) return 'activityWarn';
return 'activityDanger';
}
const SpaceToClass: Record<string, string> = {
[Spaces.Caldari]: 'Caldaria',
[Spaces.Matar]: 'Mataria',
[Spaces.Amarr]: 'Amarria',
[Spaces.Gallente]: 'Gallente',
};
function sortedLabels(labels: string[]) {
if (!labels) return [];
return LABELS_ORDER.filter(x => labels.includes(x)).map(x => LABELS_INFO[x]);
}
export function useSolarSystemNode(props: any) {
const { data, selected, id } = props;
const {
system_static_info,
system_signatures,
locked,
name,
tag,
status,
labels,
temporary_name,
linked_sig_eve_id: linkedSigEveId = '',
} = data;
const {
system_class,
security,
class_title,
solar_system_id,
statics,
effect_name,
region_name,
region_id,
is_shattered,
solar_system_name,
} = system_static_info;
// Global map state
const { interfaceSettings } = useMapRootState();
const { isShowUnsplashedSignatures } = interfaceSettings;
const isTempSystemNameEnabled = useMapGetOption('show_temp_system_name') === 'true';
const isShowLinkedSigId = useMapGetOption('show_linked_signature_id') === 'true';
const {
data: {
characters,
presentCharacters,
wormholesData,
hubs,
kills,
userCharacters,
isConnecting,
hoverNodeId,
visibleNodes,
showKSpaceBG,
isThickConnections,
},
outCommand,
} = useMapState();
// logic
const visible = useMemo(() => visibleNodes.has(id), [id, visibleNodes]);
const charactersInSystem = useMemo(() => {
return characters.filter(c => c.location?.solar_system_id === solar_system_id).filter(c => c.online);
// eslint-disable-next-line
}, [characters, presentCharacters, solar_system_id]);
const isWormhole = isWormholeSpace(system_class);
const classTitleColor = useMemo(
() => getSystemClassStyles({ systemClass: system_class, security }),
[security, system_class],
);
const sortedStatics = useMemo(() => sortWHClasses(wormholesData, statics), [wormholesData, statics]);
const linkedSigPrefix = useMemo(() => (linkedSigEveId ? linkedSigEveId.split('-')[0] : null), [linkedSigEveId]);
const labelsManager = useMemo(() => new LabelsManager(labels ?? ''), [labels]);
const labelsInfo = useMemo(() => sortedLabels(labelsManager.list), [labelsManager]);
const labelCustom = useMemo(
() =>
isShowLinkedSigId && linkedSigPrefix
? `${linkedSigPrefix}${labelsManager.customLabel}`
: labelsManager.customLabel,
[linkedSigPrefix, isShowLinkedSigId, labelsManager],
);
const killsCount = useMemo(() => kills[solar_system_id] ?? null, [kills, solar_system_id]);
const killsActivityType = killsCount ? getActivityType(killsCount) : null;
const hasUserCharacters = useMemo(() => {
return charactersInSystem.some(x => userCharacters.includes(x.eve_id));
}, [charactersInSystem, userCharacters]);
const dbClick = useDoubleClick(() => {
outCommand({
type: OutCommand.openSettings,
data: { system_id: solar_system_id.toString() },
});
});
const showHandlers = isConnecting || hoverNodeId === id;
const space = showKSpaceBG ? REGIONS_MAP[region_id] : '';
const regionClass = showKSpaceBG ? SpaceToClass[space] : null;
const systemName = (isTempSystemNameEnabled && temporary_name) || solar_system_name;
const customName = (isTempSystemNameEnabled && temporary_name && name) || (solar_system_name !== name && name);
const [unsplashedLeft, unsplashedRight] = useMemo(() => {
if (!isShowUnsplashedSignatures) {
return [[], []];
}
return prepareUnsplashedChunks(
system_signatures
.filter(s => s.group === 'Wormhole' && !s.linked_system)
.map(s => ({
eve_id: s.eve_id,
type: s.type,
custom_info: s.custom_info,
})),
);
}, [isShowUnsplashedSignatures, system_signatures]);
const nodeVars = {
// original props
id,
selected,
// computed
visible,
isWormhole,
classTitleColor,
killsCount,
killsActivityType,
hasUserCharacters,
showHandlers,
regionClass,
systemName,
customName,
labelCustom,
isShattered: is_shattered,
tag,
status,
labelsInfo,
dbClick,
sortedStatics,
effectName: effect_name,
regionName: region_name,
solarSystemId: solar_system_id,
solarSystemName: solar_system_name,
locked,
hubs,
name: name,
isConnecting,
hoverNodeId,
charactersInSystem,
unsplashedLeft,
unsplashedRight,
isThickConnections,
classTitle: class_title,
temporaryName: temporary_name,
};
return nodeVars;
}

View File

@@ -1,6 +1,5 @@
import { SolarSystemRawType } from '@/hooks/Mapper/types/system';
import { SolarSystemConnection } from '@/hooks/Mapper/types';
import { XYPosition } from 'reactflow';
export type MapSolarSystemType = Omit<SolarSystemRawType, 'position'>;
@@ -8,5 +7,3 @@ export type OnMapSelectionChange = (event: {
systems: string[];
connections: Pick<SolarSystemConnection, 'source' | 'target'>[];
}) => void;
export type OnMapAddSystemCallback = (props: { coordinates: XYPosition | null }) => void;

View File

@@ -1,31 +0,0 @@
@import './eve-common-variables';
@import './eve-common';
.default-theme {
--rf-bg-color: #0C0A09;
--rf-soft-bg-color: #171717;
--rf-node-bg-color: #202020;
--rf-node-soft-bg-color: #202020;
--rf-text-color: #ffffff;
--rf-tag-color: #38BDF8;
--rf-region-name: #D6D3D1;
--rf-custom-name: #93C5FD;
--rf-bg-variant: "dots";
--rf-bg-gap: 15;
--rf-bg-size: 1;
--rf-bg-pattern-color: #81818a;
--pastel-blue: #5a7d9a;
--pastel-pink: #d291bc;
--pastel-green: #88b04b;
--pastel-yellow: #ffdd59;
--dark-bg: #2d2d2d;
--text-color: #ffffff;
--tooltip-bg: #202020;
}

View File

@@ -1,121 +1,78 @@
$eve-link-color-default: #333;
$eve-link-color-top-mass-0: #333;
$eve-link-color-top-mass-1: #5a4520;
$eve-link-color-top-mass-2: #672c2c;
$eve-link-color-middle-mass-0: #333;
$eve-link-color-middle-mass-1: #333;
$eve-link-color-middle-mass-2: #333;
$eve-link-color-middle-time-0: #5c5c5c;
$eve-link-color-middle-time-1: #ff00cd;
$eve-link-color-middle-time-1-border: #99f3ff;
$friendlyBase: #3bbd39;
$friendlyAlpha: #3bbd3952;
$friendlyDark20: darken($friendlyBase, 20%);
$friendlyDark30: darken($friendlyBase, 30%);
$friendlyDark5: darken($friendlyBase, 5%);
$eve-link-color-top-mass-1-time-1: #796300;
$eve-link-color-top-mass-2-time-1: #8c1717;
$eve-link-color-temp: orange;
$lookingForBase: #43c2fd;
$lookingForAlpha: rgba(67, 176, 253, 0.48);
$lookingForDark15: darken($lookingForBase, 15%);
$eve-effect-pulsar: #40aef5;
$eve-effect-magnetar: #f058f8;
$eve-effect-wolfRayet: #ef7843;
$eve-effect-blackHole: #1b1b1b;
$eve-effect-cataclysmicVariable: #ffea90;
$eve-effect-redGiant: #fd3c3c;
$eve-effect-dazhLiminalityLocus: #ff6464;
$eve-effect-imperialStellarObservatory: #6991ce;
$eve-effect-stateStellarObservatory: #6991ce;
$eve-effect-republicStellarObservatory: #6991ce;
$eve-effect-federalStellarObservatory: #6991ce;
$homeBase: rgb(197, 253, 67);
$homeAlpha: rgba(197, 253, 67, 0.32);
$homeDark30: darken($homeBase, 30%);
$eve-wh-type-color-high: #5dffd2;
$eve-wh-type-color-low: #f79400;
$eve-wh-type-color-null: #fc3c3c;
$eve-wh-type-color-c1: #69bfce;
$eve-wh-type-color-c2: #6991ce;
$eve-wh-type-color-c3: #a8cb70;
$eve-wh-type-color-c4: #e39c68;
$eve-wh-type-color-c5: #de8686;
$eve-wh-type-color-c6: #e76363;
$eve-wh-type-color-c13: #988cb5;
$eve-wh-type-color-drifter: #ff44f6;
$eve-wh-type-color-thera: #ffffff;
$eve-wh-type-color-zarzakh: #212121;
$eve-security-color-10: #2c74df;
$eve-security-color-09: #3998e8;
$eve-security-color-08: #4dcbf5;
$eve-security-color-07: #60d8a2;
$eve-security-color-06: #71e454;
$eve-security-color-05: #f2fc81;
$eve-security-color-04: #d96c07;
$eve-security-color-03: #cb440f;
$eve-security-color-02: #b91117;
$eve-security-color-01: #732020;
$eve-security-color-00: #8b3263;
$eve-security-color-m-01: #8b3263;
$eve-security-color-m-02: #8b3263;
$eve-security-color-m-03: #8b3263;
$eve-security-color-m-04: #8b3263;
$eve-security-color-m-05: #8b3263;
$eve-security-color-m-06: #8b3263;
$eve-security-color-m-07: #8b3263;
$eve-security-color-m-08: #8b3263;
$eve-security-color-m-09: #8b3263;
$eve-security-color-m-10: #8b3263;
:root {
--pastel-blue: #5a7d9a;
--pastel-pink: #d291bc;
--pastel-green: #88b04b;
--pastel-yellow: #ffdd59;
--dark-bg: #2d2d2d;
--text-color: #ffffff;
--tooltip-bg: #202020;
$eve-solar-system-status-unknown: transparent;
$eve-solar-system-status-friendly: #3bbd3952;
$eve-solar-system-status-warning: #906518a6;
$eve-solar-system-status-target: #b439ff6b;
$eve-solar-system-status-dangerous: #d54040;
$eve-solar-system-status-lookingFor: rgba(67, 176, 253, 0.48);
$eve-solar-system-status-home: rgb(197, 253, 67);
--pastel-blue-darken10: #4f6b86;
--pastel-blue-lighten10: #6da3af;
--pastel-pink-darken10: #bb7ca9;
--pastel-pink-lighten10: #e0a6cb;
--pastel-green-darken10: #79a244;
--pastel-green-lighten10: #99cf52;
--pastel-yellow-darken10: #e6c44f;
--pastel-yellow-lighten10: #ffe874;
--eve-link-color-default: #333;
--eve-link-color-top-mass-0: #333;
--eve-link-color-top-mass-1: #5a4520;
--eve-link-color-top-mass-2: #672c2c;
--eve-link-color-middle-mass-0: #333;
--eve-link-color-middle-mass-1: #333;
--eve-link-color-middle-mass-2: #333;
--eve-link-color-middle-time-0: #5c5c5c;
--eve-link-color-middle-time-1: #ff00cd;
--eve-link-color-middle-time-1-border: #99f3ff;
--eve-link-color-top-mass-1-time-1: #796300;
--eve-link-color-top-mass-2-time-1: #8c1717;
--eve-link-color-temp: orange;
--eve-effect-pulsar: #40aef5;
--eve-effect-magnetar: #f058f8;
--eve-effect-wolfRayet: #ef7843;
--eve-effect-blackHole: #1b1b1b;
--eve-effect-cataclysmicVariable: #ffea90;
--eve-effect-redGiant: #fd3c3c;
--eve-effect-dazhLiminalityLocus: #ff6464;
--eve-effect-imperialStellarObservatory: #6991ce;
--eve-effect-stateStellarObservatory: #6991ce;
--eve-effect-republicStellarObservatory: #6991ce;
--eve-effect-federalStellarObservatory: #6991ce;
--eve-wh-type-color-high: #5dffd2;
--eve-wh-type-color-low: #f79400;
--eve-wh-type-color-null: #fc3c3c;
--eve-wh-type-color-c1: #69bfce;
--eve-wh-type-color-c2: #6991ce;
--eve-wh-type-color-c3: #a8cb70;
--eve-wh-type-color-c4: #e39c68;
--eve-wh-type-color-c5: #de8686;
--eve-wh-type-color-c6: #e76363;
--eve-wh-type-color-c13: #988cb5;
--eve-wh-type-color-drifter: #ff44f6;
--eve-wh-type-color-thera: #ffffff;
--eve-wh-type-color-zarzakh: #212121;
--eve-security-color-10: #2c74df;
--eve-security-color-09: #3998e8;
--eve-security-color-08: #4dcbf5;
--eve-security-color-07: #60d8a2;
--eve-security-color-06: #71e454;
--eve-security-color-05: #f2fc81;
--eve-security-color-04: #d96c07;
--eve-security-color-03: #cb440f;
--eve-security-color-02: #b91117;
--eve-security-color-01: #732020;
--eve-security-color-00: #8b3263;
--eve-security-color-m-01: #8b3263;
--eve-security-color-m-02: #8b3263;
--eve-security-color-m-03: #8b3263;
--eve-security-color-m-04: #8b3263;
--eve-security-color-m-05: #8b3263;
--eve-security-color-m-06: #8b3263;
--eve-security-color-m-07: #8b3263;
--eve-security-color-m-08: #8b3263;
--eve-security-color-m-09: #8b3263;
--eve-security-color-m-10: #8b3263;
--eve-solar-system-status-unknown: transparent;
--eve-solar-system-status-color-unknown: transparent;
--eve-solar-system-status-home: #{$homeAlpha};
--eve-solar-system-status-color-home: #{$homeBase};
--eve-solar-system-status-color-home-dark30: #{$homeDark30};
--eve-solar-system-status-friendly: #{$friendlyAlpha};
--eve-solar-system-status-color-friendly: #{$friendlyBase};
--eve-solar-system-status-friendly-dark30: #{$friendlyDark30};
--eve-solar-system-status-color-friendly-dark20: #{$friendlyDark20};
--eve-solar-system-status-color-friendly-dark5: #{$friendlyDark5};
--eve-solar-system-status-lookingFor: #{$lookingForAlpha};
--eve-solar-system-status-color-lookingFor: #{$lookingForBase};
--eve-solar-system-status-color-lookingFor-dark15: #{$lookingForDark15};
--eve-solar-system-status-warning: #906518a6;
--eve-solar-system-status-color-warning: #ffb93b;
--eve-solar-system-status-target: #b439ff6b;
--eve-solar-system-status-color-target: #b439ff;
--eve-solar-system-status-dangerous: #d54040;
--eve-solar-system-status-color-dangerous: #d54040;
--conn-time-eol: #7452c3e3;
--conn-frigate: #325d88;
--conn-save: rgba(155, 102, 45, 0.85);
--selected-item-bg: rgba(98, 98, 98, 0.33);
}
$eve-solar-system-status-color-unknown: transparent;
$eve-solar-system-status-color-friendly: #3bbd39;
$eve-solar-system-status-color-warning: #ffb93b;
$eve-solar-system-status-color-target: #b439ff;
$eve-solar-system-status-color-dangerous: #d54040;
$eve-solar-system-status-color-lookingFor: #43c2fd;
$eve-solar-system-status-color-home: rgb(197, 253, 67);

View File

@@ -1,504 +1,535 @@
@import './eve-common-variables';
@import "eve-common-variables";
.eve-wh-effect-color-pulsar {
fill: var(--eve-effect-pulsar);
background-color: var(--eve-effect-pulsar);
fill: $eve-effect-pulsar;
background-color: $eve-effect-pulsar;
}
.eve-wh-effect-color-magnetar {
fill: var(--eve-effect-magnetar);
background-color: var(--eve-effect-magnetar);
fill: $eve-effect-magnetar;
background-color: $eve-effect-magnetar;
}
.eve-wh-effect-color-wolfRayet {
fill: var(--eve-effect-wolfRayet);
background-color: var(--eve-effect-wolfRayet);
fill: $eve-effect-wolfRayet;
background-color: $eve-effect-wolfRayet;
}
.eve-wh-effect-color-blackHole {
fill: var(--eve-effect-blackHole);
background-color: var(--eve-effect-blackHole);
box-shadow: 0 0 8px rgba(255, 255, 255, 0.33);
fill: $eve-effect-blackHole;
background-color: $eve-effect-blackHole;
box-shadow: 0 0 8px rgba(255 255 255 / 33);
}
.eve-wh-effect-color-cataclysmicVariable {
fill: var(--eve-effect-cataclysmicVariable);
background-color: var(--eve-effect-cataclysmicVariable);
fill: $eve-effect-cataclysmicVariable;
background-color: $eve-effect-cataclysmicVariable;
}
.eve-wh-effect-color-redGiant {
fill: var(--eve-effect-redGiant);
background-color: var(--eve-effect-redGiant);
fill: $eve-effect-redGiant;
background-color: $eve-effect-redGiant;
}
.text-eve-wh-effect-color-pulsar {
color: var(--eve-effect-pulsar);
color: $eve-effect-pulsar;
}
.text-eve-wh-effect-color-magnetar {
color: var(--eve-effect-magnetar);
color: $eve-effect-magnetar;
}
.text-eve-wh-effect-color-wolfRayet {
color: var(--eve-effect-wolfRayet);
color: $eve-effect-wolfRayet;
}
.text-eve-wh-effect-color-blackHole {
color: #fff;
}
.text-eve-wh-effect-color-cataclysmicVariable {
color: var(--eve-effect-cataclysmicVariable);
color: $eve-effect-cataclysmicVariable;
}
.text-eve-wh-effect-color-redGiant {
color: var(--eve-effect-redGiant);
color: $eve-effect-redGiant;
}
.text-eve-wh-effect-color-dazhLiminalityLocus {
color: var(--eve-effect-dazhLiminalityLocus);
color: $eve-effect-dazhLiminalityLocus;
}
.text-eve-wh-effect-color-imperialStellarObservatory {
color: var(--eve-effect-imperialStellarObservatory);
color: $eve-effect-imperialStellarObservatory;
}
.text-eve-wh-effect-color-stateStellarObservatory {
color: var(--eve-effect-stateStellarObservatory);
color: $eve-effect-stateStellarObservatory;
}
.text-eve-wh-effect-color-republicStellarObservatory {
color: var(--eve-effect-republicStellarObservatory);
color: $eve-effect-republicStellarObservatory;
}
.text-eve-wh-effect-color-federalStellarObservatory {
color: var(--eve-effect-federalStellarObservatory);
color: $eve-effect-federalStellarObservatory;
}
/* Security color classes */
.eve-security-color-10 {
color: var(--eve-security-color-10) !important;
fill: var(--eve-security-color-10);
color: $eve-security-color-10 !important;
fill: $eve-security-color-10;
}
.eve-security-color-09 {
color: var(--eve-security-color-09) !important;
fill: var(--eve-security-color-09);
color: $eve-security-color-09 !important;
fill: $eve-security-color-09;
}
.eve-security-color-08 {
color: var(--eve-security-color-08) !important;
fill: var(--eve-security-color-08);
color: $eve-security-color-08 !important;
fill: $eve-security-color-08;
}
.eve-security-color-07 {
color: var(--eve-security-color-07) !important;
fill: var(--eve-security-color-07);
color: $eve-security-color-07 !important;
fill: $eve-security-color-07;
}
.eve-security-color-06 {
color: var(--eve-security-color-06) !important;
fill: var(--eve-security-color-06);
color: $eve-security-color-06 !important;
fill: $eve-security-color-06;
}
.eve-security-color-05 {
color: var(--eve-security-color-05) !important;
fill: var(--eve-security-color-05);
color: $eve-security-color-05 !important;
fill: $eve-security-color-05;
}
.eve-security-color-04 {
color: var(--eve-security-color-04) !important;
fill: var(--eve-security-color-04);
color: $eve-security-color-04 !important;
fill: $eve-security-color-04;
}
.eve-security-color-03 {
color: var(--eve-security-color-03) !important;
fill: var(--eve-security-color-03);
color: $eve-security-color-03 !important;
fill: $eve-security-color-03;
}
.eve-security-color-02 {
color: var(--eve-security-color-02) !important;
fill: var(--eve-security-color-02);
color: $eve-security-color-02 !important;
fill: $eve-security-color-02;
}
.eve-security-color-01 {
color: var(--eve-security-color-01) !important;
fill: var(--eve-security-color-01);
color: $eve-security-color-01 !important;
fill: $eve-security-color-01;
}
.eve-security-color-00 {
color: var(--eve-security-color-00) !important;
fill: var(--eve-security-color-00);
color: $eve-security-color-00 !important;
fill: $eve-security-color-00;
}
.eve-security-color-m-01 {
color: var(--eve-security-color-m-01) !important;
fill: var(--eve-security-color-m-01);
color: $eve-security-color-m-01 !important;
fill: $eve-security-color-m-01;
}
.eve-security-color-m-02 {
color: var(--eve-security-color-m-02) !important;
fill: var(--eve-security-color-m-02);
color: $eve-security-color-m-02 !important;
fill: $eve-security-color-m-02;
}
.eve-security-color-m-03 {
color: var(--eve-security-color-m-03) !important;
fill: var(--eve-security-color-m-03);
color: $eve-security-color-m-03 !important;
fill: $eve-security-color-m-03;
}
.eve-security-color-m-04 {
color: var(--eve-security-color-m-04) !important;
fill: var(--eve-security-color-m-04);
color: $eve-security-color-m-04 !important;
fill: $eve-security-color-m-04;
}
.eve-security-color-m-05 {
color: var(--eve-security-color-m-05) !important;
fill: var(--eve-security-color-m-05);
color: $eve-security-color-m-05 !important;
fill: $eve-security-color-m-05;
}
.eve-security-color-m-06 {
color: var(--eve-security-color-m-06) !important;
fill: var(--eve-security-color-m-06);
color: $eve-security-color-m-06 !important;
fill: $eve-security-color-m-06;
}
.eve-security-color-m-07 {
color: var(--eve-security-color-m-07) !important;
fill: var(--eve-security-color-m-07);
color: $eve-security-color-m-07 !important;
fill: $eve-security-color-m-07;
}
.eve-security-color-m-08 {
color: var(--eve-security-color-m-08) !important;
fill: var(--eve-security-color-m-08);
color: $eve-security-color-m-08 !important;
fill: $eve-security-color-m-08;
}
.eve-security-color-m-09 {
color: var(--eve-security-color-m-09) !important;
fill: var(--eve-security-color-m-09);
color: $eve-security-color-m-09 !important;
fill: $eve-security-color-m-09;
}
.eve-security-color-m-10 {
color: var(--eve-security-color-m-10) !important;
fill: var(--eve-security-color-m-10);
color: $eve-security-color-m-10 !important;
fill: $eve-security-color-m-10;
}
/* Security backgrounds */
.eve-security-background-10 {
background-color: var(--eve-security-color-10);
fill: var(--eve-security-color-10);
background-color: $eve-security-color-10;
fill: $eve-security-color-10;
}
.eve-security-background-09 {
background-color: var(--eve-security-color-09);
fill: var(--eve-security-color-09);
background-color: $eve-security-color-09;
fill: $eve-security-color-09;
}
.eve-security-background-08 {
background-color: var(--eve-security-color-08);
fill: var(--eve-security-color-08);
background-color: $eve-security-color-08;
fill: $eve-security-color-08;
}
.eve-security-background-07 {
background-color: var(--eve-security-color-07);
fill: var(--eve-security-color-07);
background-color: $eve-security-color-07;
fill: $eve-security-color-07;
}
.eve-security-background-06 {
background-color: var(--eve-security-color-06);
fill: var(--eve-security-color-06);
background-color: $eve-security-color-06;
fill: $eve-security-color-06;
}
.eve-security-background-05 {
background-color: var(--eve-security-color-05);
fill: var(--eve-security-color-05);
background-color: $eve-security-color-05;
fill: $eve-security-color-05;
}
.eve-security-background-04 {
background-color: var(--eve-security-color-04);
fill: var(--eve-security-color-04);
background-color: $eve-security-color-04;
fill: $eve-security-color-04;
}
.eve-security-background-03 {
background-color: var(--eve-security-color-03);
fill: var(--eve-security-color-03);
background-color: $eve-security-color-03;
fill: $eve-security-color-03;
}
.eve-security-background-02 {
background-color: var(--eve-security-color-02);
fill: var(--eve-security-color-02);
background-color: $eve-security-color-02;
fill: $eve-security-color-02;
}
.eve-security-background-01 {
background-color: var(--eve-security-color-01);
fill: var(--eve-security-color-01);
background-color: $eve-security-color-01;
fill: $eve-security-color-01;
}
.eve-security-background-00 {
background-color: var(--eve-security-color-00);
fill: var(--eve-security-color-00);
background-color: $eve-security-color-00;
fill: $eve-security-color-00;
}
.eve-security-background-m-01 {
background-color: var(--eve-security-color-m-01);
fill: var(--eve-security-color-m-01);
background-color: $eve-security-color-m-01;
fill: $eve-security-color-m-01;
}
.eve-security-background-m-02 {
background-color: var(--eve-security-color-m-02);
fill: var(--eve-security-color-m-02);
background-color: $eve-security-color-m-02;
fill: $eve-security-color-m-02;
}
.eve-security-background-m-03 {
background-color: var(--eve-security-color-m-03);
fill: var(--eve-security-color-m-03);
background-color: $eve-security-color-m-03;
fill: $eve-security-color-m-03;
}
.eve-security-background-m-04 {
background-color: var(--eve-security-color-m-04);
fill: var(--eve-security-color-m-04);
background-color: $eve-security-color-m-04;
fill: $eve-security-color-m-04;
}
.eve-security-background-m-05 {
background-color: var(--eve-security-color-m-05);
fill: var(--eve-security-color-m-05);
background-color: $eve-security-color-m-05;
fill: $eve-security-color-m-05;
}
.eve-security-background-m-06 {
background-color: var(--eve-security-color-m-06);
fill: var(--eve-security-color-m-06);
background-color: $eve-security-color-m-06;
fill: $eve-security-color-m-06;
}
.eve-security-background-m-07 {
background-color: var(--eve-security-color-m-07);
fill: var(--eve-security-color-m-07);
background-color: $eve-security-color-m-07;
fill: $eve-security-color-m-07;
}
.eve-security-background-m-08 {
background-color: var(--eve-security-color-m-08);
fill: var(--eve-security-color-m-08);
background-color: $eve-security-color-m-08;
fill: $eve-security-color-m-08;
}
.eve-security-background-m-09 {
background-color: var(--eve-security-color-m-09);
fill: var(--eve-security-color-m-09);
background-color: $eve-security-color-m-09;
fill: $eve-security-color-m-09;
}
.eve-security-background-m-10 {
background-color: var(--eve-security-color-m-10);
fill: var(--eve-security-color-m-10);
background-color: $eve-security-color-m-10;
fill: $eve-security-color-m-10;
}
/* WH Type color classes */
.eve-wh-type-color-high {
color: var(--eve-wh-type-color-high) !important;
fill: var(--eve-wh-type-color-high);
color: $eve-wh-type-color-high;
fill: $eve-wh-type-color-high;
font-weight: bold !important;
}
.eve-wh-type-color-low {
color: var(--eve-wh-type-color-low) !important;
fill: var(--eve-wh-type-color-low);
color: $eve-wh-type-color-low;
fill: $eve-wh-type-color-low;
font-weight: bold !important;
}
.eve-wh-type-color-null {
color: var(--eve-wh-type-color-null) !important;
fill: var(--eve-wh-type-color-null);
color: $eve-wh-type-color-null;
fill: $eve-wh-type-color-null;
font-weight: bold !important;
}
.eve-wh-type-color-c1 {
color: var(--eve-wh-type-color-c1) !important;
fill: var(--eve-wh-type-color-c1);
color: $eve-wh-type-color-c1 !important;
fill: $eve-wh-type-color-c1;
font-weight: bold !important;
}
.eve-wh-type-color-c2 {
color: var(--eve-wh-type-color-c2) !important;
fill: var(--eve-wh-type-color-c2);
color: $eve-wh-type-color-c2 !important;
fill: $eve-wh-type-color-c2;
font-weight: bold !important;
}
.eve-wh-type-color-c3 {
color: var(--eve-wh-type-color-c3) !important;
fill: var(--eve-wh-type-color-c3);
color: $eve-wh-type-color-c3 !important;
fill: $eve-wh-type-color-c3;
font-weight: bold !important;
}
.eve-wh-type-color-c4 {
color: var(--eve-wh-type-color-c4) !important;
fill: var(--eve-wh-type-color-c4);
color: $eve-wh-type-color-c4 !important;
fill: $eve-wh-type-color-c4;
font-weight: bold !important;
}
.eve-wh-type-color-c5 {
color: var(--eve-wh-type-color-c5) !important;
fill: var(--eve-wh-type-color-c5);
color: $eve-wh-type-color-c5 !important;
fill: $eve-wh-type-color-c5;
font-weight: bold !important;
}
.eve-wh-type-color-c6 {
color: var(--eve-wh-type-color-c6) !important;
fill: var(--eve-wh-type-color-c6);
color: $eve-wh-type-color-c6 !important;
fill: $eve-wh-type-color-c6;
font-weight: bold !important;
}
.eve-wh-type-color-c13 {
color: var(--eve-wh-type-color-c13) !important;
fill: var(--eve-wh-type-color-c13);
color: $eve-wh-type-color-c13 !important;
fill: $eve-wh-type-color-c13;
}
.eve-wh-type-color-drifter {
color: var(--eve-wh-type-color-drifter) !important;
fill: var(--eve-wh-type-color-drifter);
color: $eve-wh-type-color-drifter !important;
fill: $eve-wh-type-color-drifter;
}
.eve-wh-type-color-thera {
color: var(--eve-wh-type-color-thera) !important;
fill: var(--eve-wh-type-color-thera);
color: $eve-wh-type-color-thera !important;
fill: $eve-wh-type-color-thera;
}
/* WH Type backgrounds */
.eve-wh-type-background-high {
background-color: var(--eve-wh-type-color-high);
}
.eve-wh-type-background-low {
background-color: var(--eve-wh-type-color-low);
}
.eve-wh-type-background-null {
background-color: var(--eve-wh-type-color-null);
}
.eve-wh-type-background-c1 {
background-color: var(--eve-wh-type-color-c1);
}
.eve-wh-type-background-c2 {
background-color: var(--eve-wh-type-color-c2);
}
.eve-wh-type-background-c3 {
background-color: var(--eve-wh-type-color-c3);
}
.eve-wh-type-background-c4 {
background-color: var(--eve-wh-type-color-c4);
}
.eve-wh-type-background-c5 {
background-color: var(--eve-wh-type-color-c5);
}
.eve-wh-type-background-c6 {
background-color: var(--eve-wh-type-color-c6);
}
.eve-wh-type-background-c13 {
background-color: var(--eve-wh-type-color-c13);
}
.eve-wh-type-background-drifter {
background-color: var(--eve-wh-type-color-drifter);
}
.eve-wh-type-background-thera {
background-color: var(--eve-wh-type-color-thera);
}
.eve-wh-type-background-zarzakh {
background-color: var(--eve-wh-type-color-zarzakh);
background-color: $eve-wh-type-color-high;
}
/* Kind color classes */
.eve-kind-color-high {
color: var(--eve-wh-type-color-high);
fill: var(--eve-wh-type-color-high);
.eve-wh-type-background-low {
background-color: $eve-wh-type-color-low;
}
.eve-wh-type-background-null {
background-color: $eve-wh-type-color-null;
}
.eve-wh-type-background-c1 {
background-color: $eve-wh-type-color-c1;
}
.eve-wh-type-background-c2 {
background-color: $eve-wh-type-color-c2;
}
.eve-wh-type-background-c3 {
background-color: $eve-wh-type-color-c3;
}
.eve-wh-type-background-c4 {
background-color: $eve-wh-type-color-c4;
}
.eve-wh-type-background-c5 {
background-color: $eve-wh-type-color-c5;
}
.eve-wh-type-background-c6 {
background-color: $eve-wh-type-color-c6;
}
.eve-wh-type-background-c13 {
background-color: $eve-wh-type-color-c13;
}
.eve-wh-type-background-drifter {
background-color: $eve-wh-type-color-drifter;
}
.eve-wh-type-background-thera {
background-color: $eve-wh-type-color-thera;
}
.eve-wh-type-background-zarzakh {
background-color: $eve-wh-type-color-zarzakh;
}
.eve-kind-color-high {
color: $eve-wh-type-color-high;
fill: $eve-wh-type-color-high;
}
.eve-kind-color-low {
color: var(--eve-wh-type-color-low);
fill: var(--eve-wh-type-color-low);
color: $eve-wh-type-color-low;
fill: $eve-wh-type-color-low;
font-weight: bold;
}
.eve-kind-color-null {
color: var(--eve-wh-type-color-null);
fill: var(--eve-wh-type-color-null);
color: $eve-wh-type-color-null;
fill: $eve-wh-type-color-null;
}
.eve-kind-color-wh {
color: var(--eve-wh-type-color-c6);
fill: var(--eve-wh-type-color-c6);
color: $eve-wh-type-color-c6;
fill: $eve-wh-type-color-c6;
}
.eve-kind-color-thera {
color: var(--eve-wh-type-color-thera);
fill: var(--eve-wh-type-color-thera);
color: $eve-wh-type-color-thera;
fill: $eve-wh-type-color-thera;
}
.eve-kind-color-abyss {
color: var(--eve-wh-type-color-c6);
fill: var(--eve-wh-type-color-c6);
color: $eve-wh-type-color-c6;
fill: $eve-wh-type-color-c6;
}
.eve-kind-color-penalty {
color: var(--eve-wh-type-color-c6);
fill: var(--eve-wh-type-color-c6);
color: $eve-wh-type-color-c6;
fill: $eve-wh-type-color-c6;
}
.eve-kind-color-pochven {
color: var(--eve-wh-type-color-c6);
fill: var(--eve-wh-type-color-c6);
color: $eve-wh-type-color-c6;
fill: $eve-wh-type-color-c6;
}
.eve-kind-color-zarzakh {
color: var(--eve-wh-type-color-zarzakh);
fill: var(--eve-wh-type-color-zarzakh);
color: $eve-wh-type-color-zarzakh;
fill: $eve-wh-type-color-zarzakh;
}
/* Kind backgrounds */
.eve-kind-background-high {
background-color: var(--eve-wh-type-color-high);
background-color: $eve-wh-type-color-high;
}
.eve-kind-background-low {
background-color: var(--eve-wh-type-color-low);
background-color: $eve-wh-type-color-low;
}
.eve-kind-background-null {
background-color: var(--eve-wh-type-color-null);
background-color: $eve-wh-type-color-null;
}
.eve-kind-background-wh {
background-color: var(--eve-wh-type-color-c6);
background-color: $eve-wh-type-color-c6;
}
.eve-kind-background-thera {
background-color: var(--eve-wh-type-color-thera);
background-color: $eve-wh-type-color-thera;
}
.eve-kind-background-abyss {
background-color: var(--eve-wh-type-color-c6);
background-color: $eve-wh-type-color-c6;
}
.eve-kind-background-penalty {
background-color: var(--eve-wh-type-color-c6);
background-color: $eve-wh-type-color-c6;
}
.eve-kind-background-pochven {
background-color: var(--eve-wh-type-color-c6);
background-color: $eve-wh-type-color-c6;
}
.eve-kind-background-zarzakh {
background-color: var(--eve-wh-type-color-zarzakh);
background-color: $eve-wh-type-color-zarzakh;
}
/* System status color classes */
.eve-system-status-color-clear {
color: var(--eve-solar-system-status-color-unknown);
color: $eve-solar-system-status-color-unknown;
}
.eve-system-status-color-home {
color: var(--eve-solar-system-status-color-home);
color: $eve-solar-system-status-color-home;
}
.eve-system-status-color-friendly {
color: var(--eve-solar-system-status-color-friendly);
color: $eve-solar-system-status-color-friendly;
}
.eve-system-status-color-lookingFor {
color: var(--eve-solar-system-status-color-lookingFor);
color: $eve-solar-system-status-color-lookingFor;
}
.eve-system-status-color-warning {
color: var(--eve-solar-system-status-color-warning);
color: $eve-solar-system-status-color-warning;
}
.eve-system-status-color-target {
color: var(--eve-solar-system-status-color-target);
color: $eve-solar-system-status-color-target;
}
.eve-system-status-color-dangerous {
color: var(--eve-solar-system-status-color-dangerous);
}
.eve-system-status-clear {
background-color: var(--eve-solar-system-status-unknown);
}
.eve-system-status-home {
background-color: var(--eve-solar-system-status-home);
}
.eve-system-status-friendly {
background-color: var(--eve-solar-system-status-friendly);
}
.eve-system-status-lookingFor {
background-color: var(--eve-solar-system-status-lookingFor);
}
.eve-system-status-warning {
background-color: var(--eve-solar-system-status-warning);
}
.eve-system-status-target {
background-color: var(--eve-solar-system-status-target);
}
.eve-system-status-dangerous {
background-color: var(--eve-solar-system-status-dangerous);
}
.eve-system-status-clear {
background-color: var(--eve-solar-system-status-unknown);
color: var(--eve-solar-system-status-color-unknown);
}
.eve-system-status-home {
background-color: var(--eve-solar-system-status-home);
color: var(--eve-solar-system-status-color-home);
}
.eve-system-status-friendly {
background-color: var(--eve-solar-system-status-friendly);
color: var(--eve-solar-system-status-color-friendly);
}
.eve-system-status-lookingFor {
background-color: var(--eve-solar-system-status-lookingFor);
color: var(--eve-solar-system-status-color-lookingFor);
}
.eve-system-status-warning {
background-color: var(--eve-solar-system-status-warning);
color: var(--eve-solar-system-status-color-warning);
}
.eve-system-status-target {
background-color: var(--eve-solar-system-status-target);
color: var(--eve-solar-system-status-color-target);
}
.eve-system-status-dangerous {
background-color: var(--eve-solar-system-status-dangerous);
color: var(--eve-solar-system-status-color-dangerous);
color: $eve-solar-system-status-color-dangerous;
}
.wd-route-system-shape-triangle {
clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
.wd-route-system-shape-circle {
border-radius: 40%;
}
/* Some additional background classes */
.wd-marker-bookmark-color-shattered {
background-color: #833ca4;
margin-top: 1px;
}
.wd-marker-bookmark-color-custom {
background-color: #282828;
border: 1px solid #4c4c4c;
@@ -541,49 +572,3 @@
.wd-marker-bookmark-color-danger {
background-color: #d10600;
}
.react-flow {
color: var(--text-color);
&__pane {
cursor: auto;
}
&__minimap {
background-color: rgba(66, 66, 66, 1);
opacity: 0.7;
border: 1px solid #2f2f2f;
border-radius: 4px;
overflow: hidden;
}
&__minimap-mask {
fill: rgba(28, 28, 28, 0.75);
}
&__controls {
filter: brightness(1.5);
}
&__minimap-node {
fill: #ffb03a;
}
}
.context-menu-active {
background-color: rgba(131, 131, 131, 0.33);
}
.p-dialog {
.p-dialog-header {
height: 40px;
padding: 1rem;
padding-right: 10px !important;
}
.p-dialog-title {
font-size: 1rem !important;
}
.p-dialog-header-icons {
align-self: initial !important;
}
}

View File

@@ -1,2 +0,0 @@
@import './default-theme.scss';
@import './pathfinder-theme.scss';

View File

@@ -0,0 +1,74 @@
$pastel-blue: #5a7d9a;
$pastel-pink: #d291bc;
$pastel-green: #88b04b;
$pastel-yellow: #ffdd59;
$dark-bg: #2d2d2d;
$text-color: #ffffff;
$tooltip-bg: #202020;
.react-flow {
// background-color: $dark-bg;
color: $text-color;
&__node {
//cursor: auto;
}
&__pane {
cursor: auto;
}
//&__edge {
// stroke: $pastel-pink;
// stroke-width: 2px;
//
// &.selected {
// stroke: $pastel-yellow;
// }
//}
&__handle {
//background-color: $pastel-green;
//box-shadow: 0 0 5px rgba($pastel-green, 0.5);
}
&__minimap {
background-color: rgba(66, 66, 66, 1);
opacity: 0.7;
//backdrop-filter: blur(5px);
border: 1px solid #2f2f2f;
border-radius: 4px;
overflow: hidden;
}
&__minimap-mask {
fill: rgba(28, 28, 28, 0.75);
}
&__controls {
filter: brightness(1.5);
}
&__minimap-node {
fill: #ffb03a;
}
}
.context-menu-active {
background-color: rgba(131, 131, 131, 0.33);
}
.p-dialog {
.p-dialog-header {
height: 40px;
padding: 1rem;
padding-right: 10px !important;
}
.p-dialog-title {
font-size: 1rem !important;
}
.p-dialog-header-icons {
align-self: initial !important;
}
}

View File

@@ -0,0 +1,7 @@
$pastel-blue: #5a7d9a;
$pastel-pink: #d291bc;
$pastel-green: #88b04b;
$pastel-yellow: #ffdd59;
$dark-bg: #2d2d2d;
$text-color: #ffffff;
$tooltip-bg: #202020;

View File

@@ -1,51 +0,0 @@
@import './eve-common-variables';
@import './eve-common';
@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@300;400;700&display=swap');
.pathfinder-theme {
--rf-bg-color: #000000;
--rf-soft-bg-color: #282828;
--rf-node-bg-color: #202020;
--rf-node-soft-bg-color: #313335;
--rf-node-font-weight: bold;
--rf-text-color: #adadad;
--rf-region-name: var(--rf-text-color);
--rf-custom-name: var(--rf-text-color);
--tooltip-bg: #202020;
--rf-bg-variant: "lines";
--rf-bg-gap: 32;
--rf-bg-size: 1;
--rf-bg-pattern-color: #313131;
--eve-effect-pulsar: #428bca;
--eve-effect-magnetar: #e06fdf;
--eve-effect-wolfRayet: #e28a0d;
--eve-effect-blackHole: #000000;
--eve-effect-cataclysmicVariable: #ffffbb;
--eve-effect-redGiant: #d9534f;
--eve-wh-type-color-high: #5cb85c;
--eve-wh-type-color-low: #e28a0d;
--eve-wh-type-color-null: #d9534f;
--eve-wh-type-color-c1: #428bca;
--eve-wh-type-color-c2: #428bca;
--eve-wh-type-color-c3: #e28a0d;
--eve-wh-type-color-c4: #e28a0d;
--eve-wh-type-color-c5: #d9534f;
--eve-wh-type-color-c6: #d9534f;
--eve-wh-type-color-c13: #7986cb;
--eve-wh-type-color-drifter: #44aa82;
--rf-node-font-weight: bold;
--rf-node-line-height: normal;
--rf-node-font-family: 'Oxygen', sans-serif;
--rf-node-text-color: var(--pf-text-color);
--rf-tag-color: #fbbf24;
--rf-has-user-characters: #5cb85c;
}

View File

@@ -1,11 +0,0 @@
// wrapNode.ts
import { NodeProps } from 'reactflow';
import { SolarSystemNodeProps } from '../components/SolarSystemNode';
export function wrapNode<T>(
SolarSystemNode: React.FC<SolarSystemNodeProps<T>>
): React.FC<NodeProps<T>> {
return function NodeAdapter(props) {
return <SolarSystemNode {...props} />;
};
}

View File

@@ -1,10 +0,0 @@
.SearchItem {
& > * {
font-size: 13px !important;
}
}
.SearchItemEffect {
font-weight: initial !important;
}

View File

@@ -1,203 +0,0 @@
import { Dialog } from 'primereact/dialog';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { useCallback, useRef, useState } from 'react';
import { Button } from 'primereact/button';
import { IconField } from 'primereact/iconfield';
import { AutoComplete } from 'primereact/autocomplete';
import { OutCommand, SearchSystemItem } from '@/hooks/Mapper/types';
import { SystemViewStandalone, WHClassView, WHEffectView } from '@/hooks/Mapper/components/ui-kit';
import classes from './AddSystemDialog.module.scss';
import clsx from 'clsx';
import { isWormholeSpace } from '@/hooks/Mapper/components/map/helpers/isWormholeSpace.ts';
import { sortWHClasses } from '@/hooks/Mapper/helpers';
export type SearchOnSubmitCallback = (item: SearchSystemItem) => void;
interface AddSystemDialogProps {
title?: string;
visible: boolean;
setVisible: (visible: boolean) => void;
onSubmit?: SearchOnSubmitCallback;
excludedSystems?: number[];
}
export const AddSystemDialog = ({
title = 'Add system',
visible,
setVisible,
onSubmit,
excludedSystems = [],
}: AddSystemDialogProps) => {
const {
outCommand,
data: { wormholesData },
} = useMapRootState();
const inputRef = useRef<any>();
const onShow = useCallback(() => {
inputRef.current?.focus();
}, []);
const [filteredItems, setFilteredItems] = useState<SearchSystemItem[]>([]);
const [selectedItem, setSelectedItem] = useState<SearchSystemItem[] | null>(null);
const searchItems = useCallback(
async (event: { query: string }) => {
if (event.query.length < 2) {
setFilteredItems([]);
return;
}
const query = event.query;
if (query.length === 0) {
setFilteredItems([]);
} else {
try {
const result = await outCommand({
type: OutCommand.searchSystems,
data: {
text: query,
},
});
let prepared = (result.systems as SearchSystemItem[]).sort((a, b) => {
const amatch = a.label.indexOf(query);
const bmatch = b.label.indexOf(query);
return amatch - bmatch;
});
if (excludedSystems) {
prepared = prepared.filter(x => !excludedSystems.includes(x.system_static_info.solar_system_id));
}
setFilteredItems(prepared);
} catch (error) {
console.error('Error fetching data:', error);
setFilteredItems([]);
}
}
},
[excludedSystems, outCommand],
);
const ref = useRef({ onSubmit, selectedItem });
ref.current = { onSubmit, selectedItem };
const handleSubmit = useCallback(() => {
const { onSubmit, selectedItem } = ref.current;
setFilteredItems([]);
setSelectedItem([]);
if (!selectedItem) {
setVisible(false);
return;
}
onSubmit?.(selectedItem[0]);
setVisible(false);
}, [setVisible]);
return (
<Dialog
header={title}
visible={visible}
draggable={false}
style={{ width: '520px' }}
onShow={onShow}
onHide={() => {
if (!visible) {
return;
}
setVisible(false);
}}
>
<div className="flex flex-col gap-3 px-1.5">
<div className="flex flex-col gap-2 py-3.5">
<div className="flex flex-col gap-1">
<IconField>
<AutoComplete
ref={inputRef}
multiple
showEmptyMessage
scrollHeight="300px"
value={selectedItem}
suggestions={filteredItems}
completeMethod={searchItems}
onChange={e => {
setSelectedItem(e.value.length < 2 ? e.value : [e.value[e.value.length - 1]]);
}}
emptyMessage="Not found any system..."
placeholder="Type here..."
field="label"
id="value"
className="w-full"
itemTemplate={(item: SearchSystemItem) => {
const { security, system_class, effect_power, effect_name, statics } = item.system_static_info;
const sortedStatics = sortWHClasses(wormholesData, statics);
const isWH = isWormholeSpace(system_class);
return (
<div className={clsx('flex gap-1.5', classes.SearchItem)}>
<SystemViewStandalone
security={security}
system_class={system_class}
solar_system_id={item.value}
class_title={item.class_title}
solar_system_name={item.label}
region_name={item.region_name}
/>
{effect_name && isWH && (
<WHEffectView
effectName={effect_name}
effectPower={effect_power}
className={classes.SearchItemEffect}
/>
)}
{isWH && (
<div className="flex gap-1 grow justify-between">
<div></div>
<div className="flex gap-1">
{sortedStatics.map(x => (
<WHClassView key={x} whClassName={x} />
))}
</div>
</div>
)}
</div>
);
}}
selectedItemTemplate={(item: SearchSystemItem) => (
<SystemViewStandalone
security={item.system_static_info.security}
system_class={item.system_static_info.system_class}
solar_system_id={item.value}
class_title={item.class_title}
solar_system_name={item.label}
region_name={item.region_name}
/>
)}
/>
</IconField>
<span className="text-[12px] text-stone-400 ml-1">*to search type at least 2 symbols.</span>
</div>
</div>
<div className="flex gap-2 justify-end">
<Button
onClick={handleSubmit}
outlined
disabled={!selectedItem || selectedItem.length !== 1}
size="small"
label="Submit"
/>
</div>
</div>
</Dialog>
);
};

View File

@@ -1 +0,0 @@
export * from './AddSystemDialog';

View File

@@ -3,7 +3,6 @@ import { InputTextarea } from 'primereact/inputtextarea';
import { Dialog } from 'primereact/dialog';
import { getSystemById } from '@/hooks/Mapper/helpers';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { useMapGetOption } from '@/hooks/Mapper/mapRootProvider/hooks/api';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Button } from 'primereact/button';
import { OutCommand } from '@/hooks/Mapper/types';
@@ -23,21 +22,30 @@ export const SystemSettingsDialog = ({ systemId, visible, setVisible }: SystemSe
outCommand,
} = useMapRootState();
const isTempSystemNameEnabled = useMapGetOption('show_temp_system_name') === 'true';
const system = getSystemById(systems, systemId);
const [name, setName] = useState('');
const [label, setLabel] = useState('');
const [temporaryName, setTemporaryName] = useState('');
const [description, setDescription] = useState('');
const inputRef = useRef<HTMLInputElement>();
const ref = useRef({ name, description, temporaryName, label, outCommand, systemId, system });
ref.current = { name, description, label, temporaryName, outCommand, systemId, system };
useEffect(() => {
if (!system) {
return;
}
const labels = new LabelsManager(system.labels || '');
setName(system.name || '');
setLabel(labels.customLabel);
setDescription(system.description || '');
}, [system]);
const ref = useRef({ name, description, label, outCommand, systemId, system });
ref.current = { name, description, label, outCommand, systemId, system };
const handleSave = useCallback(() => {
const { name, description, label, temporaryName, outCommand, systemId, system } = ref.current;
const { name, description, label, outCommand, systemId, system } = ref.current;
const outLabel = new LabelsManager(system?.labels ?? '');
outLabel.updateCustomLabel(label);
@@ -50,14 +58,6 @@ export const SystemSettingsDialog = ({ systemId, visible, setVisible }: SystemSe
},
});
outCommand({
type: OutCommand.updateSystemTemporaryName,
data: {
system_id: systemId,
value: temporaryName,
},
});
outCommand({
type: OutCommand.updateSystemName,
data: {
@@ -93,21 +93,6 @@ export const SystemSettingsDialog = ({ systemId, visible, setVisible }: SystemSe
e.target.value = e.target.value.toUpperCase().replace(/[^A-Z0-9\-[\](){}]/g, '');
}, []);
// Attention: this effect should be call only on mount.
useEffect(() => {
const { system } = ref.current;
if (!system) {
return;
}
const labels = new LabelsManager(system.labels || '');
setName(system.name || '');
setLabel(labels.customLabel);
setTemporaryName(system.temporary_name || '');
setDescription(system.description || '');
}, []);
return (
<Dialog
header="System settings"
@@ -182,35 +167,6 @@ export const SystemSettingsDialog = ({ systemId, visible, setVisible }: SystemSe
</IconField>
</div>
{isTempSystemNameEnabled && (
<div className="flex flex-col gap-1">
<label htmlFor="username">Temporary Name</label>
<IconField>
{temporaryName !== '' && (
<WdImgButton
className="pi pi-trash text-red-400"
textSize={WdImageSize.large}
tooltip={{
content: 'Remove temporary name',
className: 'pi p-input-icon',
position: TooltipPosition.top,
}}
onClick={() => setTemporaryName('')}
/>
)}
<InputText
id="temporaryName"
aria-describedby="temporaryName"
autoComplete="off"
value={temporaryName}
maxLength={10}
onChange={e => setTemporaryName(e.target.value)}
/>
</IconField>
</div>
)}
<div className="flex flex-col gap-1">
<label htmlFor="username">Description</label>
<InputTextarea

View File

@@ -8,6 +8,7 @@
.RouteSystem {
width: 8px;
height: 8px;
background: #ffffff;
cursor: pointer;
transition: opacity 200ms;

View File

@@ -21,11 +21,6 @@ import { RoutesProvider, useRouteProvider } from './RoutesProvider.tsx';
import { ContextMenuSystemInfo, useContextMenuSystemInfoHandlers } from '@/hooks/Mapper/components/contexts';
import useMaxWidth from '@/hooks/Mapper/hooks/useMaxWidth.ts';
import { WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit/WdTooltipWrapper';
import {
AddSystemDialog,
SearchOnSubmitCallback,
} from '@/hooks/Mapper/components/mapInterface/components/AddSystemDialog';
import { OutCommand } from '@/hooks/Mapper/types';
const sortByDist = (a: Route, b: Route) => {
const distA = a.has_connection ? a.systems?.length || 0 : Infinity;
@@ -168,12 +163,6 @@ export const RoutesWidgetContent = () => {
export const RoutesWidgetComp = () => {
const [routeSettingsVisible, setRouteSettingsVisible] = useState(false);
const { data, update } = useRouteProvider();
const {
data: { hubs = [] },
outCommand,
} = useMapRootState();
const preparedHubs = useMemo(() => hubs.map(x => parseInt(x)), [hubs]);
const isSecure = data.path_type === 'secure';
const handleSecureChange = useCallback(() => {
@@ -185,23 +174,6 @@ export const RoutesWidgetComp = () => {
const ref = useRef<HTMLDivElement>(null);
const compact = useMaxWidth(ref, 155);
const [openAddSystem, setOpenAddSystem] = useState<boolean>(false);
const onAddSystem = useCallback(() => setOpenAddSystem(true), []);
const handleSubmitAddSystem: SearchOnSubmitCallback = useCallback(
async item => {
if (preparedHubs.includes(item.value)) {
return;
}
await outCommand({
type: OutCommand.addHub,
data: { system_id: item.value },
});
},
[hubs, outCommand],
);
return (
<Widget
@@ -209,14 +181,6 @@ export const RoutesWidgetComp = () => {
<div className="flex justify-between items-center text-xs w-full" ref={ref}>
<span className="select-none">Routes</span>
<LayoutEventBlocker className="flex items-center gap-2">
<WdImgButton
className={PrimeIcons.PLUS_CIRCLE}
onClick={onAddSystem}
tooltip={{
content: 'Click here to add new system to routes',
}}
/>
<WdTooltipWrapper content="Show shortest route">
<WdCheckbox
size="xs"
@@ -227,26 +191,13 @@ export const RoutesWidgetComp = () => {
classNameLabel={clsx('text-red-400')}
/>
</WdTooltipWrapper>
<WdImgButton
className={PrimeIcons.SLIDERS_H}
onClick={() => setRouteSettingsVisible(true)}
tooltip={{
content: 'Click here to open Routes settings',
}}
/>
<WdImgButton className={PrimeIcons.SLIDERS_H} onClick={() => setRouteSettingsVisible(true)} />
</LayoutEventBlocker>
</div>
}
>
<RoutesWidgetContent />
<RoutesSettingsDialog visible={routeSettingsVisible} setVisible={setRouteSettingsVisible} />
<AddSystemDialog
title="Add system to routes"
visible={openAddSystem}
setVisible={() => setOpenAddSystem(false)}
onSubmit={handleSubmitAddSystem}
/>
</Widget>
);
};

View File

@@ -2,10 +2,7 @@ import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { parseSignatures } from '@/hooks/Mapper/helpers';
import { Commands, OutCommand } from '@/hooks/Mapper/types/mapHandlers.ts';
import { WdTooltip, WdTooltipHandlers } from '@/hooks/Mapper/components/ui-kit';
import {
getGroupIdByRawGroup,
GROUPS_LIST,
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
import { GROUPS_LIST } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
import { DataTable, DataTableRowClickEvent, DataTableRowMouseEvent, SortOrder } from 'primereact/datatable';
import { Column } from 'primereact/column';
@@ -125,14 +122,13 @@ export const SystemSignaturesContent = ({
}
const isCosmicSignature = x.kind === COSMIC_SIGNATURE;
const preparedGroup = getGroupIdByRawGroup(x.group);
if (isCosmicSignature) {
const showCosmicSignatures = settings.find(y => y.key === COSMIC_SIGNATURE)?.value;
if (showCosmicSignatures) {
return !x.group || groupSettings.find(y => y.key === preparedGroup)?.value;
return !x.group || groupSettings.find(y => y.key === x.group)?.value;
} else {
return !!x.group && groupSettings.find(y => y.key === preparedGroup)?.value;
return !!x.group && groupSettings.find(y => y.key === x.group)?.value;
}
}

View File

@@ -1,12 +1,4 @@
import {
GroupType,
SignatureGroup,
SignatureGroupENG,
SignatureGroupRU,
SignatureKind,
SignatureKindENG,
SignatureKindRU,
} from '@/hooks/Mapper/types';
import { GroupType, SignatureGroup } from '@/hooks/Mapper/types';
export const TIME_ONE_MINUTE = 1000 * 60;
export const TIME_TEN_MINUTES = 1000 * 60 * 10;
@@ -32,43 +24,3 @@ export const GROUPS: Record<SignatureGroup, GroupType> = {
[SignatureGroup.Wormhole]: { id: SignatureGroup.Wormhole, icon: '/icons/brackets/wormhole.png', ...wh },
[SignatureGroup.CosmicSignature]: { id: SignatureGroup.CosmicSignature, icon: '/icons/x_close14.png', w: 9, h: 9 },
};
export const MAPPING_GROUP_TO_ENG = {
// ENGLISH
[SignatureGroupENG.GasSite]: SignatureGroup.GasSite,
[SignatureGroupENG.RelicSite]: SignatureGroup.RelicSite,
[SignatureGroupENG.DataSite]: SignatureGroup.DataSite,
[SignatureGroupENG.OreSite]: SignatureGroup.OreSite,
[SignatureGroupENG.CombatSite]: SignatureGroup.CombatSite,
[SignatureGroupENG.Wormhole]: SignatureGroup.Wormhole,
[SignatureGroupENG.CosmicSignature]: SignatureGroup.CosmicSignature,
// RUSSIAN
[SignatureGroupRU.GasSite]: SignatureGroup.GasSite,
[SignatureGroupRU.RelicSite]: SignatureGroup.RelicSite,
[SignatureGroupRU.DataSite]: SignatureGroup.DataSite,
[SignatureGroupRU.OreSite]: SignatureGroup.OreSite,
[SignatureGroupRU.CombatSite]: SignatureGroup.CombatSite,
[SignatureGroupRU.Wormhole]: SignatureGroup.Wormhole,
[SignatureGroupRU.CosmicSignature]: SignatureGroup.CosmicSignature,
};
export const MAPPING_TYPE_TO_ENG = {
// ENGLISH
[SignatureKindENG.CosmicSignature]: SignatureKind.CosmicSignature,
[SignatureKindENG.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindENG.Structure]: SignatureKind.Structure,
[SignatureKindENG.Ship]: SignatureKind.Ship,
[SignatureKindENG.Deployable]: SignatureKind.Deployable,
[SignatureKindENG.Drone]: SignatureKind.Drone,
// RUSSIAN
[SignatureKindRU.CosmicSignature]: SignatureKind.CosmicSignature,
[SignatureKindRU.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindRU.Structure]: SignatureKind.Structure,
[SignatureKindRU.Ship]: SignatureKind.Ship,
[SignatureKindRU.Deployable]: SignatureKind.Deployable,
[SignatureKindRU.Drone]: SignatureKind.Drone,
};
export const getGroupIdByRawGroup = (val: string) => MAPPING_GROUP_TO_ENG[val as SignatureGroup];

View File

@@ -16,8 +16,6 @@ export const MapRootContent = ({}: MapRootContentProps) => {
const { interfaceSettings } = useMapRootState();
const { isShowMenu } = interfaceSettings;
const themeClass = `${interfaceSettings.theme ?? 'default'}-theme`;
const [showOnTheMap, setShowOnTheMap] = useState(false);
const [showMapSettings, setShowMapSettings] = useState(false);
const mapInterface = <MapInterface />;
@@ -28,29 +26,27 @@ export const MapRootContent = ({}: MapRootContentProps) => {
useSkipContextMenu();
return (
<div className={themeClass}>
<Layout map={<MapWrapper />}>
{!isShowMenu ? (
<div className="absolute top-0 left-14 w-[calc(100%-3.5rem)] h-[calc(100%-3.5rem)] pointer-events-none">
<div className="absolute top-0 left-0 w-[calc(100%-3.5rem)] h-full pointer-events-none">
<Topbar />
{mapInterface}
</div>
<div className="absolute top-0 right-0 w-14 h-[calc(100%+3.5rem)] pointer-events-auto">
<RightBar onShowOnTheMap={handleShowOnTheMap} onShowMapSettings={handleShowMapSettings} />
</div>
</div>
) : (
<div className="absolute top-0 left-14 w-[calc(100%-3.5rem)] h-[calc(100%-3.5rem)] pointer-events-none">
<Topbar>
<MapContextMenu onShowOnTheMap={handleShowOnTheMap} onShowMapSettings={handleShowMapSettings} />
</Topbar>
<Layout map={<MapWrapper />}>
{!isShowMenu ? (
<div className="absolute top-0 left-14 w-[calc(100%-3.5rem)] h-[calc(100%-3.5rem)] pointer-events-none">
<div className="absolute top-0 left-0 w-[calc(100%-3.5rem)] h-full pointer-events-none">
<Topbar />
{mapInterface}
</div>
)}
<OnTheMap show={showOnTheMap} onHide={() => setShowOnTheMap(false)} />
<MapSettings show={showMapSettings} onHide={() => setShowMapSettings(false)} />
</Layout>
</div>
<div className="absolute top-0 right-0 w-14 h-[calc(100%+3.5rem)] pointer-events-auto">
<RightBar onShowOnTheMap={handleShowOnTheMap} onShowMapSettings={handleShowMapSettings} />
</div>
</div>
) : (
<div className="absolute top-0 left-14 w-[calc(100%-3.5rem)] h-[calc(100%-3.5rem)] pointer-events-none">
<Topbar>
<MapContextMenu onShowOnTheMap={handleShowOnTheMap} onShowMapSettings={handleShowMapSettings} />
</Topbar>
{mapInterface}
</div>
)}
<OnTheMap show={showOnTheMap} onHide={() => setShowOnTheMap(false)} />
<MapSettings show={showMapSettings} onHide={() => setShowMapSettings(false)} />
</Layout>
);
};

View File

@@ -3,13 +3,8 @@ import { Dialog } from 'primereact/dialog';
import { useCallback, useMemo, useState } from 'react';
import { TabPanel, TabView } from 'primereact/tabview';
import { PrettySwitchbox } from './components';
import {
InterfaceStoredSettingsProps,
useMapRootState,
InterfaceStoredSettings,
} from '@/hooks/Mapper/mapRootProvider';
import { InterfaceStoredSettings, InterfaceStoredSettingsProps, useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { OutCommand } from '@/hooks/Mapper/types';
import { Dropdown } from 'primereact/dropdown';
export enum UserSettingsRemoteProps {
link_signature_on_splash = 'link_signature_on_splash',
@@ -42,171 +37,97 @@ export interface MapSettingsProps {
onHide: () => void;
}
type SettingsListItem = {
type CheckboxesList = {
prop: keyof UserSettings;
label: string;
type: 'checkbox' | 'dropdown';
options?: { label: string; value: string }[];
};
}[];
const COMMON_CHECKBOXES_PROPS: SettingsListItem[] = [
{
prop: InterfaceStoredSettingsProps.isShowMinimap,
label: 'Show Minimap',
type: 'checkbox',
},
const COMMON_CHECKBOXES_PROPS: CheckboxesList = [
{ prop: InterfaceStoredSettingsProps.isShowMinimap, label: 'Show Minimap' },
{ prop: InterfaceStoredSettingsProps.isStickMinimapToLeft, label: 'Stick Minimap to left' },
];
const SYSTEMS_CHECKBOXES_PROPS: SettingsListItem[] = [
{
prop: InterfaceStoredSettingsProps.isShowKSpace,
label: 'Highlight Low/High-security systems',
type: 'checkbox',
},
{
prop: UserSettingsRemoteProps.select_on_spash,
label: 'Auto-select splashed',
type: 'checkbox',
},
const SYSTEMS_CHECKBOXES_PROPS: CheckboxesList = [
{ prop: InterfaceStoredSettingsProps.isShowKSpace, label: 'Highlight Low/High-security systems' },
{ prop: UserSettingsRemoteProps.select_on_spash, label: 'Auto-select splashed' },
];
const SIGNATURES_CHECKBOXES_PROPS: SettingsListItem[] = [
{
prop: UserSettingsRemoteProps.link_signature_on_splash,
label: 'Link signature on splash',
type: 'checkbox',
},
{
prop: InterfaceStoredSettingsProps.isShowUnsplashedSignatures,
label: 'Show unsplashed signatures',
type: 'checkbox',
},
const SIGNATURES_CHECKBOXES_PROPS: CheckboxesList = [
{ prop: UserSettingsRemoteProps.link_signature_on_splash, label: 'Link signature on splash' },
{ prop: InterfaceStoredSettingsProps.isShowUnsplashedSignatures, label: 'Show unsplashed signatures' },
];
const CONNECTIONS_CHECKBOXES_PROPS: SettingsListItem[] = [
{
prop: UserSettingsRemoteProps.delete_connection_with_sigs,
label: 'Delete connections to linked signatures',
type: 'checkbox',
},
{
prop: InterfaceStoredSettingsProps.isThickConnections,
label: 'Thicker connections',
type: 'checkbox',
},
const CONNECTIONS_CHECKBOXES_PROPS: CheckboxesList = [
{ prop: UserSettingsRemoteProps.delete_connection_with_sigs, label: 'Delete connections to linked signatures' },
{ prop: InterfaceStoredSettingsProps.isThickConnections, label: 'Thicker connections' },
];
const UI_CHECKBOXES_PROPS: SettingsListItem[] = [
{
prop: InterfaceStoredSettingsProps.isShowMenu,
label: 'Enable compact map menu bar',
type: 'checkbox',
},
{
prop: InterfaceStoredSettingsProps.isShowBackgroundPattern,
label: 'Show background pattern',
type: 'checkbox',
},
{
prop: InterfaceStoredSettingsProps.isSoftBackground,
label: 'Enable soft background',
type: 'checkbox',
},
const UI_CHECKBOXES_PROPS: CheckboxesList = [
{ prop: InterfaceStoredSettingsProps.isShowMenu, label: 'Enable compact map menu bar' },
{ prop: InterfaceStoredSettingsProps.isShowBackgroundPattern, label: 'Show background pattern' },
{ prop: InterfaceStoredSettingsProps.isSoftBackground, label: 'Enable soft background' },
];
const THEME_OPTIONS = [
{ label: 'Default', value: 'default' },
{ label: 'Pathfinder', value: 'pathfinder' },
];
const THEME_SETTING: SettingsListItem = {
prop: 'theme',
label: 'Theme',
type: 'dropdown',
options: THEME_OPTIONS,
};
export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
const [activeIndex, setActiveIndex] = useState(0);
const { outCommand, interfaceSettings, setInterfaceSettings } = useMapRootState();
const [userRemoteSettings, setUserRemoteSettings] = useState<UserSettingsRemote>({
...DEFAULT_REMOTE_SETTINGS,
});
const [userRemoteSettings, setUserRemoteSettings] = useState<UserSettingsRemote>({ ...DEFAULT_REMOTE_SETTINGS });
const mergedSettings = useMemo(() => {
return {
...userRemoteSettings,
...interfaceSettings,
...userRemoteSettings,
};
}, [userRemoteSettings, interfaceSettings]);
const handleShow = async () => {
const { user_settings } = await outCommand({
type: OutCommand.getUserSettings,
data: null,
});
setUserRemoteSettings({
...user_settings,
});
};
const handleSettingChange = useCallback(
async (prop: keyof UserSettings, value: boolean | string) => {
if (UserSettingsRemoteList.includes(prop as any)) {
const handleChangeChecked = useCallback(
(prop: keyof UserSettings) => async (checked: boolean) => {
// @ts-ignore
if (UserSettingsRemoteList.includes(prop)) {
const newRemoteSettings = {
...userRemoteSettings,
[prop]: value,
[prop]: checked,
};
await outCommand({
type: OutCommand.updateUserSettings,
data: newRemoteSettings,
});
setUserRemoteSettings(newRemoteSettings);
} else {
setInterfaceSettings({
...interfaceSettings,
[prop]: value,
});
return;
}
setInterfaceSettings({
...interfaceSettings,
[prop]: checked,
});
},
[userRemoteSettings, interfaceSettings, outCommand, setInterfaceSettings],
[interfaceSettings, outCommand, setInterfaceSettings, userRemoteSettings],
);
const renderSettingItem = (item: SettingsListItem) => {
const currentValue = mergedSettings[item.prop];
if (item.type === 'checkbox') {
const renderCheckboxesList = (list: CheckboxesList) => {
return list.map(x => {
return (
<PrettySwitchbox
key={item.prop}
label={item.label}
checked={!!currentValue}
setChecked={(checked) => handleSettingChange(item.prop, checked)}
key={x.prop}
label={x.label}
checked={mergedSettings[x.prop]}
setChecked={handleChangeChecked(x.prop)}
/>
);
}
if (item.type === 'dropdown' && item.options) {
return (
<div key={item.prop} className="flex items-center gap-2 mt-2">
<label className="text-sm">{item.label}:</label>
<Dropdown
className="text-sm"
value={currentValue}
options={item.options}
onChange={(e) => handleSettingChange(item.prop, e.value)}
placeholder="Select a theme"
/>
</div>
);
}
return null;
};
const renderSettingsList = (list: SettingsListItem[]) => {
return list.map(renderSettingItem);
});
};
return (
@@ -217,7 +138,10 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
style={{ width: '550px' }}
onShow={handleShow}
onHide={() => {
if (!show) return;
if (!show) {
return;
}
setActiveIndex(0);
onHide();
}}
@@ -227,35 +151,25 @@ export const MapSettings = ({ show, onHide }: MapSettingsProps) => {
<div className={styles.verticalTabsContainer}>
<TabView
activeIndex={activeIndex}
onTabChange={(e) => setActiveIndex(e.index)}
onTabChange={e => setActiveIndex(e.index)}
className={styles.verticalTabView}
>
<TabPanel header="Common" headerClassName={styles.verticalTabHeader}>
<div className="w-full h-full flex flex-col gap-1">
{renderSettingsList(COMMON_CHECKBOXES_PROPS)}
</div>
<div className="w-full h-full flex flex-col gap-1">{renderCheckboxesList(COMMON_CHECKBOXES_PROPS)}</div>
</TabPanel>
<TabPanel header="Systems" headerClassName={styles.verticalTabHeader}>
<div className="w-full h-full flex flex-col gap-1">
{renderSettingsList(SYSTEMS_CHECKBOXES_PROPS)}
{renderCheckboxesList(SYSTEMS_CHECKBOXES_PROPS)}
</div>
</TabPanel>
<TabPanel header="Connections" headerClassName={styles.verticalTabHeader}>
{renderSettingsList(CONNECTIONS_CHECKBOXES_PROPS)}
{renderCheckboxesList(CONNECTIONS_CHECKBOXES_PROPS)}
</TabPanel>
<TabPanel header="Signatures" headerClassName={styles.verticalTabHeader}>
{renderSettingsList(SIGNATURES_CHECKBOXES_PROPS)}
{renderCheckboxesList(SIGNATURES_CHECKBOXES_PROPS)}
</TabPanel>
<TabPanel header="User Interface" headerClassName={styles.verticalTabHeader}>
{renderSettingsList(UI_CHECKBOXES_PROPS)}
</TabPanel>
<TabPanel header="Theme" headerClassName={styles.verticalTabHeader}>
{renderSettingItem(THEME_SETTING)}
{renderCheckboxesList(UI_CHECKBOXES_PROPS)}
</TabPanel>
</TabView>
</div>

View File

@@ -1,3 +1,8 @@
.MiniMap {
right: 3.5rem !important;
&--left {
left: 3.5rem !important;
width: 200px !important;
}
}

View File

@@ -1,8 +1,8 @@
import { Map } from '@/hooks/Mapper/components/map/Map.tsx';
import { useCallback, useRef, useState } from 'react';
import { useCallback, useRef, useState, useMemo } from 'react';
import { OutCommand, OutCommandHandler, SolarSystemConnection } from '@/hooks/Mapper/types';
import { MapRootData, useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { OnMapAddSystemCallback, OnMapSelectionChange } from '@/hooks/Mapper/components/map/map.types.ts';
import { OnMapSelectionChange } from '@/hooks/Mapper/components/map/map.types.ts';
import isEqual from 'lodash.isequal';
import { ContextMenuSystem, useContextMenuSystemHandlers } from '@/hooks/Mapper/components/contexts';
import {
@@ -14,18 +14,14 @@ import classes from './MapWrapper.module.scss';
import { Connections } from '@/hooks/Mapper/components/mapRootContent/components/Connections';
import { ContextMenuSystemMultiple, useContextMenuSystemMultipleHandlers } from '../contexts/ContextMenuSystemMultiple';
import { getSystemById } from '@/hooks/Mapper/helpers';
import { Node, XYPosition } from 'reactflow';
import { Node } from 'reactflow';
import { Commands } from '@/hooks/Mapper/types/mapHandlers.ts';
import { emitMapEvent, useMapEventListener } from '@/hooks/Mapper/events';
import { useMapEventListener } from '@/hooks/Mapper/events';
import { STORED_INTERFACE_DEFAULT_VALUES } from '@/hooks/Mapper/mapRootProvider/MapRootProvider';
import { useDeleteSystems } from '@/hooks/Mapper/components/contexts/hooks';
import { useCommonMapEventProcessor } from '@/hooks/Mapper/components/mapWrapper/hooks/useCommonMapEventProcessor.ts';
import {
AddSystemDialog,
SearchOnSubmitCallback,
} from '@/hooks/Mapper/components/mapInterface/components/AddSystemDialog';
// TODO: INFO - this component needs for abstract work with Map instance
export const MapWrapper = () => {
@@ -36,11 +32,11 @@ export const MapWrapper = () => {
interfaceSettings: {
isShowMenu,
isShowMinimap = STORED_INTERFACE_DEFAULT_VALUES.isShowMinimap,
isStickMinimapToLeft = STORED_INTERFACE_DEFAULT_VALUES.isStickMinimapToLeft,
isShowKSpace,
isThickConnections,
isShowBackgroundPattern,
isSoftBackground,
theme,
},
} = useMapRootState();
const { deleteSystems } = useDeleteSystems();
@@ -52,7 +48,6 @@ export const MapWrapper = () => {
const [openSettings, setOpenSettings] = useState<string | null>(null);
const [openLinkSignatures, setOpenLinkSignatures] = useState<any | null>(null);
const [openCustomLabel, setOpenCustomLabel] = useState<string | null>(null);
const [openAddSystem, setOpenAddSystem] = useState<XYPosition | null>(null);
const [selectedConnection, setSelectedConnection] = useState<SolarSystemConnection | null>(null);
const ref = useRef({ selectedConnections, selectedSystems, systemContextProps, systems, deleteSystems });
@@ -68,6 +63,18 @@ export const MapWrapper = () => {
runCommand(event);
});
const minimapClasses = useMemo(() => {
if (isStickMinimapToLeft) {
return classes['MiniMap--left'];
}
if (!isShowMenu) {
return classes.MiniMap;
}
return undefined;
}, [isShowMenu, isStickMinimapToLeft]);
const onSelectionChange: OnMapSelectionChange = useCallback(
({ systems, connections }) => {
const { selectedConnections, selectedSystems } = ref.current;
@@ -129,28 +136,6 @@ export const MapWrapper = () => {
}
}, []);
const onAddSystem: OnMapAddSystemCallback = useCallback(({ coordinates }) => {
setOpenAddSystem(coordinates);
}, []);
const handleSubmitAddSystem: SearchOnSubmitCallback = useCallback(
async item => {
if (ref.current.systems.some(x => x.system_static_info.solar_system_id === item.value)) {
emitMapEvent({
name: Commands.centerSystem,
data: item.value.toString(),
});
return;
}
await outCommand({
type: OutCommand.manualAddSystem,
data: { coordinates: openAddSystem, solar_system_id: item.value },
});
},
[openAddSystem, outCommand],
);
return (
<>
<Map
@@ -160,15 +145,13 @@ export const MapWrapper = () => {
onConnectionInfoClick={handleConnectionDbClick}
onSystemContextMenu={handleSystemContextMenu}
onSelectionContextMenu={handleSystemMultipleContext}
minimapClasses={!isShowMenu ? classes.MiniMap : undefined}
minimapClasses={minimapClasses}
isShowMinimap={isShowMinimap}
showKSpaceBG={isShowKSpace}
onManualDelete={handleManualDelete}
isThickConnections={isThickConnections}
isShowBackgroundPattern={isShowBackgroundPattern}
isSoftBackground={isSoftBackground}
theme={theme}
onAddSystem={onAddSystem}
/>
{openSettings != null && (
@@ -183,12 +166,6 @@ export const MapWrapper = () => {
<SystemLinkSignatureDialog data={openLinkSignatures} setVisible={() => setOpenLinkSignatures(null)} />
)}
<AddSystemDialog
visible={!!openAddSystem}
setVisible={() => setOpenAddSystem(null)}
onSubmit={handleSubmitAddSystem}
/>
<Connections selectedConnection={selectedConnection} onHide={() => setSelectedConnection(null)} />
<ContextMenuSystem

View File

@@ -31,15 +31,12 @@ const prepareEffects = (effects: Record<string, EffectRaw>, effectName: string,
return out;
};
let counter = 0;
export interface WHEffectViewProps {
effectName: string;
effectPower: number;
className?: string;
}
export const WHEffectView = ({ effectName, effectPower, className }: WHEffectViewProps) => {
export const WHEffectView = ({ effectName, effectPower }: WHEffectViewProps) => {
const {
data: { effects },
} = useMapRootState();
@@ -52,7 +49,7 @@ export const WHEffectView = ({ effectName, effectPower, className }: WHEffectVie
[effectName, effectPower, effects],
);
const targetClass = useMemo(() => `wh-effect-name${effectInfo.id}-${counter++}`, []);
const targetClass = `wh-effect-name${effectInfo.id}`;
return (
<div className={classes.WHEffectViewRoot}>
@@ -87,7 +84,7 @@ export const WHEffectView = ({ effectName, effectPower, className }: WHEffectVie
</div>
</FixedTooltip>
<div className={clsx('font-bold select-none cursor-help w-min-content', effectClass, targetClass, className)}>
<div className={clsx('font-bold select-none cursor-help w-min-content', effectClass, targetClass)}>
{effectName}
</div>
</div>

View File

@@ -1,5 +1,5 @@
import { SignatureGroup, SignatureKind, SystemSignature } from '@/hooks/Mapper/types';
import { MAPPING_TYPE_TO_ENG } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
import { COSMIC_SIGNATURE } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/SystemSignatureSettingsDialog';
import { SystemSignature } from '@/hooks/Mapper/types';
export const parseSignatures = (value: string, availableKeys: string[]): SystemSignature[] => {
const outArr: SystemSignature[] = [];
@@ -14,12 +14,10 @@ export const parseSignatures = (value: string, availableKeys: string[]): SystemS
continue;
}
const kind = MAPPING_TYPE_TO_ENG[sigArrInfo[1] as SignatureKind];
outArr.push({
eve_id: sigArrInfo[0],
kind: availableKeys.includes(kind) ? kind : SignatureKind.CosmicSignature,
group: sigArrInfo[2] as SignatureGroup,
kind: availableKeys.includes(sigArrInfo[1]) ? sigArrInfo[1] : COSMIC_SIGNATURE,
group: sigArrInfo[2],
name: sigArrInfo[3],
type: '',
});

View File

@@ -32,35 +32,35 @@ const INITIAL_DATA: MapRootData = {
export enum InterfaceStoredSettingsProps {
isShowMenu = 'isShowMenu',
isShowMinimap = 'isShowMinimap',
isStickMinimapToLeft = 'isStickMinimapToLeft',
isShowKSpace = 'isShowKSpace',
isThickConnections = 'isThickConnections',
isShowUnsplashedSignatures = 'isShowUnsplashedSignatures',
isShowBackgroundPattern = 'isShowBackgroundPattern',
isSoftBackground = 'isSoftBackground',
theme = 'theme',
}
export type InterfaceStoredSettings = {
isShowMenu: boolean;
isShowMinimap: boolean;
isStickMinimapToLeft: boolean;
isShowKSpace: boolean;
isThickConnections: boolean;
isShowUnsplashedSignatures: boolean;
isShowBackgroundPattern: boolean;
isSoftBackground: boolean;
theme: string;
};
export const STORED_INTERFACE_DEFAULT_VALUES: InterfaceStoredSettings = {
isShowMenu: false,
isShowMinimap: true,
isStickMinimapToLeft: false,
isShowKSpace: false,
isThickConnections: false,
isShowUnsplashedSignatures: false,
isShowBackgroundPattern: true,
isSoftBackground: false,
theme: 'default',
}
};
export interface MapRootContextProps {
update: ContextStoreDataUpdate<MapRootData>;

View File

@@ -129,7 +129,6 @@ export enum OutCommand {
updateConnectionCustomInfo = 'update_connection_custom_info',
updateSignatures = 'update_signatures',
updateSystemName = 'update_system_name',
updateSystemTemporaryName = 'update_system_temporary_name',
updateSystemDescription = 'update_system_description',
updateSystemLabels = 'update_system_labels',
updateSystemLocked = 'update_system_locked',
@@ -154,7 +153,6 @@ export enum OutCommand {
getUserSettings = 'get_user_settings',
updateUserSettings = 'update_user_settings',
unlinkSignature = 'unlink_signature',
searchSystems = 'search_systems',
}
export type OutCommandHandler = <T = any>(event: { type: OutCommand; data: any }) => Promise<T>;

View File

@@ -10,15 +10,6 @@ export enum SignatureGroup {
CombatSite = 'Combat Site',
}
export enum SignatureKind {
CosmicSignature = 'Cosmic Signature',
CosmicAnomaly = 'Cosmic Anomaly',
Structure = 'Structure',
Ship = 'Ship',
Deployable = 'Deployable',
Drone = 'Drone',
}
export type GroupType = {
id: string;
icon: string;
@@ -28,7 +19,7 @@ export type GroupType = {
export type SystemSignature = {
eve_id: string;
kind: SignatureKind;
kind: string;
name: string;
custom_info?: string;
description?: string;
@@ -39,41 +30,3 @@ export type SystemSignature = {
inserted_at?: string;
updated_at?: string;
};
export enum SignatureKindENG {
CosmicSignature = 'Cosmic Signature',
CosmicAnomaly = 'Cosmic Anomaly',
Structure = 'Structure',
Ship = 'Ship',
Deployable = 'Deployable',
Drone = 'Drone',
}
export enum SignatureKindRU {
CosmicSignature = 'Скрытый сигнал',
CosmicAnomaly = 'Космическая аномалия',
Structure = 'Сооружение',
Ship = 'Корабль',
Deployable = 'Полевые блоки',
Drone = 'Дрон',
}
export enum SignatureGroupENG {
CosmicSignature = 'Cosmic Signature',
Wormhole = 'Wormhole',
GasSite = 'Gas Site',
RelicSite = 'Relic Site',
DataSite = 'Data Site',
OreSite = 'Ore Site',
CombatSite = 'Combat Site',
}
export enum SignatureGroupRU {
CosmicSignature = 'Скрытый сигнал',
Wormhole = 'Червоточина',
GasSite = 'Газовый район',
RelicSite = 'Археологический район',
DataSite = 'Информационный район',
OreSite = 'Астероидный район',
CombatSite = 'Боевой район',
}

View File

@@ -116,18 +116,7 @@ export type SolarSystemRawType = {
tag: string | null;
status: number;
name: string | null;
temporary_name: string | null;
system_static_info: SolarSystemStaticInfoRaw;
system_signatures: SystemSignature[];
};
export type SearchSystemItem = {
class_title: string;
constellation_name: string;
label: string;
region_name: string;
system_static_info: SolarSystemStaticInfoRaw;
value: number;
};

View File

@@ -1,14 +1,17 @@
export default {
mounted() {
const button = this.el;
const hook = this;
const url = hook.el.dataset.url;
const button = hook.el;
button.addEventListener('click', function () {
// Get the URL from the data attribute
button.classList.remove('copied');
// Copy the URL to the clipboard
navigator.clipboard
.writeText(button.dataset.url)
.writeText(url)
.then(() => {
button.classList.add('copied');
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -48,11 +48,6 @@ port =
scheme = System.get_env("WEB_EXTERNAL_SCHEME", "http")
public_api_disabled =
config_dir
|> get_var_from_path_or_env("WANDERER_PUBLIC_API_DISABLED", "false")
|> String.to_existing_atom()
map_subscriptions_enabled =
config_dir
|> get_var_from_path_or_env("WANDERER_MAP_SUBSCRIPTIONS_ENABLED", "false")
@@ -66,18 +61,6 @@ map_subscription_hubs_limit =
config_dir
|> get_int_from_path_or_env("WANDERER_MAP_SUBSCRIPTION_HUBS_LIMIT", 100)
map_connection_auto_expire_hours =
config_dir
|> get_int_from_path_or_env("WANDERER_MAP_CONNECTION_AUTO_EXPIRE_HOURS", 24)
map_connection_auto_eol_hours =
config_dir
|> get_int_from_path_or_env("WANDERER_MAP_CONNECTION_AUTO_EOL_HOURS", 21)
map_connection_eol_expire_timeout_mins =
config_dir
|> get_int_from_path_or_env("WANDERER_MAP_CONNECTION_EOL_EXPIRE_TIMEOUT_MINS", 30)
wallet_tracking_enabled =
config_dir
|> get_var_from_path_or_env("WANDERER_WALLET_TRACKING_ENABLED", "false")
@@ -100,11 +83,7 @@ config :wanderer_app,
admins: admins,
corp_id: System.get_env("WANDERER_CORP_ID", "-1") |> String.to_integer(),
corp_wallet: System.get_env("WANDERER_CORP_WALLET", ""),
public_api_disabled: public_api_disabled,
map_subscriptions_enabled: map_subscriptions_enabled,
map_connection_auto_expire_hours: map_connection_auto_expire_hours,
map_connection_auto_eol_hours: map_connection_auto_eol_hours,
map_connection_eol_expire_timeout_mins: map_connection_eol_expire_timeout_mins,
wallet_tracking_enabled: wallet_tracking_enabled,
subscription_settings: %{
plans: [

View File

@@ -21,7 +21,6 @@ defmodule WandererApp.Api.Map do
define(:update_options, action: :update_options)
define(:assign_owner, action: :assign_owner)
define(:mark_as_deleted, action: :mark_as_deleted)
define(:update_api_key, action: :update_api_key)
define(:by_id,
get_by: [:id],
@@ -123,11 +122,6 @@ defmodule WandererApp.Api.Map do
change(set_attribute(:deleted, true))
end
update :update_api_key do
accept [:public_api_key]
end
end
attributes do
@@ -147,10 +141,6 @@ defmodule WandererApp.Api.Map do
attribute :description, :string
attribute :personal_note, :string
attribute :public_api_key, :string do
allow_nil? true
end
attribute :hubs, {:array, :string} do
allow_nil?(true)

View File

@@ -14,24 +14,31 @@ defmodule WandererApp.Api.MapCharacterSettings do
define(:create, action: :create)
define(:destroy, action: :destroy)
define(:read_by_map, action: :read_by_map)
define(:by_map_filtered, action: :by_map_filtered)
define(:tracked_by_map_filtered, action: :tracked_by_map_filtered)
define(:tracked_by_map_all, action: :tracked_by_map_all)
define(:read_by_map,
action: :read_by_map
)
define(:by_map_filtered,
action: :by_map_filtered
)
define(:tracked_by_map_filtered,
action: :tracked_by_map_filtered
)
define(:tracked_by_map_all,
action: :tracked_by_map_all
)
define(:track, action: :track)
define(:untrack, action: :untrack)
define(:follow, action: :follow)
define(:unfollow, action: :unfollow)
end
actions do
default_accept [
:map_id,
:character_id,
:tracked,
:followed
:tracked
]
defaults [:create, :read, :update, :destroy]
@@ -69,14 +76,6 @@ defmodule WandererApp.Api.MapCharacterSettings do
update :untrack do
change(set_attribute(:tracked, false))
end
update :follow do
change(set_attribute(:followed, true))
end
update :unfollow do
change(set_attribute(:followed, false))
end
end
attributes do
@@ -87,11 +86,6 @@ defmodule WandererApp.Api.MapCharacterSettings do
allow_nil? true
end
attribute :followed, :boolean do
default false
allow_nil? true
end
create_timestamp(:inserted_at)
update_timestamp(:updated_at)
end

View File

@@ -46,9 +46,7 @@ defmodule WandererApp.Api.MapSystem do
define(:update_locked, action: :update_locked)
define(:update_status, action: :update_status)
define(:update_tag, action: :update_tag)
define(:update_temporary_name, action: :update_temporary_name)
define(:update_labels, action: :update_labels)
define(:update_linked_sig_eve_id, action: :update_linked_sig_eve_id)
define(:update_position, action: :update_position)
define(:update_visible, action: :update_visible)
end
@@ -104,10 +102,6 @@ defmodule WandererApp.Api.MapSystem do
accept [:tag]
end
update :update_temporary_name do
accept [:temporary_name]
end
update :update_labels do
accept [:labels]
end
@@ -118,10 +112,6 @@ defmodule WandererApp.Api.MapSystem do
change(set_attribute(:visible, true))
end
update :update_linked_sig_eve_id do
accept [:linked_sig_eve_id]
end
update :update_visible do
accept [:visible]
end
@@ -151,10 +141,6 @@ defmodule WandererApp.Api.MapSystem do
allow_nil? true
end
attribute :temporary_name, :string do
allow_nil? true
end
attribute :labels, :string do
allow_nil? true
end
@@ -198,10 +184,6 @@ defmodule WandererApp.Api.MapSystem do
allow_nil? true
end
attribute :linked_sig_eve_id, :string do
allow_nil? true
end
create_timestamp(:inserted_at)
update_timestamp(:updated_at)
end

View File

@@ -489,7 +489,7 @@ defmodule WandererApp.Character.Tracker do
defp maybe_update_location(
%{
character_id: character_id,
character_id: character_id
} =
state,
location

View File

@@ -1,6 +1,5 @@
defmodule WandererApp.Env do
@moduledoc false
use Nebulex.Caching
@app :wanderer_app
@@ -10,7 +9,6 @@ defmodule WandererApp.Env do
def custom_route_base_url, do: get_key(:custom_route_base_url, "<CUSTOM_ROUTE_BASE_URL>")
def invites, do: get_key(:invites, false)
def map_subscriptions_enabled?, do: get_key(:map_subscriptions_enabled, false)
def public_api_disabled?, do: get_key(:public_api_disabled, false)
def wallet_tracking_enabled?, do: get_key(:wallet_tracking_enabled, false)
def admins, do: get_key(:admins, [])
def admin_username, do: get_key(:admin_username)
@@ -18,25 +16,5 @@ defmodule WandererApp.Env do
def corp_wallet, do: get_key(:corp_wallet, "")
def corp_eve_id, do: get_key(:corp_id, -1)
def subscription_settings, do: get_key(:subscription_settings)
@decorate cacheable(
cache: WandererApp.Cache,
key: "map-connection-auto-expire-hours"
)
def map_connection_auto_expire_hours, do: get_key(:map_connection_auto_expire_hours)
@decorate cacheable(
cache: WandererApp.Cache,
key: "map-connection-auto-eol-hours"
)
def map_connection_auto_eol_hours, do: get_key(:map_connection_auto_eol_hours)
@decorate cacheable(
cache: WandererApp.Cache,
key: "map-connection-eol-expire-timeout-mins"
)
def map_connection_eol_expire_timeout_mins,
do: get_key(:map_connection_eol_expire_timeout_mins)
def get_key(key, default \\ nil), do: Application.get_env(@app, key, default)
end

View File

@@ -31,7 +31,7 @@ defmodule WandererApp.Esi.ApiClient do
}
@cache_opts [cache: true]
@retry_opts [max_retries: 1, retry_log_level: :warning]
@retry_opts [retry: false, retry_log_level: :warning]
@timeout_opts [receive_timeout: :timer.seconds(30)]
@api_retry_count 1

View File

@@ -70,11 +70,6 @@ defmodule WandererApp.Map do
def get_characters_limit(map_id),
do: {:ok, map_id |> get_map!() |> Map.get(:characters_limit, 100)}
def is_subscription_active?(map_id) do
{:ok, %{plan: plan}} = WandererApp.Map.SubscriptionManager.get_active_map_subscription(map_id)
not WandererApp.Env.map_subscriptions_enabled?() || plan != :alpha
end
def get_options(map_id),
do: {:ok, map_id |> get_map!() |> Map.get(:options, Map.new())}

View File

@@ -9,38 +9,20 @@ defmodule WandererApp.Map.Audit do
@logger Application.compile_env(:wanderer_app, :logger)
@week_seconds :timer.hours(24 * 7)
@month_seconds @week_seconds * 4
@audit_expired_seconds @month_seconds * 3
def track_map_subscription_event(event_type, metadata) do
case event_type do
"subscription.created" ->
track_map_event(event_type, metadata)
"subscription.updated" ->
track_map_event(event_type, metadata)
"subscription.deleted" ->
track_map_event(event_type, metadata)
_ ->
{:ok, nil}
end
end
def archive() do
Logger.info("Start map audit arhiving...")
@logger.info("Start map audit arhiving...")
WandererApp.Api.UserActivity
|> Ash.Query.filter(inserted_at: [less_than: get_expired_at()])
|> Ash.Query.filter(inserted_at: [less_than: _get_expired_at()])
|> Ash.bulk_destroy!(:archive, %{}, batch_size: 100)
Logger.info(fn -> "Audit arhived" end)
@logger.info(fn -> "Audit arhived" end)
:ok
end
def get_activity_page(map_id, page, per_page, period, activity) do
{from, to} = period |> get_period()
{from, to} = period |> _get_period()
query =
WandererApp.Api.UserActivity
@@ -102,43 +84,52 @@ defmodule WandererApp.Map.Audit do
def track_map_event(_event_type, _metadata), do: {:ok, nil}
defp get_period("1H") do
defp _get_period("1H") do
now = DateTime.utc_now()
start_date = now |> DateTime.add(-1 * 3600, :second)
{start_date, now}
end
defp get_period("1D") do
defp _get_period("1D") do
now = DateTime.utc_now()
start_date = now |> DateTime.add(-24 * 3600, :second)
{start_date, now}
end
defp get_period("1W") do
defp _get_period("1W") do
now = DateTime.utc_now()
start_date = now |> DateTime.add(-24 * 3600 * 7, :second)
{start_date, now}
end
defp get_period("1M") do
# defp _get_period("1M") do
# now = DateTime.utc_now()
# start_date = now |> DateTime.add(-24 * 3600 * 31, :second)
# {start_date, now}
# end
# defp _get_period("ALL") do
# now = DateTime.utc_now()
# start_date = %{
# now
# | year: 2000,
# month: 1,
# day: 1,
# hour: 00,
# minute: 00,
# second: 00,
# microsecond: {0, 0}
# }
# {start_date, now}
# end
defp _get_period(_) do
now = DateTime.utc_now()
start_date = now |> DateTime.add(-24 * 3600 * 31, :second)
start_date = now |> DateTime.add(-1 * 3600, :second)
{start_date, now}
end
defp get_period("2M") do
now = DateTime.utc_now()
start_date = now |> DateTime.add(-24 * 3600 * 31 * 2, :second)
{start_date, now}
end
defp get_period("3M") do
now = DateTime.utc_now()
start_date = now |> DateTime.add(-24 * 3600 * 31 * 3, :second)
{start_date, now}
end
defp get_period(_), do: get_period("1H")
defp get_expired_at(), do: DateTime.utc_now() |> DateTime.add(-@audit_expired_seconds, :second)
defp _get_expired_at(), do: DateTime.utc_now() |> DateTime.add(-@week_seconds, :second)
end

View File

@@ -105,12 +105,6 @@ defmodule WandererApp.Map.Server do
|> map_pid!
|> GenServer.cast({&Impl.update_system_position/2, [update]})
def update_system_linked_sig_eve_id(map_id, update) when is_binary(map_id),
do:
map_id
|> map_pid!
|> GenServer.cast({&Impl.update_system_linked_sig_eve_id/2, [update]})
def update_system_name(map_id, update) when is_binary(map_id),
do:
map_id
@@ -135,12 +129,6 @@ defmodule WandererApp.Map.Server do
|> map_pid!
|> GenServer.cast({&Impl.update_system_tag/2, [update]})
def update_system_temporary_name(map_id, update) when is_binary(map_id),
do:
map_id
|> map_pid!
|> GenServer.cast({&Impl.update_system_temporary_name/2, [update]})
def update_system_locked(map_id, update) when is_binary(map_id),
do:
map_id

View File

@@ -150,14 +150,10 @@ defmodule WandererApp.Map.Server.Impl do
defdelegate update_system_tag(state, update), to: SystemsImpl
defdelegate update_system_temporary_name(state, update), to: SystemsImpl
defdelegate update_system_locked(state, update), to: SystemsImpl
defdelegate update_system_labels(state, update), to: SystemsImpl
defdelegate update_system_linked_sig_eve_id(state, update), to: SystemsImpl
defdelegate update_system_position(state, update), to: SystemsImpl
defdelegate add_hub(state, hub_info), to: SystemsImpl
@@ -205,7 +201,7 @@ defmodule WandererApp.Map.Server.Impl do
| map: map |> WandererApp.Map.update_subscription_settings!(subscription_settings)
}
def handle_event(:update_characters, state) do
def handle_event(:update_characters, %{map_id: map_id} = state) do
Process.send_after(self(), :update_characters, @update_characters_timeout)
CharactersImpl.update_characters(state)
@@ -263,7 +259,7 @@ defmodule WandererApp.Map.Server.Impl do
state
end
def handle_event(:cleanup_systems, state) do
def handle_event(:cleanup_systems, %{map_id: map_id} = state) do
Process.send_after(self(), :cleanup_systems, @systems_cleanup_timeout)
state |> SystemsImpl.cleanup_systems()
@@ -324,10 +320,6 @@ defmodule WandererApp.Map.Server.Impl do
layout: options |> Map.get("layout", "left_to_right"),
store_custom_labels:
options |> Map.get("store_custom_labels", "false") |> String.to_existing_atom(),
show_linked_signature_id:
options |> Map.get("show_linked_signature_id", "false") |> String.to_existing_atom(),
show_temp_system_name:
options |> Map.get("show_temp_system_name", "false") |> String.to_existing_atom(),
restrict_offline_showing:
options |> Map.get("restrict_offline_showing", "false") |> String.to_existing_atom()
]
@@ -435,8 +427,7 @@ defmodule WandererApp.Map.Server.Impl do
"name" => name,
"position" => %{"x" => x, "y" => y},
"status" => status,
"tag" => tag,
"temporary_name" => temporary_name
"tag" => tag
} = _system,
acc ->
acc
@@ -455,10 +446,6 @@ defmodule WandererApp.Map.Server.Impl do
})
|> update_system_status(%{solar_system_id: id |> String.to_integer(), status: status})
|> update_system_tag(%{solar_system_id: id |> String.to_integer(), tag: tag})
|> update_system_temporary_name(%{
solar_system_id: id |> String.to_integer(),
temporary_name: temporary_name
})
|> update_system_locked(%{solar_system_id: id |> String.to_integer(), locked: locked})
|> update_system_labels(%{solar_system_id: id |> String.to_integer(), labels: labels})
end)

View File

@@ -15,12 +15,13 @@ defmodule WandererApp.Map.Server.CharactersImpl do
WandererApp.MapCharacterSettingsRepo.create(%{
character_id: character_id,
map_id: map_id,
tracked: track_character,
followed: false
tracked: track_character
}),
{:ok, character} <- WandererApp.Character.get_character(character_id) do
Impl.broadcast!(map_id, :character_added, character)
:telemetry.execute([:wanderer_app, :map, :character, :added], %{count: 1})
:ok
else
_error ->
@@ -381,6 +382,7 @@ defmodule WandererApp.Map.Server.CharactersImpl do
{:character_location, %{solar_system_id: solar_system_id},
%{solar_system_id: old_solar_system_id}}
]
_ ->
[:skip]
end

View File

@@ -67,29 +67,20 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
# @unknown 100_100
#
@connection_time_status_eol 1
@connection_auto_eol_hours 21
@connection_auto_expire_hours 24
@connection_eol_expire_timeout :timer.hours(3) + :timer.minutes(30)
@connection_type_wormhole 0
@connection_type_stargate 1
def get_connection_auto_expire_hours(), do: WandererApp.Env.map_connection_auto_expire_hours()
def get_connection_auto_eol_hours(), do: WandererApp.Env.map_connection_auto_eol_hours()
def get_eol_expire_timeout_mins(), do: WandererApp.Env.map_connection_eol_expire_timeout_mins()
def get_eol_expire_timeout(),
do:
:timer.hours(get_connection_auto_expire_hours() - get_connection_auto_eol_hours()) +
:timer.minutes(get_eol_expire_timeout_mins())
def init_eol_cache(map_id, connections_eol_time) do
eol_expire_timeout = get_eol_expire_timeout()
connections_eol_time
|> Enum.each(fn {connection_id, connection_eol_time} ->
WandererApp.Cache.put(
"map_#{map_id}:conn_#{connection_id}:mark_eol_time",
connection_eol_time,
ttl: eol_expire_timeout
ttl: @connection_eol_expire_timeout
)
end)
end
@@ -164,7 +155,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
WandererApp.Cache.put(
"map_#{map_id}:conn_#{connection_id}:mark_eol_time",
DateTime.utc_now(),
ttl: get_eol_expire_timeout()
ttl: @connection_eol_expire_timeout
)
_ ->
@@ -203,9 +194,6 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
do: update_connection(state, :update_custom_info, [:custom_info], connection_update)
def cleanup_connections(%{map_id: map_id} = state) do
connection_auto_expire_hours = get_connection_auto_expire_hours()
connection_auto_eol_hours = get_connection_auto_eol_hours()
state =
map_id
|> WandererApp.Map.list_connections!()
@@ -217,7 +205,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
} ->
type != @connection_type_stargate &&
DateTime.diff(DateTime.utc_now(), inserted_at, :hour) >=
connection_auto_eol_hours &&
@connection_auto_eol_hours &&
is_connection_valid(
:wormholes,
solar_system_source_id,
@@ -274,9 +262,9 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
not is_connection_exist ||
(type != @connection_type_stargate && is_connection_valid &&
(DateTime.diff(DateTime.utc_now(), inserted_at, :hour) >=
connection_auto_expire_hours ||
@connection_auto_expire_hours ||
DateTime.diff(DateTime.utc_now(), connection_mark_eol_time, :hour) >=
connection_auto_expire_hours - connection_auto_eol_hours))
@connection_auto_expire_hours - @connection_auto_eol_hours))
end)
|> Enum.reduce(state, fn %{
solar_system_source: solar_system_source_id,
@@ -358,18 +346,8 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
:ok
{:error, :already_exists} ->
# Still broadcast location change in case of followed character
Impl.broadcast!(map_id, :maybe_select_system, %{
character_id: character_id,
solar_system_id: location.solar_system_id
})
:ok
{:error, error} ->
Logger.debug(fn -> "Failed to add connection: #{inspect(error, pretty: true)}" end)
:ok
end
end
@@ -381,30 +359,33 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
def can_add_location(:none, _solar_system_id), do: false
def can_add_location(scope, solar_system_id) do
{:ok, system_static_info} = get_system_static_info(solar_system_id)
system_static_info =
case WandererApp.CachedInfo.get_system_static_info(solar_system_id) do
{:ok, system_static_info} when not is_nil(system_static_info) ->
system_static_info
_ ->
%{system_class: nil}
end
case scope do
:wormholes ->
not is_prohibited_system_class?(system_static_info.system_class) and
not (@prohibited_system_classes |> Enum.member?(system_static_info.system_class)) and
not (@prohibited_systems |> Enum.member?(solar_system_id)) and
@wh_space |> Enum.member?(system_static_info.system_class)
:stargates ->
not is_prohibited_system_class?(system_static_info.system_class) and
not (@prohibited_system_classes |> Enum.member?(system_static_info.system_class)) and
@known_space |> Enum.member?(system_static_info.system_class)
:all ->
not is_prohibited_system_class?(system_static_info.system_class)
not (@prohibited_system_classes |> Enum.member?(system_static_info.system_class))
_ ->
false
end
end
def is_prohibited_system_class?(system_class) do
@prohibited_system_classes |> Enum.member?(system_class)
end
def is_connection_exist(map_id, from_solar_system_id, to_solar_system_id),
do:
not is_nil(
@@ -433,21 +414,24 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
current_system_id: to_solar_system_id
})
{:ok, from_system_static_info} = get_system_static_info(from_solar_system_id)
{:ok, to_system_static_info} = get_system_static_info(to_solar_system_id)
system_static_info =
case WandererApp.CachedInfo.get_system_static_info(to_solar_system_id) do
{:ok, system_static_info} when not is_nil(system_static_info) ->
system_static_info
_ ->
%{system_class: nil}
end
case scope do
:wormholes ->
not is_prohibited_system_class?(from_system_static_info.system_class) and
not is_prohibited_system_class?(to_system_static_info.system_class) and
not (@prohibited_systems |> Enum.member?(from_solar_system_id)) and
not (@prohibited_system_classes |> Enum.member?(system_static_info.system_class)) and
not (@prohibited_systems |> Enum.member?(to_solar_system_id)) and
known_jumps |> Enum.empty?() and to_solar_system_id != @jita and
from_solar_system_id != @jita
:stargates ->
not is_prohibited_system_class?(from_system_static_info.system_class) and
not is_prohibited_system_class?(to_system_static_info.system_class) and
not (@prohibited_system_classes |> Enum.member?(system_static_info.system_class)) and
not (known_jumps |> Enum.empty?())
end
end
@@ -463,16 +447,6 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
end
end
defp get_system_static_info(solar_system_id) do
case WandererApp.CachedInfo.get_system_static_info(solar_system_id) do
{:ok, system_static_info} when not is_nil(system_static_info) ->
{:ok, system_static_info}
_ ->
{:ok, %{system_class: nil}}
end
end
defp maybe_remove_connection(map_id, location, old_location)
when not is_nil(location) and not is_nil(old_location) and
location.solar_system_id != old_location.solar_system_id do

View File

@@ -122,13 +122,6 @@ defmodule WandererApp.Map.Server.SystemsImpl do
),
do: state |> update_system(:update_tag, [:tag], update)
def update_system_temporary_name(
state,
update
) do
state |> update_system(:update_temporary_name, [:temporary_name], update)
end
def update_system_locked(
state,
update
@@ -141,12 +134,6 @@ defmodule WandererApp.Map.Server.SystemsImpl do
),
do: state |> update_system(:update_labels, [:labels], update)
def update_system_linked_sig_eve_id(
state,
update
),
do: state |> update_system(:update_linked_sig_eve_id, [:linked_sig_eve_id], update)
def update_system_position(
%{rtree_name: rtree_name} = state,
update
@@ -290,7 +277,7 @@ defmodule WandererApp.Map.Server.SystemsImpl do
location.solar_system_id
) do
{:ok, existing_system} when not is_nil(existing_system) ->
updated_system =
{:ok, updated_system} =
existing_system
|> WandererApp.MapSystemRepo.update_position!(%{
position_x: position.x,
@@ -298,9 +285,7 @@ defmodule WandererApp.Map.Server.SystemsImpl do
})
|> WandererApp.MapSystemRepo.cleanup_labels!(map_opts)
|> WandererApp.MapSystemRepo.update_visible!(%{visible: true})
|> WandererApp.MapSystemRepo.cleanup_tags!()
|> WandererApp.MapSystemRepo.cleanup_temporary_name!()
|> WandererApp.MapSystemRepo.cleanup_linked_sig_eve_id!()
|> WandererApp.MapSystemRepo.cleanup_tags()
@ddrt.insert(
{existing_system.solar_system_id,
@@ -419,8 +404,6 @@ defmodule WandererApp.Map.Server.SystemsImpl do
|> WandererApp.MapSystemRepo.update_position!(%{position_x: x, position_y: y})
|> WandererApp.MapSystemRepo.cleanup_labels!(map_opts)
|> WandererApp.MapSystemRepo.cleanup_tags!()
|> WandererApp.MapSystemRepo.cleanup_temporary_name!()
|> WandererApp.MapSystemRepo.cleanup_linked_sig_eve_id!()
|> WandererApp.MapSystemRepo.update_visible(%{visible: true})
end

View File

@@ -84,22 +84,20 @@ defmodule WandererApp.Maps do
id: id,
eve_id: eve_id,
corporation_ticker: corporation_ticker,
tracked: false,
followed: false
tracked: false
}
def map_character(
%{name: name, id: id, eve_id: eve_id, corporation_ticker: corporation_ticker} =
_character,
%{tracked: tracked, followed: followed} = _character_settings
%{tracked: tracked} = _character_settings
),
do: %{
name: name,
id: id,
eve_id: eve_id,
corporation_ticker: corporation_ticker,
tracked: tracked,
followed: followed
tracked: tracked
}
@decorate cacheable(

View File

@@ -24,31 +24,11 @@ defmodule WandererApp.MapCharacterSettingsRepo do
def get_tracked_by_map_all(map_id),
do: WandererApp.Api.MapCharacterSettings.tracked_by_map_all(%{map_id: map_id})
def get_by_map(map_id, character_id) do
case get_by_map_filtered(map_id, [character_id]) do
{:ok, [setting | _]} ->
{:ok, setting}
{:ok, []} ->
{:error, :not_found}
{:error, reason} ->
{:error, reason}
end
end
def track(settings), do: settings |> WandererApp.Api.MapCharacterSettings.track()
def untrack(settings), do: settings |> WandererApp.Api.MapCharacterSettings.untrack()
def track!(settings), do: settings |> WandererApp.Api.MapCharacterSettings.track!()
def untrack!(settings), do: settings |> WandererApp.Api.MapCharacterSettings.untrack!()
def follow(settings), do: settings |> WandererApp.Api.MapCharacterSettings.follow()
def unfollow(settings), do: settings |> WandererApp.Api.MapCharacterSettings.unfollow()
def follow!(settings), do: settings |> WandererApp.Api.MapCharacterSettings.follow!()
def unfollow!(settings), do: settings |> WandererApp.Api.MapCharacterSettings.unfollow!()
def destroy!(settings), do: settings |> WandererApp.Api.MapCharacterSettings.destroy!()
end

View File

@@ -4,8 +4,6 @@ defmodule WandererApp.MapRepo do
@default_map_options %{
"layout" => "left_to_right",
"store_custom_labels" => "false",
"show_linked_signature_id" => "false",
"show_temp_system_name" => "false",
"restrict_offline_showing" => "false"
}

View File

@@ -16,13 +16,11 @@ defmodule WandererApp.MapSystemRepo do
end
end
def get_all_by_map(map_id) do
WandererApp.Api.MapSystem.read_all_by_map(%{map_id: map_id})
end
def get_all_by_map(map_id),
do: WandererApp.Api.MapSystem.read_all_by_map(%{map_id: map_id})
def get_visible_by_map(map_id) do
WandererApp.Api.MapSystem.read_visible_by_map(%{map_id: map_id})
end
def get_visible_by_map(map_id),
do: WandererApp.Api.MapSystem.read_visible_by_map(%{map_id: map_id})
def remove_from_map(map_id, solar_system_id) do
WandererApp.Api.MapSystem.read_by_map_and_solar_system!(%{
@@ -61,27 +59,6 @@ defmodule WandererApp.MapSystemRepo do
})
end
def cleanup_temporary_name(system) do
system
|> WandererApp.Api.MapSystem.update_temporary_name(%{
temporary_name: nil
})
end
def cleanup_temporary_name!(system) do
system
|> WandererApp.Api.MapSystem.update_temporary_name!(%{
temporary_name: nil
})
end
def cleanup_linked_sig_eve_id!(system) do
system
|> WandererApp.Api.MapSystem.update_linked_sig_eve_id!(%{
linked_sig_eve_id: nil
})
end
def get_filtered_labels(labels, true) when is_binary(labels) do
labels
|> Jason.decode!()
@@ -122,11 +99,6 @@ defmodule WandererApp.MapSystemRepo do
system
|> WandererApp.Api.MapSystem.update_tag(update)
def update_temporary_name(system, update) do
system
|> WandererApp.Api.MapSystem.update_temporary_name(update)
end
def update_labels(system, update),
do:
system
@@ -137,16 +109,6 @@ defmodule WandererApp.MapSystemRepo do
system
|> WandererApp.Api.MapSystem.update_labels!(update)
def update_linked_sig_eve_id(system, update),
do:
system
|> WandererApp.Api.MapSystem.update_linked_sig_eve_id(update)
def update_linked_sig_eve_id!(system, update),
do:
system
|> WandererApp.Api.MapSystem.update_linked_sig_eve_id!(update)
def update_position(system, update),
do:
system

View File

@@ -1,47 +0,0 @@
defmodule WandererAppWeb.CharacterActivity do
use WandererAppWeb, :live_component
use LiveViewEvents
@impl true
def mount(socket) do
{:ok, socket}
end
@impl true
def update(
assigns,
socket
) do
{:ok,
socket
|> handle_info_or_assign(assigns)}
end
def render(assigns) do
~H"""
<div id={@id}>
<.table class="!max-h-[80vh] !overflow-y-auto" id="activity-tbl" rows={@activity}>
<:col :let={row} label="Character">
<.character_item character={row.character} />
</:col>
<:col :let={row} label="Passages">
<%= row.count %>
</:col>
</.table>
</div>
"""
end
def character_item(assigns) do
~H"""
<div class="flex items-center gap-3">
<div class="avatar">
<div class="rounded-md w-12 h-12">
<img src={member_icon_url(@character.eve_id)} alt={@character.name} />
</div>
</div>
<%= @character.name %>
</div>
"""
end
end

Some files were not shown because too many files have changed in this diff Show More