fix(Map): Fixed remove pings for removed systems

This commit is contained in:
Dmitry Popov
2025-07-18 13:39:36 +02:00
parent e457d94df8
commit 0f6847b16d
10 changed files with 41 additions and 38 deletions

View File

@@ -1,3 +1,3 @@
erlang 26.2.5.5 erlang 27.0
elixir 1.17.3-otp-26 elixir 1.17.2-otp-27
nodejs 18.0.0 nodejs 18.0.0

View File

@@ -1,9 +1,4 @@
import { Button } from 'primereact/button'; import { PingRoute } from '@/hooks/Mapper/components/mapInterface/components/PingsInterface/PingRoute.tsx';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Toast } from 'primereact/toast';
import clsx from 'clsx';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { Commands, OutCommand, PingType } from '@/hooks/Mapper/types';
import { import {
CharacterCardById, CharacterCardById,
SystemView, SystemView,
@@ -12,12 +7,17 @@ import {
WdImgButton, WdImgButton,
WdImgButtonTooltip, WdImgButtonTooltip,
} from '@/hooks/Mapper/components/ui-kit'; } from '@/hooks/Mapper/components/ui-kit';
import useRefState from 'react-usestateref';
import { PrimeIcons } from 'primereact/api';
import { emitMapEvent } from '@/hooks/Mapper/events'; import { emitMapEvent } from '@/hooks/Mapper/events';
import { ConfirmPopup } from 'primereact/confirmpopup'; import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { PingRoute } from '@/hooks/Mapper/components/mapInterface/components/PingsInterface/PingRoute.tsx';
import { PingsPlacement } from '@/hooks/Mapper/mapRootProvider/types.ts'; import { PingsPlacement } from '@/hooks/Mapper/mapRootProvider/types.ts';
import { Commands, OutCommand, PingType } from '@/hooks/Mapper/types';
import clsx from 'clsx';
import { PrimeIcons } from 'primereact/api';
import { Button } from 'primereact/button';
import { ConfirmPopup } from 'primereact/confirmpopup';
import { Toast } from 'primereact/toast';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import useRefState from 'react-usestateref';
const PING_PLACEMENT_MAP = { const PING_PLACEMENT_MAP = {
[PingsPlacement.rightTop]: 'top-right', [PingsPlacement.rightTop]: 'top-right',
@@ -119,7 +119,7 @@ export const PingsInterface = ({ hasLeftOffset }: PingsInterfaceProps) => {
await outCommand({ await outCommand({
type: OutCommand.cancelPing, type: OutCommand.cancelPing,
data: { type: ping.type, solar_system_id: ping.solar_system_id }, data: { type: ping.type, id: ping.id },
}); });
}, [outCommand, ping]); }, [outCommand, ping]);

View File

@@ -14,8 +14,8 @@ export const useCommandPings = () => {
ref.current.update({ pings }); ref.current.update({ pings });
}, []); }, []);
const pingCancelled = useCallback(({ type, solar_system_id }: CommandPingCancelled) => { const pingCancelled = useCallback(({ type, id }: CommandPingCancelled) => {
const newPings = ref.current.pings.filter(x => x.solar_system_id !== solar_system_id && x.type !== type); const newPings = ref.current.pings.filter(x => x.id !== id && x.type !== type);
ref.current.update({ pings: newPings }); ref.current.update({ pings: newPings });
}, []); }, []);

View File

@@ -151,7 +151,7 @@ export type CommandUpdateTracking = {
follow: boolean; follow: boolean;
}; };
export type CommandPingAdded = PingData[]; export type CommandPingAdded = PingData[];
export type CommandPingCancelled = Pick<PingData, 'type' | 'solar_system_id'>; export type CommandPingCancelled = Pick<PingData, 'type' | 'id'>;
export interface UserSettings { export interface UserSettings {
primaryCharacterId?: string; primaryCharacterId?: string;

View File

@@ -4,6 +4,7 @@ export enum PingType {
} }
export type PingData = { export type PingData = {
id: string;
inserted_at: number; inserted_at: number;
character_eve_id: string; character_eve_id: string;
solar_system_id: string; solar_system_id: string;

View File

@@ -14,6 +14,11 @@ defmodule WandererApp.Api.MapPing do
define(:new, action: :new) define(:new, action: :new)
define(:destroy, action: :destroy) define(:destroy, action: :destroy)
define(:by_id,
get_by: [:id],
action: :read
)
define(:by_map, define(:by_map,
action: :by_map action: :by_map
) )

View File

@@ -178,10 +178,11 @@ defmodule WandererApp.Map.Manager do
case WandererApp.MapPingsRepo.get_by_inserted_before(delete_after_date) do case WandererApp.MapPingsRepo.get_by_inserted_before(delete_after_date) do
{:ok, pings} -> {:ok, pings} ->
Enum.each(pings, fn %{map_id: map_id, type: type} = ping -> Enum.each(pings, fn %{id: ping_id, map_id: map_id, type: type} = ping ->
{:ok, %{system: system}} = ping |> Ash.load([:system]) {:ok, %{system: system}} = ping |> Ash.load([:system])
WandererApp.Map.Server.Impl.broadcast!(map_id, :ping_cancelled, %{ WandererApp.Map.Server.Impl.broadcast!(map_id, :ping_cancelled, %{
id: ping_id,
solar_system_id: system.solar_system_id, solar_system_id: system.solar_system_id,
type: type type: type
}) })

View File

@@ -52,7 +52,7 @@ defmodule WandererApp.Map.Server.PingsImpl do
def cancel_ping( def cancel_ping(
%{map_id: map_id} = state, %{map_id: map_id} = state,
%{ %{
solar_system_id: solar_system_id, id: ping_id,
character_id: character_id, character_id: character_id,
user_id: user_id, user_id: user_id,
type: type type: type
@@ -60,14 +60,13 @@ defmodule WandererApp.Map.Server.PingsImpl do
) do ) do
{:ok, character} = WandererApp.Character.get_character(character_id) {:ok, character} = WandererApp.Character.get_character(character_id)
system = {:ok, %{system: %{solar_system_id: solar_system_id}} = ping} =
WandererApp.Map.find_system_by_location(map_id, %{ WandererApp.MapPingsRepo.get_by_id(ping_id)
solar_system_id: solar_system_id |> String.to_integer()
})
:ok = WandererApp.MapPingsRepo.destroy(map_id, system.id) :ok = WandererApp.MapPingsRepo.destroy(ping)
Impl.broadcast!(map_id, :ping_cancelled, %{ Impl.broadcast!(map_id, :ping_cancelled, %{
id: ping_id,
solar_system_id: solar_system_id, solar_system_id: solar_system_id,
type: type type: type
}) })

View File

@@ -4,7 +4,7 @@ defmodule WandererApp.MapPingsRepo do
require Logger require Logger
def get_by_id(ping_id), def get_by_id(ping_id),
do: WandererApp.Api.MapPing.by_id(ping_id) do: WandererApp.Api.MapPing.by_id!(ping_id) |> Ash.load([:system])
def get_by_map(map_id), def get_by_map(map_id),
do: WandererApp.Api.MapPing.by_map!(%{map_id: map_id}) |> Ash.load([:character, :system]) do: WandererApp.Api.MapPing.by_map!(%{map_id: map_id}) |> Ash.load([:character, :system])
@@ -18,20 +18,12 @@ defmodule WandererApp.MapPingsRepo do
def create(ping), do: ping |> WandererApp.Api.MapPing.new() def create(ping), do: ping |> WandererApp.Api.MapPing.new()
def create!(ping), do: ping |> WandererApp.Api.MapPing.new!() def create!(ping), do: ping |> WandererApp.Api.MapPing.new!()
def destroy(map_id, system_id) when is_binary(map_id) and is_binary(system_id) do def destroy(ping) do
{:ok, pings} = ping
WandererApp.Api.MapPing.by_map_and_system(%{ |> WandererApp.Api.MapPing.destroy!()
map_id: map_id,
system_id: system_id
})
pings
|> Enum.each(fn ping ->
WandererApp.Api.MapPing.destroy!(ping)
end)
:ok :ok
end end
def destroy(_ping), do: :ok def destroy(_ping_id), do: :ok
end end

View File

@@ -18,6 +18,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
pings pings
|> Enum.reduce(socket, fn %{ |> Enum.reduce(socket, fn %{
id: id,
type: type, type: type,
message: message, message: message,
system: system, system: system,
@@ -28,6 +29,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
socket socket
|> MapEventHandler.push_map_event("ping_added", [ |> MapEventHandler.push_map_event("ping_added", [
map_ui_ping(%{ map_ui_ping(%{
id: id,
inserted_at: inserted_at, inserted_at: inserted_at,
character_eve_id: character.eve_id, character_eve_id: character.eve_id,
solar_system_id: "#{system.solar_system_id}", solar_system_id: "#{system.solar_system_id}",
@@ -49,6 +51,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
do: do:
socket socket
|> MapEventHandler.push_map_event("ping_cancelled", %{ |> MapEventHandler.push_map_event("ping_cancelled", %{
id: ping_info.id,
solar_system_id: ping_info.solar_system_id, solar_system_id: ping_info.solar_system_id,
type: ping_info.type type: ping_info.type
}) })
@@ -97,7 +100,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
def handle_ui_event( def handle_ui_event(
"cancel_ping", "cancel_ping",
%{"solar_system_id" => solar_system_id, "type" => type} = _event, %{"id" => id, "type" => type} = _event,
%{ %{
assigns: %{ assigns: %{
map_id: map_id, map_id: map_id,
@@ -112,7 +115,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
when not is_nil(main_character_id) do when not is_nil(main_character_id) do
map_id map_id
|> WandererApp.Map.Server.cancel_ping(%{ |> WandererApp.Map.Server.cancel_ping(%{
solar_system_id: solar_system_id, id: id,
type: type, type: type,
character_id: main_character_id, character_id: main_character_id,
user_id: current_user.id user_id: current_user.id
@@ -126,6 +129,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
def map_ui_ping( def map_ui_ping(
%{ %{
id: id,
inserted_at: inserted_at, inserted_at: inserted_at,
character_eve_id: character_eve_id, character_eve_id: character_eve_id,
solar_system_id: solar_system_id, solar_system_id: solar_system_id,
@@ -134,6 +138,7 @@ defmodule WandererAppWeb.MapPingsEventHandler do
} = _ping } = _ping
) do ) do
%{ %{
id: id,
inserted_at: inserted_at, inserted_at: inserted_at,
character_eve_id: character_eve_id, character_eve_id: character_eve_id,
solar_system_id: solar_system_id, solar_system_id: solar_system_id,