mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-11 18:26:04 +00:00
feat: support german and french signatures
This commit is contained in:
@@ -25,12 +25,16 @@ function useSignatureUndo(
|
|||||||
settings: SignatureSettingsType,
|
settings: SignatureSettingsType,
|
||||||
outCommand: OutCommandHandler,
|
outCommand: OutCommandHandler,
|
||||||
) {
|
) {
|
||||||
const [pendingIds, setPendingIds] = useState<string[]>([]);
|
const [countdown, setCountdown] = useState<number>(0);
|
||||||
const [countdown, setCountdown] = useState(0);
|
const [pendingIds, setPendingIds] = useState<Set<string>>(new Set());
|
||||||
const intervalRef = useRef<number | null>(null);
|
const intervalRef = useRef<number | null>(null);
|
||||||
|
|
||||||
const addDeleted = useCallback((ids: string[]) => {
|
const addDeleted = useCallback((ids: string[]) => {
|
||||||
setPendingIds(prev => [...prev, ...ids]);
|
setPendingIds(prev => {
|
||||||
|
const next = new Set(prev);
|
||||||
|
ids.forEach(id => next.add(id));
|
||||||
|
return next;
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// kick off or clear countdown whenever pendingIds changes
|
// kick off or clear countdown whenever pendingIds changes
|
||||||
@@ -41,7 +45,7 @@ function useSignatureUndo(
|
|||||||
intervalRef.current = null;
|
intervalRef.current = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pendingIds.length === 0) {
|
if (pendingIds.size === 0) {
|
||||||
setCountdown(0);
|
setCountdown(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -58,7 +62,7 @@ function useSignatureUndo(
|
|||||||
if (prev <= 1) {
|
if (prev <= 1) {
|
||||||
clearInterval(intervalRef.current!);
|
clearInterval(intervalRef.current!);
|
||||||
intervalRef.current = null;
|
intervalRef.current = null;
|
||||||
setPendingIds([]);
|
setPendingIds(new Set());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return prev - 1;
|
return prev - 1;
|
||||||
@@ -71,16 +75,16 @@ function useSignatureUndo(
|
|||||||
intervalRef.current = null;
|
intervalRef.current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [pendingIds, settings]);
|
}, [pendingIds, settings[SETTINGS_KEYS.DELETION_TIMING]]);
|
||||||
|
|
||||||
// undo handler
|
// undo handler
|
||||||
const handleUndo = useCallback(async () => {
|
const handleUndo = useCallback(async () => {
|
||||||
if (!systemId || pendingIds.length === 0) return;
|
if (!systemId || pendingIds.size === 0) return;
|
||||||
await outCommand({
|
await outCommand({
|
||||||
type: OutCommand.undoDeleteSignatures,
|
type: OutCommand.undoDeleteSignatures,
|
||||||
data: { system_id: systemId, eve_ids: pendingIds },
|
data: { system_id: systemId, eve_ids: Array.from(pendingIds) },
|
||||||
});
|
});
|
||||||
setPendingIds([]);
|
setPendingIds(new Set());
|
||||||
setCountdown(0);
|
setCountdown(0);
|
||||||
if (intervalRef.current != null) {
|
if (intervalRef.current != null) {
|
||||||
clearInterval(intervalRef.current);
|
clearInterval(intervalRef.current);
|
||||||
@@ -117,7 +121,7 @@ export const SystemSignatures = () => {
|
|||||||
const { pendingIds, countdown, addDeleted, handleUndo } = useSignatureUndo(systemId, currentSettings, outCommand);
|
const { pendingIds, countdown, addDeleted, handleUndo } = useSignatureUndo(systemId, currentSettings, outCommand);
|
||||||
|
|
||||||
useHotkey(true, ['z', 'Z'], (event: KeyboardEvent) => {
|
useHotkey(true, ['z', 'Z'], (event: KeyboardEvent) => {
|
||||||
if (pendingIds.length > 0 && countdown > 0) {
|
if (pendingIds.size > 0 && countdown > 0) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
handleUndo();
|
handleUndo();
|
||||||
@@ -154,7 +158,7 @@ export const SystemSignatures = () => {
|
|||||||
<SystemSignaturesHeader
|
<SystemSignaturesHeader
|
||||||
sigCount={sigCount}
|
sigCount={sigCount}
|
||||||
lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean}
|
lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean}
|
||||||
pendingCount={pendingIds.length}
|
pendingCount={pendingIds.size}
|
||||||
undoCountdown={countdown}
|
undoCountdown={countdown}
|
||||||
onLazyDeleteChange={handleLazyDeleteToggle}
|
onLazyDeleteChange={handleLazyDeleteToggle}
|
||||||
onUndoClick={handleUndo}
|
onUndoClick={handleUndo}
|
||||||
|
|||||||
@@ -90,14 +90,21 @@ export const SystemSignaturesContent = ({
|
|||||||
{ defaultValue: SORT_DEFAULT_VALUES },
|
{ defaultValue: SORT_DEFAULT_VALUES },
|
||||||
);
|
);
|
||||||
|
|
||||||
const { signatures, selectedSignatures, setSelectedSignatures, handleDeleteSelected, handleSelectAll, handlePaste } =
|
const {
|
||||||
useSystemSignaturesData({
|
signatures,
|
||||||
systemId,
|
selectedSignatures,
|
||||||
settings,
|
setSelectedSignatures,
|
||||||
onCountChange,
|
handleDeleteSelected,
|
||||||
onLazyDeleteChange,
|
handleSelectAll,
|
||||||
onSignatureDeleted,
|
handlePaste,
|
||||||
});
|
hasUnsupportedLanguage,
|
||||||
|
} = useSystemSignaturesData({
|
||||||
|
systemId,
|
||||||
|
settings,
|
||||||
|
onCountChange,
|
||||||
|
onLazyDeleteChange,
|
||||||
|
onSignatureDeleted,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectable) return;
|
if (selectable) return;
|
||||||
@@ -186,7 +193,11 @@ export const SystemSignaturesContent = ({
|
|||||||
x => GROUPS_LIST.includes(x as SignatureGroup) && settings[x as SETTINGS_KEYS],
|
x => GROUPS_LIST.includes(x as SignatureGroup) && settings[x as SETTINGS_KEYS],
|
||||||
);
|
);
|
||||||
|
|
||||||
return enabledGroups.includes(getGroupIdByRawGroup(sig.group));
|
const mappedGroup = getGroupIdByRawGroup(sig.group);
|
||||||
|
if (!mappedGroup) {
|
||||||
|
return true; // If we can't determine the group, still show it
|
||||||
|
}
|
||||||
|
return enabledGroups.includes(mappedGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -234,113 +245,121 @@ export const SystemSignaturesContent = ({
|
|||||||
No signatures
|
No signatures
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<DataTable
|
<>
|
||||||
value={filteredSignatures}
|
{hasUnsupportedLanguage && (
|
||||||
size="small"
|
<div className="w-full flex justify-center items-center text-amber-500 text-xs p-1 bg-amber-950/20 border-b border-amber-800/30">
|
||||||
selectionMode="multiple"
|
<i className={PrimeIcons.EXCLAMATION_TRIANGLE + ' mr-1'} />
|
||||||
selection={selectedSignatures}
|
Non-English signatures detected. Some signatures may not display correctly. Double-click to edit signature details.
|
||||||
metaKeySelection
|
</div>
|
||||||
onSelectionChange={handleSelectSignatures}
|
|
||||||
dataKey="eve_id"
|
|
||||||
className="w-full select-none"
|
|
||||||
resizableColumns={false}
|
|
||||||
rowHover
|
|
||||||
selectAll
|
|
||||||
onRowDoubleClick={handleRowClick}
|
|
||||||
sortField={sortSettings.sortField}
|
|
||||||
sortOrder={sortSettings.sortOrder}
|
|
||||||
onSort={handleSortSettings}
|
|
||||||
onRowMouseEnter={onRowMouseEnter}
|
|
||||||
onRowMouseLeave={onRowMouseLeave}
|
|
||||||
// @ts-ignore
|
|
||||||
rowClassName={getRowClassName}
|
|
||||||
>
|
|
||||||
<Column
|
|
||||||
field="icon"
|
|
||||||
header=""
|
|
||||||
body={renderColIcon}
|
|
||||||
bodyClassName="p-0 px-1"
|
|
||||||
style={{ maxWidth: 26, minWidth: 26, width: 26 }}
|
|
||||||
/>
|
|
||||||
<Column
|
|
||||||
field="eve_id"
|
|
||||||
header="Id"
|
|
||||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
|
||||||
style={{ maxWidth: 72, minWidth: 72, width: 72 }}
|
|
||||||
sortable
|
|
||||||
/>
|
|
||||||
<Column
|
|
||||||
field="group"
|
|
||||||
header="Group"
|
|
||||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
|
||||||
style={{ maxWidth: 110, minWidth: 110, width: 110 }}
|
|
||||||
body={sig => sig.group ?? ''}
|
|
||||||
hidden={isCompact}
|
|
||||||
sortable
|
|
||||||
/>
|
|
||||||
<Column
|
|
||||||
field="info"
|
|
||||||
header="Info"
|
|
||||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
|
||||||
style={{ maxWidth: nameColumnWidth }}
|
|
||||||
hidden={isCompact || isMedium}
|
|
||||||
body={renderInfoColumn}
|
|
||||||
/>
|
|
||||||
{showDescriptionColumn && (
|
|
||||||
<Column
|
|
||||||
field="description"
|
|
||||||
header="Description"
|
|
||||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
|
||||||
hidden={isCompact}
|
|
||||||
body={renderDescription}
|
|
||||||
sortable
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<Column
|
<DataTable
|
||||||
field="inserted_at"
|
value={filteredSignatures}
|
||||||
header="Added"
|
size="small"
|
||||||
dataType="date"
|
selectionMode="multiple"
|
||||||
body={renderAddedTimeLeft}
|
selection={selectedSignatures}
|
||||||
style={{ minWidth: 70, maxWidth: 80 }}
|
metaKeySelection
|
||||||
bodyClassName="ssc-header text-ellipsis overflow-hidden whitespace-nowrap"
|
onSelectionChange={handleSelectSignatures}
|
||||||
sortable
|
dataKey="eve_id"
|
||||||
/>
|
className="w-full select-none"
|
||||||
{showUpdatedColumn && (
|
resizableColumns={false}
|
||||||
<Column
|
rowHover
|
||||||
field="updated_at"
|
selectAll
|
||||||
header="Updated"
|
onRowDoubleClick={handleRowClick}
|
||||||
dataType="date"
|
sortField={sortSettings.sortField}
|
||||||
body={renderUpdatedTimeLeft}
|
sortOrder={sortSettings.sortOrder}
|
||||||
style={{ minWidth: 70, maxWidth: 80 }}
|
onSort={handleSortSettings}
|
||||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
onRowMouseEnter={onRowMouseEnter}
|
||||||
sortable
|
onRowMouseLeave={onRowMouseLeave}
|
||||||
/>
|
// @ts-ignore
|
||||||
)}
|
rowClassName={getRowClassName}
|
||||||
|
>
|
||||||
{showCharacterColumn && (
|
|
||||||
<Column
|
|
||||||
field="character_name"
|
|
||||||
header="Character"
|
|
||||||
bodyClassName="w-[70px] text-ellipsis overflow-hidden whitespace-nowrap"
|
|
||||||
sortable
|
|
||||||
></Column>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!selectable && (
|
|
||||||
<Column
|
<Column
|
||||||
|
field="icon"
|
||||||
header=""
|
header=""
|
||||||
body={() => (
|
body={renderColIcon}
|
||||||
<div className="flex justify-end items-center gap-2 mr-[4px]">
|
bodyClassName="p-0 px-1"
|
||||||
<WdTooltipWrapper content="Double-click a row to edit signature">
|
|
||||||
<span className={PrimeIcons.PENCIL + ' text-[10px]'} />
|
|
||||||
</WdTooltipWrapper>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
style={{ maxWidth: 26, minWidth: 26, width: 26 }}
|
style={{ maxWidth: 26, minWidth: 26, width: 26 }}
|
||||||
bodyClassName="p-0 pl-1 pr-2"
|
|
||||||
/>
|
/>
|
||||||
)}
|
<Column
|
||||||
</DataTable>
|
field="eve_id"
|
||||||
|
header="Id"
|
||||||
|
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
style={{ maxWidth: 72, minWidth: 72, width: 72 }}
|
||||||
|
sortable
|
||||||
|
/>
|
||||||
|
<Column
|
||||||
|
field="group"
|
||||||
|
header="Group"
|
||||||
|
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
style={{ maxWidth: 110, minWidth: 110, width: 110 }}
|
||||||
|
body={sig => sig.group ?? ''}
|
||||||
|
hidden={isCompact}
|
||||||
|
sortable
|
||||||
|
/>
|
||||||
|
<Column
|
||||||
|
field="info"
|
||||||
|
header="Info"
|
||||||
|
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
style={{ maxWidth: nameColumnWidth }}
|
||||||
|
hidden={isCompact || isMedium}
|
||||||
|
body={renderInfoColumn}
|
||||||
|
/>
|
||||||
|
{showDescriptionColumn && (
|
||||||
|
<Column
|
||||||
|
field="description"
|
||||||
|
header="Description"
|
||||||
|
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
hidden={isCompact}
|
||||||
|
body={renderDescription}
|
||||||
|
sortable
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Column
|
||||||
|
field="inserted_at"
|
||||||
|
header="Added"
|
||||||
|
dataType="date"
|
||||||
|
body={renderAddedTimeLeft}
|
||||||
|
style={{ minWidth: 70, maxWidth: 80 }}
|
||||||
|
bodyClassName="ssc-header text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
sortable
|
||||||
|
/>
|
||||||
|
{showUpdatedColumn && (
|
||||||
|
<Column
|
||||||
|
field="updated_at"
|
||||||
|
header="Updated"
|
||||||
|
dataType="date"
|
||||||
|
body={renderUpdatedTimeLeft}
|
||||||
|
style={{ minWidth: 70, maxWidth: 80 }}
|
||||||
|
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
sortable
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showCharacterColumn && (
|
||||||
|
<Column
|
||||||
|
field="character_name"
|
||||||
|
header="Character"
|
||||||
|
bodyClassName="w-[70px] text-ellipsis overflow-hidden whitespace-nowrap"
|
||||||
|
sortable
|
||||||
|
></Column>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!selectable && (
|
||||||
|
<Column
|
||||||
|
header=""
|
||||||
|
body={() => (
|
||||||
|
<div className="flex justify-end items-center gap-2 mr-[4px]">
|
||||||
|
<WdTooltipWrapper content="Double-click a row to edit signature">
|
||||||
|
<span className={PrimeIcons.PENCIL + ' text-[10px]'} />
|
||||||
|
</WdTooltipWrapper>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
style={{ maxWidth: 26, minWidth: 26, width: 26 }}
|
||||||
|
bodyClassName="p-0 pl-1 pr-2"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</DataTable>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<WdTooltip
|
<WdTooltip
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
GroupType,
|
GroupType,
|
||||||
SignatureGroup,
|
SignatureGroup,
|
||||||
|
SignatureGroupDE,
|
||||||
SignatureGroupENG,
|
SignatureGroupENG,
|
||||||
|
SignatureGroupFR,
|
||||||
SignatureGroupRU,
|
SignatureGroupRU,
|
||||||
SignatureKind,
|
SignatureKind,
|
||||||
|
SignatureKindDE,
|
||||||
SignatureKindENG,
|
SignatureKindENG,
|
||||||
|
SignatureKindFR,
|
||||||
SignatureKindRU,
|
SignatureKindRU,
|
||||||
} from '@/hooks/Mapper/types';
|
} from '@/hooks/Mapper/types';
|
||||||
|
|
||||||
@@ -40,46 +44,58 @@ export const GROUPS: Record<SignatureGroup, GroupType> = {
|
|||||||
[SignatureGroup.CosmicSignature]: { id: SignatureGroup.CosmicSignature, icon: '/icons/x_close14.png', w: 9, h: 9 },
|
[SignatureGroup.CosmicSignature]: { id: SignatureGroup.CosmicSignature, icon: '/icons/x_close14.png', w: 9, h: 9 },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MAPPING_GROUP_TO_ENG = {
|
export const LANGUAGE_GROUP_MAPPINGS = {
|
||||||
// ENGLISH
|
EN: {
|
||||||
[SignatureGroupENG.GasSite]: SignatureGroup.GasSite,
|
[SignatureGroupENG.GasSite]: SignatureGroup.GasSite,
|
||||||
[SignatureGroupENG.RelicSite]: SignatureGroup.RelicSite,
|
[SignatureGroupENG.RelicSite]: SignatureGroup.RelicSite,
|
||||||
[SignatureGroupENG.DataSite]: SignatureGroup.DataSite,
|
[SignatureGroupENG.DataSite]: SignatureGroup.DataSite,
|
||||||
[SignatureGroupENG.OreSite]: SignatureGroup.OreSite,
|
[SignatureGroupENG.OreSite]: SignatureGroup.OreSite,
|
||||||
[SignatureGroupENG.CombatSite]: SignatureGroup.CombatSite,
|
[SignatureGroupENG.CombatSite]: SignatureGroup.CombatSite,
|
||||||
[SignatureGroupENG.Wormhole]: SignatureGroup.Wormhole,
|
[SignatureGroupENG.Wormhole]: SignatureGroup.Wormhole,
|
||||||
[SignatureGroupENG.CosmicSignature]: SignatureGroup.CosmicSignature,
|
[SignatureGroupENG.CosmicSignature]: SignatureGroup.CosmicSignature,
|
||||||
|
},
|
||||||
// RUSSIAN
|
RU: {
|
||||||
[SignatureGroupRU.GasSite]: SignatureGroup.GasSite,
|
[SignatureGroupRU.GasSite]: SignatureGroup.GasSite,
|
||||||
[SignatureGroupRU.RelicSite]: SignatureGroup.RelicSite,
|
[SignatureGroupRU.RelicSite]: SignatureGroup.RelicSite,
|
||||||
[SignatureGroupRU.DataSite]: SignatureGroup.DataSite,
|
[SignatureGroupRU.DataSite]: SignatureGroup.DataSite,
|
||||||
[SignatureGroupRU.OreSite]: SignatureGroup.OreSite,
|
[SignatureGroupRU.OreSite]: SignatureGroup.OreSite,
|
||||||
[SignatureGroupRU.CombatSite]: SignatureGroup.CombatSite,
|
[SignatureGroupRU.CombatSite]: SignatureGroup.CombatSite,
|
||||||
[SignatureGroupRU.Wormhole]: SignatureGroup.Wormhole,
|
[SignatureGroupRU.Wormhole]: SignatureGroup.Wormhole,
|
||||||
[SignatureGroupRU.CosmicSignature]: SignatureGroup.CosmicSignature,
|
[SignatureGroupRU.CosmicSignature]: SignatureGroup.CosmicSignature,
|
||||||
|
},
|
||||||
|
FR: {
|
||||||
|
[SignatureGroupFR.GasSite]: SignatureGroup.GasSite,
|
||||||
|
[SignatureGroupFR.RelicSite]: SignatureGroup.RelicSite,
|
||||||
|
[SignatureGroupFR.DataSite]: SignatureGroup.DataSite,
|
||||||
|
[SignatureGroupFR.OreSite]: SignatureGroup.OreSite,
|
||||||
|
[SignatureGroupFR.CombatSite]: SignatureGroup.CombatSite,
|
||||||
|
[SignatureGroupFR.Wormhole]: SignatureGroup.Wormhole,
|
||||||
|
[SignatureGroupFR.CosmicSignature]: SignatureGroup.CosmicSignature,
|
||||||
|
},
|
||||||
|
DE: {
|
||||||
|
[SignatureGroupDE.GasSite]: SignatureGroup.GasSite,
|
||||||
|
[SignatureGroupDE.RelicSite]: SignatureGroup.RelicSite,
|
||||||
|
[SignatureGroupDE.DataSite]: SignatureGroup.DataSite,
|
||||||
|
[SignatureGroupDE.OreSite]: SignatureGroup.OreSite,
|
||||||
|
[SignatureGroupDE.CombatSite]: SignatureGroup.CombatSite,
|
||||||
|
[SignatureGroupDE.Wormhole]: SignatureGroup.Wormhole,
|
||||||
|
[SignatureGroupDE.CosmicSignature]: SignatureGroup.CosmicSignature,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MAPPING_TYPE_TO_ENG = {
|
// Flatten the structure for backward compatibility
|
||||||
// ENGLISH
|
export const MAPPING_GROUP_TO_ENG: Record<string, SignatureGroup> = (() => {
|
||||||
[SignatureKindENG.CosmicSignature]: SignatureKind.CosmicSignature,
|
const flattened: Record<string, SignatureGroup> = {};
|
||||||
[SignatureKindENG.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
|
for (const [, mappings] of Object.entries(LANGUAGE_GROUP_MAPPINGS)) {
|
||||||
[SignatureKindENG.Structure]: SignatureKind.Structure,
|
Object.assign(flattened, mappings);
|
||||||
[SignatureKindENG.Ship]: SignatureKind.Ship,
|
}
|
||||||
[SignatureKindENG.Deployable]: SignatureKind.Deployable,
|
return flattened;
|
||||||
[SignatureKindENG.Drone]: SignatureKind.Drone,
|
})();
|
||||||
|
|
||||||
// RUSSIAN
|
export const getGroupIdByRawGroup = (val: string): SignatureGroup | undefined => {
|
||||||
[SignatureKindRU.CosmicSignature]: SignatureKind.CosmicSignature,
|
return MAPPING_GROUP_TO_ENG[val] || undefined;
|
||||||
[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];
|
|
||||||
|
|
||||||
export const SIGNATURE_WINDOW_ID = 'system_signatures_window';
|
export const SIGNATURE_WINDOW_ID = 'system_signatures_window';
|
||||||
export const SIGNATURE_SETTING_STORE_KEY = 'wanderer_system_signature_settings_v6_5';
|
export const SIGNATURE_SETTING_STORE_KEY = 'wanderer_system_signature_settings_v6_5';
|
||||||
|
|
||||||
@@ -123,7 +139,7 @@ export type Setting = {
|
|||||||
name: string;
|
name: string;
|
||||||
type: SettingsTypes;
|
type: SettingsTypes;
|
||||||
isSeparator?: boolean;
|
isSeparator?: boolean;
|
||||||
options?: { label: string; value: any }[];
|
options?: { label: string; value: number | string | boolean }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum SIGNATURES_DELETION_TIMING {
|
export enum SIGNATURES_DELETION_TIMING {
|
||||||
@@ -208,3 +224,52 @@ export const SIGNATURE_DELETION_TIMEOUTS: SignatureDeletionTimingType = {
|
|||||||
[SIGNATURES_DELETION_TIMING.IMMEDIATE]: 0,
|
[SIGNATURES_DELETION_TIMING.IMMEDIATE]: 0,
|
||||||
[SIGNATURES_DELETION_TIMING.EXTENDED]: 30_000,
|
[SIGNATURES_DELETION_TIMING.EXTENDED]: 30_000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Replace the flat structure with a nested structure by language
|
||||||
|
export const LANGUAGE_TYPE_MAPPINGS = {
|
||||||
|
EN: {
|
||||||
|
[SignatureKindENG.CosmicSignature]: SignatureKind.CosmicSignature,
|
||||||
|
[SignatureKindENG.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
|
||||||
|
[SignatureKindENG.Structure]: SignatureKind.Structure,
|
||||||
|
[SignatureKindENG.Ship]: SignatureKind.Ship,
|
||||||
|
[SignatureKindENG.Deployable]: SignatureKind.Deployable,
|
||||||
|
[SignatureKindENG.Drone]: SignatureKind.Drone,
|
||||||
|
[SignatureKindENG.Starbase]: SignatureKind.Starbase,
|
||||||
|
},
|
||||||
|
RU: {
|
||||||
|
[SignatureKindRU.CosmicSignature]: SignatureKind.CosmicSignature,
|
||||||
|
[SignatureKindRU.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
|
||||||
|
[SignatureKindRU.Structure]: SignatureKind.Structure,
|
||||||
|
[SignatureKindRU.Ship]: SignatureKind.Ship,
|
||||||
|
[SignatureKindRU.Deployable]: SignatureKind.Deployable,
|
||||||
|
[SignatureKindRU.Drone]: SignatureKind.Drone,
|
||||||
|
[SignatureKindRU.Starbase]: SignatureKind.Starbase,
|
||||||
|
},
|
||||||
|
FR: {
|
||||||
|
[SignatureKindFR.CosmicSignature]: SignatureKind.CosmicSignature,
|
||||||
|
[SignatureKindFR.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
|
||||||
|
[SignatureKindFR.Structure]: SignatureKind.Structure,
|
||||||
|
[SignatureKindFR.Ship]: SignatureKind.Ship,
|
||||||
|
[SignatureKindFR.Deployable]: SignatureKind.Deployable,
|
||||||
|
[SignatureKindFR.Drone]: SignatureKind.Drone,
|
||||||
|
[SignatureKindFR.Starbase]: SignatureKind.Starbase,
|
||||||
|
},
|
||||||
|
DE: {
|
||||||
|
[SignatureKindDE.CosmicSignature]: SignatureKind.CosmicSignature,
|
||||||
|
[SignatureKindDE.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
|
||||||
|
[SignatureKindDE.Structure]: SignatureKind.Structure,
|
||||||
|
[SignatureKindDE.Ship]: SignatureKind.Ship,
|
||||||
|
[SignatureKindDE.Deployable]: SignatureKind.Deployable,
|
||||||
|
[SignatureKindDE.Drone]: SignatureKind.Drone,
|
||||||
|
[SignatureKindDE.Starbase]: SignatureKind.Starbase,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Flatten the structure for backward compatibility
|
||||||
|
export const MAPPING_TYPE_TO_ENG: Record<string, SignatureKind> = (() => {
|
||||||
|
const flattened: Record<string, SignatureKind> = {};
|
||||||
|
for (const [, mappings] of Object.entries(LANGUAGE_TYPE_MAPPINGS)) {
|
||||||
|
Object.assign(flattened, mappings);
|
||||||
|
}
|
||||||
|
return flattened;
|
||||||
|
})();
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ export const useSystemSignaturesData = ({
|
|||||||
onPendingChange,
|
onPendingChange,
|
||||||
onLazyDeleteChange,
|
onLazyDeleteChange,
|
||||||
onSignatureDeleted,
|
onSignatureDeleted,
|
||||||
}: Omit<UseSystemSignaturesDataProps, 'deletionTiming'> & { onSignatureDeleted?: (deletedIds: string[]) => void }) => {
|
}: Omit<UseSystemSignaturesDataProps, 'deletionTiming'> & {
|
||||||
|
onSignatureDeleted?: (deletedIds: string[]) => void;
|
||||||
|
}) => {
|
||||||
const { outCommand } = useMapRootState();
|
const { outCommand } = useMapRootState();
|
||||||
const [signatures, setSignatures, signaturesRef] = useRefState<ExtendedSystemSignature[]>([]);
|
const [signatures, setSignatures, signaturesRef] = useRefState<ExtendedSystemSignature[]>([]);
|
||||||
const [selectedSignatures, setSelectedSignatures] = useState<ExtendedSystemSignature[]>([]);
|
const [selectedSignatures, setSelectedSignatures] = useState<ExtendedSystemSignature[]>([]);
|
||||||
|
const [hasUnsupportedLanguage, setHasUnsupportedLanguage] = useState<boolean>(false);
|
||||||
|
|
||||||
const { pendingDeletionMapRef, processRemovedSignatures, clearPendingDeletions } = usePendingDeletions({
|
const { pendingDeletionMapRef, processRemovedSignatures, clearPendingDeletions } = usePendingDeletions({
|
||||||
systemId,
|
systemId,
|
||||||
@@ -41,6 +44,7 @@ export const useSystemSignaturesData = ({
|
|||||||
async (clipboardString: string) => {
|
async (clipboardString: string) => {
|
||||||
const lazyDeleteValue = settings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean;
|
const lazyDeleteValue = settings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean;
|
||||||
|
|
||||||
|
// Parse the incoming signatures
|
||||||
const incomingSignatures = parseSignatures(
|
const incomingSignatures = parseSignatures(
|
||||||
clipboardString,
|
clipboardString,
|
||||||
Object.keys(settings).filter(skey => skey in SignatureKind),
|
Object.keys(settings).filter(skey => skey in SignatureKind),
|
||||||
@@ -50,6 +54,18 @@ export const useSystemSignaturesData = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if any signatures might be using unsupported languages
|
||||||
|
// This is a basic heuristic: if we have signatures where the original group wasn't mapped
|
||||||
|
const clipboardRows = clipboardString.split('\n').filter(row => row.trim() !== '');
|
||||||
|
const detectedSignatureCount = clipboardRows.filter(row => row.match(/^[A-Z]{3}-\d{3}/)).length;
|
||||||
|
|
||||||
|
// If we detected valid IDs but got fewer parsed signatures, we might have language issues
|
||||||
|
if (detectedSignatureCount > 0 && incomingSignatures.length < detectedSignatureCount) {
|
||||||
|
setHasUnsupportedLanguage(true);
|
||||||
|
} else {
|
||||||
|
setHasUnsupportedLanguage(false);
|
||||||
|
}
|
||||||
|
|
||||||
const currentNonPending = lazyDeleteValue
|
const currentNonPending = lazyDeleteValue
|
||||||
? signaturesRef.current.filter(sig => !sig.pendingDeletion)
|
? signaturesRef.current.filter(sig => !sig.pendingDeletion)
|
||||||
: signaturesRef.current.filter(sig => !sig.pendingDeletion || !sig.pendingAddition);
|
: signaturesRef.current.filter(sig => !sig.pendingDeletion || !sig.pendingAddition);
|
||||||
@@ -127,5 +143,6 @@ export const useSystemSignaturesData = ({
|
|||||||
handleDeleteSelected,
|
handleDeleteSelected,
|
||||||
handleSelectAll,
|
handleSelectAll,
|
||||||
handlePaste,
|
handlePaste,
|
||||||
|
hasUnsupportedLanguage,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { SignatureGroup, SignatureKind, SystemSignature } from '@/hooks/Mapper/types';
|
import { SignatureGroup, SignatureKind, SystemSignature } from '@/hooks/Mapper/types';
|
||||||
import { MAPPING_TYPE_TO_ENG } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
|
import {
|
||||||
|
MAPPING_GROUP_TO_ENG,
|
||||||
|
MAPPING_TYPE_TO_ENG,
|
||||||
|
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
|
||||||
|
|
||||||
export const parseSignatures = (value: string, availableKeys: string[]): SystemSignature[] => {
|
export const parseSignatures = (value: string, availableKeys: string[]): SystemSignature[] => {
|
||||||
const outArr: SystemSignature[] = [];
|
const outArr: SystemSignature[] = [];
|
||||||
@@ -14,13 +17,37 @@ export const parseSignatures = (value: string, availableKeys: string[]): SystemS
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const kind = MAPPING_TYPE_TO_ENG[sigArrInfo[1] as SignatureKind];
|
// Extract the signature ID and check if it's valid (XXX-XXX format)
|
||||||
|
const sigId = sigArrInfo[0];
|
||||||
|
if (!sigId || !sigId.match(/^[A-Z]{3}-\d{3}$/)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to map the kind, or fall back to CosmicSignature if unknown
|
||||||
|
const typeString = sigArrInfo[1];
|
||||||
|
let kind = SignatureKind.CosmicSignature;
|
||||||
|
|
||||||
|
// Try to map the kind using the flattened mapping
|
||||||
|
const mappedKind = MAPPING_TYPE_TO_ENG[typeString];
|
||||||
|
if (mappedKind && availableKeys.includes(mappedKind)) {
|
||||||
|
kind = mappedKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to map the group, or fall back to CosmicSignature if unknown
|
||||||
|
const rawGroup = sigArrInfo[2];
|
||||||
|
let group = SignatureGroup.CosmicSignature;
|
||||||
|
|
||||||
|
// Try to map the group using the flattened mapping
|
||||||
|
const mappedGroup = MAPPING_GROUP_TO_ENG[rawGroup];
|
||||||
|
if (mappedGroup) {
|
||||||
|
group = mappedGroup;
|
||||||
|
}
|
||||||
|
|
||||||
const signature: SystemSignature = {
|
const signature: SystemSignature = {
|
||||||
eve_id: sigArrInfo[0],
|
eve_id: sigId,
|
||||||
kind: availableKeys.includes(kind) ? kind : SignatureKind.CosmicSignature,
|
kind,
|
||||||
group: sigArrInfo[2] as SignatureGroup,
|
group,
|
||||||
name: sigArrInfo[3],
|
name: sigArrInfo[3] || 'Unknown',
|
||||||
type: '',
|
type: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,26 @@ export enum SignatureKindRU {
|
|||||||
Starbase = 'Starbase',
|
Starbase = 'Starbase',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SignatureKindFR {
|
||||||
|
CosmicSignature = 'Signature cosmique (type)',
|
||||||
|
CosmicAnomaly = 'Anomalie cosmique',
|
||||||
|
Structure = 'Structure',
|
||||||
|
Ship = 'Vaisseau',
|
||||||
|
Deployable = 'Déployable',
|
||||||
|
Drone = 'Drone',
|
||||||
|
Starbase = 'Base stellaire',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SignatureKindDE {
|
||||||
|
CosmicSignature = 'Kosmische Signatur (typ)',
|
||||||
|
CosmicAnomaly = 'Kosmische Anomalie',
|
||||||
|
Structure = 'Struktur',
|
||||||
|
Ship = 'Schiff',
|
||||||
|
Deployable = 'Mobile Struktur',
|
||||||
|
Drone = 'Drohne',
|
||||||
|
Starbase = 'Sternenbasis',
|
||||||
|
}
|
||||||
|
|
||||||
export enum SignatureGroupENG {
|
export enum SignatureGroupENG {
|
||||||
CosmicSignature = 'Cosmic Signature',
|
CosmicSignature = 'Cosmic Signature',
|
||||||
Wormhole = 'Wormhole',
|
Wormhole = 'Wormhole',
|
||||||
@@ -97,3 +117,23 @@ export enum SignatureGroupRU {
|
|||||||
OreSite = 'Астероидный район',
|
OreSite = 'Астероидный район',
|
||||||
CombatSite = 'Боевой район',
|
CombatSite = 'Боевой район',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SignatureGroupFR {
|
||||||
|
CosmicSignature = 'Signature cosmique (groupe)',
|
||||||
|
Wormhole = 'Trou de ver',
|
||||||
|
GasSite = 'Site de gaz',
|
||||||
|
RelicSite = 'Site de reliques',
|
||||||
|
DataSite = 'Site de données',
|
||||||
|
OreSite = 'Site de minerai',
|
||||||
|
CombatSite = 'Site de combat',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SignatureGroupDE {
|
||||||
|
CosmicSignature = 'Kosmische Signatur (gruppe)',
|
||||||
|
Wormhole = 'Wurmloch',
|
||||||
|
GasSite = 'Gasgebiet',
|
||||||
|
RelicSite = 'Reliktgebiet',
|
||||||
|
DataSite = 'Datengebiet',
|
||||||
|
OreSite = 'Mineraliengebiet',
|
||||||
|
CombatSite = 'Kampfgebiet',
|
||||||
|
}
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ defmodule WandererApp.Api.MapSystemSignature do
|
|||||||
:kind,
|
:kind,
|
||||||
:group,
|
:group,
|
||||||
:custom_info,
|
:custom_info,
|
||||||
:updated,
|
:deleted,
|
||||||
:inserted_at,
|
:inserted_at,
|
||||||
:updated_at
|
:updated_at
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
|||||||
%MapSystemSignature{deleted: true} = deleted_sig ->
|
%MapSystemSignature{deleted: true} = deleted_sig ->
|
||||||
MapSystemSignature.update!(
|
MapSystemSignature.update!(
|
||||||
deleted_sig,
|
deleted_sig,
|
||||||
%{sig | deleted: false}
|
Map.take(sig, [:name, :description, :kind, :group, :type, :custom_info, :deleted])
|
||||||
)
|
)
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
@@ -152,7 +152,11 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
|||||||
|
|
||||||
defp apply_update_signature(%MapSystemSignature{} = existing, update_params)
|
defp apply_update_signature(%MapSystemSignature{} = existing, update_params)
|
||||||
when not is_nil(update_params) do
|
when not is_nil(update_params) do
|
||||||
MapSystemSignature.update(existing, update_params)
|
case MapSystemSignature.update(existing, update_params) do
|
||||||
|
{:ok, _} -> :ok
|
||||||
|
{:error, reason} ->
|
||||||
|
Logger.error("Failed to update signature #{existing.id}: #{inspect(reason)}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp track_activity(event, map_id, solar_system_id, user_id, character_id, signatures) do
|
defp track_activity(event, map_id, solar_system_id, user_id, character_id, signatures) do
|
||||||
|
|||||||
Reference in New Issue
Block a user