mirror of
https://github.com/wanderer-industries/wanderer
synced 2026-01-21 06:10:24 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89d7df0ba2 | ||
|
|
ba0c10d2e4 | ||
|
|
996c88d839 | ||
|
|
80e998cf79 | ||
|
|
d2bcb89fa1 | ||
|
|
922f296f17 | ||
|
|
71dc20c933 | ||
|
|
80f7d34d3d | ||
|
|
113fe1c695 | ||
|
|
5550844912 | ||
|
|
0228e68a1d | ||
|
|
3424667af1 | ||
|
|
6c7b28a6c1 | ||
|
|
3988079cd3 | ||
|
|
f5d407fee0 | ||
|
|
a857422c46 | ||
|
|
ec6717d0ef | ||
|
|
56dacdcbbd | ||
|
|
c8e17b1691 |
40
CHANGELOG.md
40
CHANGELOG.md
@@ -2,6 +2,46 @@
|
||||
|
||||
<!-- changelog -->
|
||||
|
||||
## [v1.92.0](https://github.com/wanderer-industries/wanderer/compare/v1.91.11...v1.92.0) (2026-01-14)
|
||||
|
||||
|
||||
|
||||
|
||||
### Features:
|
||||
|
||||
* Added ability to select a range of wh classes for k162.
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* core: Show c1/c2/c3 or c4/c5 or link signature modal
|
||||
|
||||
## [v1.91.11](https://github.com/wanderer-industries/wanderer/compare/v1.91.10...v1.91.11) (2026-01-13)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* allow sig api when map relay is off
|
||||
|
||||
## [v1.91.10](https://github.com/wanderer-industries/wanderer/compare/v1.91.9...v1.91.10) (2026-01-07)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* remove actor context requirement from sig api
|
||||
|
||||
## [v1.91.9](https://github.com/wanderer-industries/wanderer/compare/v1.91.8...v1.91.9) (2026-01-06)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* core: fixed rally point cancel logic
|
||||
|
||||
## [v1.91.8](https://github.com/wanderer-industries/wanderer/compare/v1.91.7...v1.91.8) (2026-01-06)
|
||||
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ export const PingsInterface = ({ hasLeftOffset }: PingsInterfaceProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!ping) {
|
||||
setIsShow(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,27 +162,26 @@ export const PingsInterface = ({ hasLeftOffset }: PingsInterfaceProps) => {
|
||||
};
|
||||
}, [interfaceSettings]);
|
||||
|
||||
if (!ping) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isShowSelectedSystem = selectedSystem != null && selectedSystem !== ping.solar_system_id;
|
||||
const isShowSelectedSystem = ping && selectedSystem != null && selectedSystem !== ping.solar_system_id;
|
||||
|
||||
// Only render Toast when there's a ping
|
||||
return (
|
||||
<>
|
||||
<Toast
|
||||
position={placement as never}
|
||||
className={clsx('!max-w-[initial] w-[500px]', hasLeftOffset ? offsets.withLeftMenu : offsets.default)}
|
||||
ref={toast}
|
||||
content={({ message }) => (
|
||||
<section
|
||||
className={clsx(
|
||||
'flex flex-col p-3 w-full border border-stone-800 shadow-md animate-fadeInDown rounded-[5px]',
|
||||
'bg-gradient-to-tr from-transparent to-sky-700/60 bg-stone-900/70',
|
||||
)}
|
||||
>
|
||||
<div className="flex gap-3">
|
||||
<i className={clsx('pi text-yellow-500 text-2xl', 'relative top-[2px]', ICONS[ping.type])}></i>
|
||||
{ping && (
|
||||
<Toast
|
||||
key={ping.id}
|
||||
position={placement as never}
|
||||
className={clsx('!max-w-[initial] w-[500px]', hasLeftOffset ? offsets.withLeftMenu : offsets.default)}
|
||||
ref={toast}
|
||||
content={({ message }) => (
|
||||
<section
|
||||
className={clsx(
|
||||
'flex flex-col p-3 w-full border border-stone-800 shadow-md animate-fadeInDown rounded-[5px]',
|
||||
'bg-gradient-to-tr from-transparent to-sky-700/60 bg-stone-900/70',
|
||||
)}
|
||||
>
|
||||
<div className="flex gap-3">
|
||||
<i className={clsx('pi text-yellow-500 text-2xl', 'relative top-[2px]', ICONS[ping.type])}></i>
|
||||
<div className="flex flex-col gap-1 w-full">
|
||||
<div className="flex justify-between">
|
||||
<div>
|
||||
@@ -253,28 +253,33 @@ export const PingsInterface = ({ hasLeftOffset }: PingsInterfaceProps) => {
|
||||
{/*/>*/}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
></Toast>
|
||||
)}
|
||||
></Toast>
|
||||
)}
|
||||
|
||||
<WdButton
|
||||
icon="pi pi-bell"
|
||||
severity="warning"
|
||||
aria-label="Notification"
|
||||
size="small"
|
||||
className="w-[33px] h-[33px]"
|
||||
outlined
|
||||
onClick={handleClickShow}
|
||||
disabled={isShow}
|
||||
/>
|
||||
{ping && (
|
||||
<>
|
||||
<WdButton
|
||||
icon="pi pi-bell"
|
||||
severity="warning"
|
||||
aria-label="Notification"
|
||||
size="small"
|
||||
className="w-[33px] h-[33px]"
|
||||
outlined
|
||||
onClick={handleClickShow}
|
||||
disabled={isShow}
|
||||
/>
|
||||
|
||||
<ConfirmPopup
|
||||
target={cfRef.current}
|
||||
visible={cfVisible}
|
||||
onHide={cfHide}
|
||||
message="Are you sure you want to delete ping?"
|
||||
icon="pi pi-exclamation-triangle text-orange-400"
|
||||
accept={removePing}
|
||||
/>
|
||||
<ConfirmPopup
|
||||
target={cfRef.current}
|
||||
visible={cfVisible}
|
||||
onHide={cfHide}
|
||||
message="Are you sure you want to delete ping?"
|
||||
icon="pi pi-exclamation-triangle text-orange-400"
|
||||
accept={removePing}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,9 +3,9 @@ import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
import { useSystemInfo } from '@/hooks/Mapper/components/hooks';
|
||||
import {
|
||||
SOLAR_SYSTEM_CLASS_IDS,
|
||||
SOLAR_SYSTEM_CLASSES_TO_CLASS_GROUPS,
|
||||
WORMHOLES_ADDITIONAL_INFO_BY_SHORT_NAME,
|
||||
SOLAR_SYSTEM_CLASS_IDS,
|
||||
SOLAR_SYSTEM_CLASSES_TO_CLASS_GROUPS,
|
||||
WORMHOLES_ADDITIONAL_INFO_BY_SHORT_NAME,
|
||||
} from '@/hooks/Mapper/components/map/constants.ts';
|
||||
import { SystemSignaturesContent } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/SystemSignaturesContent';
|
||||
import { K162_TYPES_MAP } from '@/hooks/Mapper/constants.ts';
|
||||
@@ -91,7 +91,7 @@ export const SystemLinkSignatureDialog = ({ data, setVisible }: SystemLinkSignat
|
||||
|
||||
if (k162TypeInfo) {
|
||||
// Check if the k162Type matches our target system class
|
||||
return customInfo.k162Type === targetSystemClassGroup;
|
||||
return k162TypeInfo.value.includes(targetSystemClassGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,26 @@ export const renderK162Type = (option: K162Type) => {
|
||||
return renderNoValue();
|
||||
}
|
||||
|
||||
if (['c1_c2_c3', 'c4_c5'].includes(value)) {
|
||||
const arr = whClassName.split('_');
|
||||
|
||||
return (
|
||||
<div className="flex gap-1 items-center">
|
||||
{arr.map(x => (
|
||||
<WHClassView
|
||||
key={x}
|
||||
classNameWh="!text-[11px] !font-bold"
|
||||
hideWhClassName
|
||||
hideTooltip
|
||||
whClassName={x}
|
||||
noOffset
|
||||
useShortTitle
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<WHClassView
|
||||
classNameWh="!text-[11px] !font-bold"
|
||||
|
||||
@@ -88,6 +88,16 @@ export const K162_TYPES: K162Type[] = [
|
||||
value: 'ns',
|
||||
whClassName: 'C248',
|
||||
},
|
||||
{
|
||||
label: 'C1/C2/C3',
|
||||
value: 'c1_c2_c3',
|
||||
whClassName: 'E004_D382_L477',
|
||||
},
|
||||
{
|
||||
label: 'C4/C5',
|
||||
value: 'c4_c5',
|
||||
whClassName: 'M001_L614',
|
||||
},
|
||||
{
|
||||
label: 'C1',
|
||||
value: 'c1',
|
||||
|
||||
@@ -63,7 +63,6 @@ export const useComments = ({ outCommand }: UseCommentsProps): UseCommentsData =
|
||||
|
||||
const removeComment = useCallback((systemId: number, commentId: string) => {
|
||||
const cSystem = commentBySystemsRef.current.get(systemId);
|
||||
console.log('cSystem', cSystem);
|
||||
if (!cSystem) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ defmodule WandererApp.Map.Manager do
|
||||
@maps_queue :maps_queue
|
||||
@check_maps_queue_interval :timer.seconds(1)
|
||||
|
||||
@pings_cleanup_interval :timer.minutes(1)
|
||||
@pings_cleanup_interval :timer.minutes(5)
|
||||
@pings_expire_minutes 60
|
||||
|
||||
# Test-aware async task runner
|
||||
|
||||
@@ -78,7 +78,8 @@ defmodule WandererApp.Map.Operations.Signatures do
|
||||
)
|
||||
when is_integer(solar_system_id) do
|
||||
with {:ok, validated_char_uuid} <- validate_character_eve_id(params, char_id),
|
||||
{:ok, system} <- MapSystem.by_map_id_and_solar_system_id(map_id, solar_system_id) do
|
||||
{:ok, system} <-
|
||||
MapSystem.read_by_map_and_solar_system(%{map_id: map_id, solar_system_id: solar_system_id}) do
|
||||
attrs =
|
||||
params
|
||||
|> Map.put("system_id", system.id)
|
||||
|
||||
@@ -72,14 +72,15 @@ defmodule WandererApp.Map.Server.PingsImpl do
|
||||
type: type
|
||||
} = _ping_info
|
||||
) do
|
||||
Logger.debug("cancel_ping called: map_id=#{map_id}, ping_id=#{ping_id}, type=#{type}")
|
||||
|
||||
case WandererApp.MapPingsRepo.get_by_id(ping_id) do
|
||||
result = WandererApp.MapPingsRepo.get_by_id(ping_id)
|
||||
|
||||
case result do
|
||||
{:ok,
|
||||
%{system: %{id: system_id, name: system_name, solar_system_id: solar_system_id}} = ping} ->
|
||||
with {:ok, character} <- WandererApp.Character.get_character(character_id),
|
||||
:ok <- WandererApp.MapPingsRepo.destroy(ping) do
|
||||
Logger.debug("Ping #{ping_id} destroyed successfully")
|
||||
Logger.debug("Ping #{ping_id} destroyed successfully, broadcasting :ping_cancelled")
|
||||
|
||||
Impl.broadcast!(map_id, :ping_cancelled, %{
|
||||
id: ping_id,
|
||||
@@ -87,6 +88,8 @@ defmodule WandererApp.Map.Server.PingsImpl do
|
||||
type: type
|
||||
})
|
||||
|
||||
Logger.debug("Broadcast :ping_cancelled sent for ping #{ping_id}")
|
||||
|
||||
# Broadcast rally point removal events to external clients (webhooks/SSE)
|
||||
if type == 1 do
|
||||
WandererApp.ExternalEvents.broadcast(map_id, :rally_point_removed, %{
|
||||
@@ -113,8 +116,6 @@ defmodule WandererApp.Map.Server.PingsImpl do
|
||||
|
||||
# Handle case where ping exists but system was deleted (nil)
|
||||
{:ok, %{system: nil} = ping} ->
|
||||
Logger.warning("Ping #{ping_id} has no associated system, destroying orphaned ping")
|
||||
|
||||
case WandererApp.MapPingsRepo.destroy(ping) do
|
||||
:ok ->
|
||||
Impl.broadcast!(map_id, :ping_cancelled, %{
|
||||
@@ -129,19 +130,22 @@ defmodule WandererApp.Map.Server.PingsImpl do
|
||||
|
||||
{:error, %Ash.Error.Query.NotFound{}} ->
|
||||
# Ping already deleted (possibly by cascade deletion from map/system/character removal,
|
||||
# auto-expiry, or concurrent cancellation). This is not an error - the desired state
|
||||
# (ping is gone) is already achieved. Just broadcast the cancellation event.
|
||||
Logger.debug(
|
||||
"Ping #{ping_id} not found during cancellation - already deleted, skipping broadcast"
|
||||
)
|
||||
# auto-expiry, or concurrent cancellation). Broadcast cancellation so frontend updates.
|
||||
Impl.broadcast!(map_id, :ping_cancelled, %{
|
||||
id: ping_id,
|
||||
solar_system_id: nil,
|
||||
type: type
|
||||
})
|
||||
|
||||
:ok
|
||||
|
||||
{:error, %Ash.Error.Invalid{errors: [%Ash.Error.Query.NotFound{} | _]}} ->
|
||||
# Same as above, but Ash wraps NotFound inside Invalid in some cases
|
||||
Logger.debug(
|
||||
"Ping #{ping_id} not found during cancellation - already deleted, skipping broadcast"
|
||||
)
|
||||
Impl.broadcast!(map_id, :ping_cancelled, %{
|
||||
id: ping_id,
|
||||
solar_system_id: nil,
|
||||
type: type
|
||||
})
|
||||
|
||||
:ok
|
||||
|
||||
|
||||
@@ -167,6 +167,9 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
||||
updated_count: length(updated_ids),
|
||||
removed_count: length(removed_ids)
|
||||
})
|
||||
|
||||
# Always return :ok - external event failures should not affect the main operation
|
||||
:ok
|
||||
end
|
||||
|
||||
defp remove_signature(map_id, sig, system, delete_conn?) do
|
||||
|
||||
@@ -51,14 +51,18 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
map_ui_ping(ping_info)
|
||||
])
|
||||
|
||||
def handle_server_event(%{event: :ping_cancelled, payload: ping_info}, socket),
|
||||
do:
|
||||
socket
|
||||
|> MapEventHandler.push_map_event("ping_cancelled", %{
|
||||
id: ping_info.id,
|
||||
solar_system_id: ping_info.solar_system_id,
|
||||
type: ping_info.type
|
||||
})
|
||||
def handle_server_event(%{event: :ping_cancelled, payload: ping_info}, socket) do
|
||||
Logger.debug(
|
||||
"handle_server_event :ping_cancelled - id: #{ping_info.id}, is_version_valid?: #{inspect(socket.assigns[:is_version_valid?])}"
|
||||
)
|
||||
|
||||
socket
|
||||
|> MapEventHandler.push_map_event("ping_cancelled", %{
|
||||
id: ping_info.id,
|
||||
solar_system_id: ping_info.solar_system_id,
|
||||
type: ping_info.type
|
||||
})
|
||||
end
|
||||
|
||||
def handle_server_event(event, socket),
|
||||
do: MapCoreEventHandler.handle_server_event(event, socket)
|
||||
@@ -153,8 +157,6 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
socket
|
||||
)
|
||||
when not is_nil(main_character_id) do
|
||||
Logger.debug("handle_ui_event cancel_ping: id=#{id}, type=#{type}, map_id=#{map_id}")
|
||||
|
||||
map_id
|
||||
|> WandererApp.Map.Server.cancel_ping(%{
|
||||
id: id,
|
||||
@@ -172,8 +174,6 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
_event,
|
||||
%{assigns: %{main_character_id: nil}} = socket
|
||||
) do
|
||||
Logger.warning("add_ping blocked: main_character_id is nil")
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> MapEventHandler.push_map_event("ping_blocked", %{
|
||||
@@ -188,8 +188,6 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
_event,
|
||||
%{assigns: %{has_tracked_characters?: false}} = socket
|
||||
) do
|
||||
Logger.warning("add_ping blocked: no tracked characters")
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> MapEventHandler.push_map_event("ping_blocked", %{
|
||||
@@ -204,8 +202,6 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
_event,
|
||||
%{assigns: %{is_subscription_active?: false}} = socket
|
||||
) do
|
||||
Logger.warning("add_ping blocked: subscription not active")
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> MapEventHandler.push_map_event("ping_blocked", %{
|
||||
@@ -220,8 +216,6 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
_event,
|
||||
%{assigns: %{user_permissions: %{update_system: false}}} = socket
|
||||
) do
|
||||
Logger.warning("add_ping blocked: no update_system permission")
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> MapEventHandler.push_map_event("ping_blocked", %{
|
||||
@@ -236,7 +230,15 @@ defmodule WandererAppWeb.MapPingsEventHandler do
|
||||
_event,
|
||||
%{assigns: %{main_character_id: nil}} = socket
|
||||
) do
|
||||
Logger.warning("cancel_ping blocked: main_character_id is nil")
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
# Catch-all for cancel_ping to debug why it doesn't match
|
||||
def handle_ui_event(
|
||||
"cancel_ping",
|
||||
event,
|
||||
%{assigns: assigns} = socket
|
||||
) do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user