Compare commits

..

13 Commits

Author SHA1 Message Date
CI
0b7c067de7 chore: release version v1.77.4 2025-09-02 10:26:47 +00:00
Dmitry Popov
0d0db8c129 Merge pull request #509 from guarzo/guarzo/aclapi
fix: ensure pub/sub occurs after acl api change
2025-09-02 14:26:20 +04:00
guarzo
378df0ac70 fix: pr feedback 2025-09-02 00:27:40 +00:00
guarzo
0e4a132f69 refactor: dry 2025-09-01 22:38:12 +00:00
guarzo
631746375d fix: ensure pub/sub occurs after acl api change 2025-09-01 22:11:58 +00:00
CI
7dc01dad54 chore: [skip ci] 2025-08-29 00:33:30 +00:00
CI
8a9807d3e5 chore: release version v1.77.3 2025-08-29 00:33:30 +00:00
Dmitry Popov
39df3c97ce Merge pull request #505 from wanderer-industries/tracking-fix
Tracking fix
2025-08-29 04:33:00 +04:00
Dmitry Popov
46c1ccdfcc fix: Fixed character tracking settings 2025-08-29 02:31:00 +02:00
Dmitry Popov
8817536038 fix: Fixed character tracking settings 2025-08-29 02:30:19 +02:00
Dmitry Popov
c3bb23a6ee fix: Fixed character tracking settings 2025-08-29 01:41:08 +02:00
Dmitry Popov
7e9c4c575e fix: Fixed character tracking settings 2025-08-28 22:18:18 +02:00
CI
5a70eee91e chore: [skip ci] 2025-08-28 10:24:51 +00:00
19 changed files with 245 additions and 208 deletions

View File

@@ -2,6 +2,32 @@
<!-- changelog -->
## [v1.77.4](https://github.com/wanderer-industries/wanderer/compare/v1.77.3...v1.77.4) (2025-09-02)
### Bug Fixes:
* pr feedback
* ensure pub/sub occurs after acl api change
## [v1.77.3](https://github.com/wanderer-industries/wanderer/compare/v1.77.2...v1.77.3) (2025-08-29)
### Bug Fixes:
* Fixed character tracking settings
* Fixed character tracking settings
* Fixed character tracking settings
* Fixed character tracking settings
## [v1.77.2](https://github.com/wanderer-industries/wanderer/compare/v1.77.1...v1.77.2) (2025-08-28)

View File

@@ -79,8 +79,7 @@ defmodule WandererApp.Api.MapCharacterSettings do
accept [
:map_id,
:character_id,
:tracked,
:followed
:tracked
]
argument :map_id, :uuid, allow_nil?: false

View File

@@ -129,21 +129,23 @@ defmodule WandererApp.CachedInfo do
def get_solar_system_jump(from_solar_system_id, to_solar_system_id) do
# Create normalized cache key (smaller ID first for bidirectional lookup)
{id1, id2} = if from_solar_system_id < to_solar_system_id do
{from_solar_system_id, to_solar_system_id}
else
{to_solar_system_id, from_solar_system_id}
end
{id1, id2} =
if from_solar_system_id < to_solar_system_id do
{from_solar_system_id, to_solar_system_id}
else
{to_solar_system_id, from_solar_system_id}
end
cache_key = "jump_#{id1}_#{id2}"
case WandererApp.Cache.lookup(cache_key) do
{:ok, nil} ->
# Build jump index if not exists
build_jump_index()
WandererApp.Cache.lookup(cache_key)
result -> result
result ->
result
end
end
@@ -152,17 +154,19 @@ defmodule WandererApp.CachedInfo do
{:ok, jumps} ->
jumps
|> Enum.each(fn jump ->
{id1, id2} = if jump.from_solar_system_id < jump.to_solar_system_id do
{jump.from_solar_system_id, jump.to_solar_system_id}
else
{jump.to_solar_system_id, jump.from_solar_system_id}
end
{id1, id2} =
if jump.from_solar_system_id < jump.to_solar_system_id do
{jump.from_solar_system_id, jump.to_solar_system_id}
else
{jump.to_solar_system_id, jump.from_solar_system_id}
end
cache_key = "jump_#{id1}_#{id2}"
WandererApp.Cache.put(cache_key, jump)
end)
_ -> :error
_ ->
:error
end
end

View File

@@ -20,7 +20,7 @@ defmodule WandererApp.Character.TrackingUtils do
)
when not is_nil(caller_pid) do
with {:ok, character} <-
WandererApp.Character.get_by_eve_id(character_eve_id),
WandererApp.Character.get_by_eve_id("#{character_eve_id}"),
{:ok, %{tracked: is_tracked}} <-
do_update_character_tracking(character, map_id, track, caller_pid) do
# Determine which event to send based on tracking mode and previous state
@@ -55,15 +55,19 @@ defmodule WandererApp.Character.TrackingUtils do
Builds tracking data for all characters with access to a map.
"""
def build_tracking_data(map_id, current_user_id) do
with {:ok, map} <- WandererApp.MapRepo.get(map_id, [:acls]),
{:ok, character_settings} <-
WandererApp.Character.Activity.get_map_character_settings(map_id),
with {:ok, map} <-
WandererApp.MapRepo.get(map_id,
acls: [
:owner_id,
members: [:role, :eve_character_id, :eve_corporation_id, :eve_alliance_id]
]
),
{:ok, user_settings} <- WandererApp.MapUserSettingsRepo.get(map_id, current_user_id),
{:ok, %{characters: characters_with_access}} <-
WandererApp.Maps.load_characters(map, character_settings, current_user_id) do
WandererApp.Maps.load_characters(map, current_user_id) do
# Map characters to tracking data
{:ok, characters_data} =
build_character_tracking_data(characters_with_access, character_settings)
build_character_tracking_data(characters_with_access)
{:ok, main_character} =
get_main_character(user_settings, characters_with_access, characters_with_access)
@@ -98,21 +102,19 @@ defmodule WandererApp.Character.TrackingUtils do
end
# Helper to build tracking data for each character
defp build_character_tracking_data(characters, character_settings) do
defp build_character_tracking_data(characters) do
{:ok,
Enum.map(characters, fn char ->
setting = Enum.find(character_settings, &(&1.character_id == char.id))
%{
character: char |> WandererAppWeb.MapEventHandler.map_ui_character_stat(),
tracked: (setting && setting.tracked) || false
tracked: char.tracked
}
end)}
end
# Private implementation of update character tracking
defp do_update_character_tracking(character, map_id, track, caller_pid) do
WandererApp.MapCharacterSettingsRepo.get_by_map(map_id, character.id)
WandererApp.MapCharacterSettingsRepo.get(map_id, character.id)
|> case do
# Untracking flow
{:ok, %{tracked: true} = existing_settings} ->

View File

@@ -88,11 +88,18 @@ defmodule WandererApp.Map.Server do
|> map_pid!
|> GenServer.cast({&Impl.remove_character/2, [character_id]})
def untrack_characters(map_id, character_ids) when is_binary(map_id),
do:
map_id
|> map_pid!
|> GenServer.cast({&Impl.untrack_characters/2, [character_ids]})
def untrack_characters(map_id, character_ids) when is_binary(map_id) do
map_id
|> map_pid()
|> case do
pid when is_pid(pid) ->
GenServer.cast(pid, {&Impl.untrack_characters/2, [character_ids]})
_ ->
WandererApp.Cache.insert("map_#{map_id}:started", false)
:ok
end
end
def add_system(map_id, system_info, user_id, character_id) when is_binary(map_id),
do:

View File

@@ -59,6 +59,7 @@ defmodule WandererApp.Map.Server.AclsImpl do
map_update = %{acls: map.acls, scope: map.scope}
WandererApp.Map.update_map(map_id, map_update)
WandererApp.Cache.delete("map_characters-#{map_id}")
broadcast_acl_updates({:ok, result}, map_id)
@@ -66,7 +67,7 @@ defmodule WandererApp.Map.Server.AclsImpl do
end
def handle_acl_updated(map_id, acl_id) do
{:ok, map} =
{:ok, %{acls: acls}} =
WandererApp.MapRepo.get(map_id,
acls: [
:owner_id,
@@ -74,8 +75,9 @@ defmodule WandererApp.Map.Server.AclsImpl do
]
)
if map.acls |> Enum.map(& &1.id) |> Enum.member?(acl_id) do
WandererApp.Map.update_map(map_id, %{acls: map.acls})
if acls |> Enum.map(& &1.id) |> Enum.member?(acl_id) do
WandererApp.Map.update_map(map_id, %{acls: acls})
WandererApp.Cache.delete("map_characters-#{map_id}")
:ok =
acl_id
@@ -85,7 +87,7 @@ defmodule WandererApp.Map.Server.AclsImpl do
end
def handle_acl_deleted(map_id, _acl_id) do
{:ok, map} =
{:ok, %{acls: acls}} =
WandererApp.MapRepo.get(map_id,
acls: [
:owner_id,
@@ -93,7 +95,8 @@ defmodule WandererApp.Map.Server.AclsImpl do
]
)
WandererApp.Map.update_map(map_id, %{acls: map.acls})
WandererApp.Map.update_map(map_id, %{acls: acls})
WandererApp.Cache.delete("map_characters-#{map_id}")
character_ids =
map_id

View File

@@ -78,15 +78,12 @@ defmodule WandererApp.Map.Server.CharactersImpl do
characters_to_remove = old_map_tracked_characters -- map_active_tracked_characters
{:ok, invalidate_character_ids} =
WandererApp.Cache.lookup(
"map_#{map_id}:invalidate_character_ids",
[]
)
WandererApp.Cache.insert(
WandererApp.Cache.insert_or_update(
"map_#{map_id}:invalidate_character_ids",
(invalidate_character_ids ++ characters_to_remove) |> Enum.uniq()
characters_to_remove,
fn ids ->
(ids ++ characters_to_remove) |> Enum.uniq()
end
)
WandererApp.Cache.insert("maps:#{map_id}:tracked_characters", map_active_tracked_characters)
@@ -126,15 +123,18 @@ defmodule WandererApp.Map.Server.CharactersImpl do
def cleanup_characters(map_id, owner_id) do
{:ok, invalidate_character_ids} =
WandererApp.Cache.lookup(
WandererApp.Cache.get_and_remove(
"map_#{map_id}:invalidate_character_ids",
[]
)
acls =
map_id
|> WandererApp.Map.get_map!()
|> Map.get(:acls, [])
{:ok, %{acls: acls}} =
WandererApp.MapRepo.get(map_id,
acls: [
:owner_id,
members: [:role, :eve_character_id, :eve_corporation_id, :eve_alliance_id]
]
)
invalidate_character_ids
|> Task.async_stream(
@@ -186,11 +186,6 @@ defmodule WandererApp.Map.Server.CharactersImpl do
{:error, reason} ->
Logger.error("Error in cleanup_characters: #{inspect(reason)}")
end)
WandererApp.Cache.insert(
"map_#{map_id}:invalidate_character_ids",
[]
)
end
defp remove_and_untrack_characters(map_id, character_ids) do

View File

@@ -25,7 +25,7 @@ defmodule WandererApp.Map.Server.Impl do
]
@systems_cleanup_timeout :timer.minutes(30)
@characters_cleanup_timeout :timer.minutes(1)
@characters_cleanup_timeout :timer.minutes(5)
@connections_cleanup_timeout :timer.minutes(2)
@pubsub_client Application.compile_env(:wanderer_app, :pubsub_client)
@@ -100,7 +100,7 @@ defmodule WandererApp.Map.Server.Impl do
Process.send_after(self(), :update_presence, @update_presence_timeout)
Process.send_after(self(), :cleanup_connections, 5_000)
Process.send_after(self(), :cleanup_systems, 10_000)
Process.send_after(self(), :cleanup_characters, :timer.minutes(5))
Process.send_after(self(), :cleanup_characters, @characters_cleanup_timeout)
Process.send_after(self(), :backup_state, @backup_state_timeout)
WandererApp.Cache.insert("map_#{map_id}:started", true)
@@ -127,6 +127,7 @@ defmodule WandererApp.Map.Server.Impl do
Logger.debug(fn -> "Stopping map server for #{map_id}" end)
WandererApp.Cache.delete("map_#{map_id}:started")
WandererApp.Cache.delete("map_characters-#{map_id}")
:telemetry.execute([:wanderer_app, :map, :stopped], %{count: 1})
@@ -278,7 +279,7 @@ defmodule WandererApp.Map.Server.Impl do
end
def handle_event({:acl_deleted, %{acl_id: acl_id}}, %{map_id: map_id} = state) do
AclsImpl.handle_acl_updated(map_id, acl_id)
AclsImpl.handle_acl_deleted(map_id, acl_id)
state
end

View File

@@ -94,13 +94,22 @@ defmodule WandererApp.Maps do
end
end
def load_characters(map, character_settings, user_id) do
def load_characters(map, user_id) do
{:ok, user_characters} =
WandererApp.Api.Character.active_by_user(%{user_id: user_id})
characters =
map_available_characters =
map
|> get_map_available_characters(user_characters)
{:ok, character_settings} =
WandererApp.MapCharacterSettingsRepo.get_by_map_filtered(
map.id,
map_available_characters |> Enum.map(& &1.id)
)
characters =
map_available_characters
|> Enum.map(fn c ->
map_character(c, character_settings |> Enum.find(&(&1.character_id == c.id)))
end)
@@ -176,48 +185,57 @@ defmodule WandererApp.Maps do
tracked: tracked
}
@decorate cacheable(
cache: WandererApp.Cache,
key: "map_characters-#{map_id}",
opts: [ttl: :timer.seconds(2)]
)
defp _get_map_characters(%{id: map_id} = map) do
map_acls =
map.acls
|> Enum.map(fn acl -> acl |> Ash.load!(:members) end)
defp get_map_characters(%{id: map_id} = map) do
WandererApp.Cache.lookup!("map_characters-#{map_id}")
|> case do
nil ->
map_acls =
map.acls
|> Enum.map(fn acl -> acl |> Ash.load!(:members) end)
map_acl_owner_ids =
map_acls
|> Enum.map(fn acl -> acl.owner_id end)
map_acl_owner_ids =
map_acls
|> Enum.map(fn acl -> acl.owner_id end)
map_members =
map_acls
|> Enum.map(fn acl -> acl.members end)
|> List.flatten()
|> Enum.filter(fn member -> member.role != :blocked end)
map_members =
map_acls
|> Enum.map(fn acl -> acl.members end)
|> List.flatten()
|> Enum.filter(fn member -> member.role != :blocked end)
map_member_eve_ids =
map_members
|> Enum.filter(fn member -> not is_nil(member.eve_character_id) end)
|> Enum.map(fn member -> member.eve_character_id end)
map_member_eve_ids =
map_members
|> Enum.filter(fn member -> not is_nil(member.eve_character_id) end)
|> Enum.map(fn member -> member.eve_character_id end)
map_member_corporation_ids =
map_members
|> Enum.filter(fn member -> not is_nil(member.eve_corporation_id) end)
|> Enum.map(fn member -> member.eve_corporation_id end)
map_member_corporation_ids =
map_members
|> Enum.filter(fn member -> not is_nil(member.eve_corporation_id) end)
|> Enum.map(fn member -> member.eve_corporation_id end)
map_member_alliance_ids =
map_members
|> Enum.filter(fn member -> not is_nil(member.eve_alliance_id) end)
|> Enum.map(fn member -> member.eve_alliance_id end)
map_member_alliance_ids =
map_members
|> Enum.filter(fn member -> not is_nil(member.eve_alliance_id) end)
|> Enum.map(fn member -> member.eve_alliance_id end)
{:ok,
%{
map_acl_owner_ids: map_acl_owner_ids,
map_member_eve_ids: map_member_eve_ids,
map_member_corporation_ids: map_member_corporation_ids,
map_member_alliance_ids: map_member_alliance_ids
}}
map_characters =
%{
map_acl_owner_ids: map_acl_owner_ids,
map_member_eve_ids: map_member_eve_ids,
map_member_corporation_ids: map_member_corporation_ids,
map_member_alliance_ids: map_member_alliance_ids
}
WandererApp.Cache.insert(
"map_characters-#{map_id}",
map_characters
)
{:ok, map_characters}
map_characters ->
{:ok, map_characters}
end
end
defp get_map_available_characters(map, user_characters) do
@@ -227,7 +245,7 @@ defmodule WandererApp.Maps do
map_member_eve_ids: map_member_eve_ids,
map_member_corporation_ids: map_member_corporation_ids,
map_member_alliance_ids: map_member_alliance_ids
}} = _get_map_characters(map)
}} = get_map_characters(map)
user_characters
|> Enum.filter(fn c ->

View File

@@ -53,20 +53,8 @@ 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
{:ok, _} = get(settings.map_id, settings.character_id)
# Only update the tracked field, preserving other fields
WandererApp.Api.MapCharacterSettings.track(%{
map_id: settings.map_id,
@@ -75,6 +63,7 @@ defmodule WandererApp.MapCharacterSettingsRepo do
end
def untrack(settings) do
{:ok, _} = get(settings.map_id, settings.character_id)
# Only update the tracked field, preserving other fields
WandererApp.Api.MapCharacterSettings.untrack(%{
map_id: settings.map_id,
@@ -83,22 +72,16 @@ defmodule WandererApp.MapCharacterSettingsRepo do
end
def track!(settings) do
case WandererApp.Api.MapCharacterSettings.track(%{
map_id: settings.map_id,
character_id: settings.character_id
}) do
case track(settings) do
{:ok, result} -> result
{:error, error} -> raise "Failed to track: #{inspect(error)}"
error -> raise "Failed to track: #{inspect(error)}"
end
end
def untrack!(settings) do
case WandererApp.Api.MapCharacterSettings.untrack(%{
map_id: settings.map_id,
character_id: settings.character_id
}) do
case untrack(settings) do
{:ok, result} -> result
{:error, error} -> raise "Failed to untrack: #{inspect(error)}"
error -> raise "Failed to untrack: #{inspect(error)}"
end
end
@@ -117,22 +100,16 @@ defmodule WandererApp.MapCharacterSettingsRepo do
end
def follow!(settings) do
case WandererApp.Api.MapCharacterSettings.follow(%{
map_id: settings.map_id,
character_id: settings.character_id
}) do
case follow(settings) do
{:ok, result} -> result
{:error, error} -> raise "Failed to follow: #{inspect(error)}"
error -> raise "Failed to follow: #{inspect(error)}"
end
end
def unfollow!(settings) do
case WandererApp.Api.MapCharacterSettings.unfollow(%{
map_id: settings.map_id,
character_id: settings.character_id
}) do
case unfollow(settings) do
{:ok, result} -> result
{:error, error} -> raise "Failed to unfollow: #{inspect(error)}"
error -> raise "Failed to unfollow: #{inspect(error)}"
end
end

View File

@@ -596,10 +596,24 @@ defmodule WandererAppWeb.MapAccessListAPIController do
acl -> acl.id
end)
updated_acls = current_acl_ids ++ [new_acl_id]
updated_acls =
if new_acl_id in current_acl_ids do
current_acl_ids
else
current_acl_ids ++ [new_acl_id]
end
case WandererApp.Api.Map.update_acls(loaded_map, %{acls: updated_acls}) do
{:ok, updated_map} ->
# Only broadcast if we actually added a new ACL
unless new_acl_id in current_acl_ids do
Phoenix.PubSub.broadcast(
WandererApp.PubSub,
"maps:#{loaded_map.id}",
{:map_acl_updated, [new_acl_id], []}
)
end
{:ok, updated_map}
{:error, error} ->

View File

@@ -192,6 +192,8 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
:acl_member_added
) do
:ok ->
broadcast_acl_updated(acl_id)
json(conn, %{data: member_to_json(new_member)})
{:error, broadcast_error} ->
@@ -199,6 +201,9 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
"Failed to broadcast ACL member added event: #{inspect(broadcast_error)}"
)
# Still broadcast internal message even if external broadcast fails
broadcast_acl_updated(acl_id)
json(conn, %{data: member_to_json(new_member)})
end
@@ -300,6 +305,8 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
:acl_member_updated
) do
:ok ->
broadcast_acl_updated(acl_id)
json(conn, %{data: member_to_json(updated_membership)})
{:error, broadcast_error} ->
@@ -307,6 +314,9 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
"Failed to broadcast ACL member updated event: #{inspect(broadcast_error)}"
)
# Still broadcast internal message even if external broadcast fails
broadcast_acl_updated(acl_id)
json(conn, %{data: member_to_json(updated_membership)})
end
@@ -385,6 +395,8 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
:acl_member_removed
) do
:ok ->
broadcast_acl_updated(acl_id)
json(conn, %{ok: true})
{:error, broadcast_error} ->
@@ -392,6 +404,9 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
"Failed to broadcast ACL member removed event: #{inspect(broadcast_error)}"
)
# Still broadcast internal message even if external broadcast fails
broadcast_acl_updated(acl_id)
json(conn, %{ok: true})
end
@@ -417,6 +432,14 @@ defmodule WandererAppWeb.AccessListMemberAPIController do
# Private Helpers
# ---------------------------------------------------------------------------
defp broadcast_acl_updated(acl_id) do
Phoenix.PubSub.broadcast(
WandererApp.PubSub,
"acls:#{acl_id}",
{:acl_updated, %{acl_id: acl_id}}
)
end
@doc false
defp member_to_json(member) do
base = %{

View File

@@ -185,12 +185,12 @@ defmodule WandererAppWeb.Plugs.CheckJsonApiAuth do
# Helper to resolve map by ID or slug
defp resolve_map_identifier(identifier) do
alias WandererApp.Api.Map
# Try as UUID first
case Map.by_id(identifier) do
{:ok, map} ->
{:ok, map} ->
{:ok, map}
_ ->
# Try as slug
Map.get_map_by_slug(identifier)

View File

@@ -75,13 +75,12 @@ defmodule WandererAppWeb.CharactersLive do
def handle_event("delete", %{"character_id" => character_id}, socket) do
WandererApp.Character.TrackerManager.stop_tracking(character_id)
{:ok, map_user_settings} =
{:ok, map_character_settings} =
WandererApp.Api.MapCharacterSettings.tracked_by_character(%{character_id: character_id})
map_user_settings
map_character_settings
|> Enum.each(fn settings ->
settings
|> WandererApp.Api.MapCharacterSettings.untrack()
{:ok, _} = WandererApp.MapCharacterSettingsRepo.untrack(settings)
end)
{:ok, updated_character} =

View File

@@ -4,7 +4,7 @@ defmodule WandererAppWeb.CharactersTrackingLive do
require Logger
@impl true
def mount(_params, %{"user_id" => user_id} = _session, socket) when not is_nil(user_id) do
def mount(_params, _session, socket) do
{:ok, maps} = WandererApp.Maps.get_available_maps(socket.assigns.current_user)
{:ok,
@@ -14,7 +14,6 @@ defmodule WandererAppWeb.CharactersTrackingLive do
characters: [],
selected_map: nil,
selected_map_slug: nil,
user_id: user_id,
maps: maps |> Enum.sort_by(& &1.name, :asc)
)}
end
@@ -37,24 +36,22 @@ defmodule WandererAppWeb.CharactersTrackingLive do
|> assign(:page_title, "Characters Tracking")
end
defp apply_action(socket, :characters, %{"slug" => map_slug} = _params) do
selected_map = socket.assigns.maps |> Enum.find(&(&1.slug == map_slug))
{:ok, character_settings} =
WandererApp.Character.Activity.get_map_character_settings(selected_map.id)
user_id = socket.assigns.user_id
defp apply_action(
%{assigns: %{current_user: current_user, maps: maps}} = socket,
:characters,
%{"slug" => map_slug} = _params
) do
selected_map = maps |> Enum.find(&(&1.slug == map_slug))
socket
|> assign(:active_page, :characters_tracking)
|> assign(:page_title, "Characters Tracking")
|> assign(
selected_map: selected_map,
selected_map_slug: map_slug,
character_settings: character_settings
selected_map_slug: map_slug
)
|> assign_async(:characters, fn ->
WandererApp.Maps.load_characters(selected_map, character_settings, user_id)
WandererApp.Maps.load_characters(selected_map, current_user.id)
end)
end
@@ -71,55 +68,36 @@ defmodule WandererAppWeb.CharactersTrackingLive do
end
@impl true
def handle_event("toggle_track", %{"character_id" => character_id}, socket) do
def handle_event(
"toggle_track",
%{"character_id" => character_id},
%{assigns: %{current_user: current_user}} = socket
) do
selected_map = socket.assigns.selected_map
character_settings = socket.assigns.character_settings
case character_settings |> Enum.find(&(&1.character_id == character_id)) do
nil ->
WandererApp.MapCharacterSettingsRepo.create(%{
character_id: character_id,
map_id: selected_map.id,
tracked: true
})
{:noreply, socket}
character_setting ->
case character_setting.tracked do
true ->
character_setting
|> WandererApp.MapCharacterSettingsRepo.untrack!()
WandererApp.Map.Server.untrack_characters(selected_map.id, [
character_setting.character_id
])
_ ->
character_setting
|> WandererApp.MapCharacterSettingsRepo.track!()
end
end
%{result: characters} = socket.assigns.characters
{:ok, character_settings} =
WandererApp.Character.Activity.get_map_character_settings(selected_map.id)
case characters |> Enum.find(&(&1.id == character_id)) do
%{tracked: false} ->
WandererApp.MapCharacterSettingsRepo.track(%{
character_id: character_id,
map_id: selected_map.id
})
characters =
characters
|> Enum.map(fn c ->
WandererApp.Maps.map_character(
c,
character_settings |> Enum.find(&(&1.character_id == c.id))
)
end)
%{tracked: true} ->
WandererApp.MapCharacterSettingsRepo.untrack(%{
character_id: character_id,
map_id: selected_map.id
})
WandererApp.Map.Server.untrack_characters(selected_map.id, [
character_id
])
end
{:noreply,
socket
|> assign(character_settings: character_settings)
|> assign_async(:characters, fn ->
{:ok, %{characters: characters}}
WandererApp.Maps.load_characters(selected_map, current_user.id)
end)}
end

View File

@@ -333,21 +333,18 @@ defmodule WandererAppWeb.MapCharactersEventHandler do
def needs_tracking_setup?(
only_tracked_characters,
characters,
character_settings,
user_permissions
) do
tracked_count =
characters
|> Enum.count(fn char ->
setting = Enum.find(character_settings, &(&1.character_id == char.id))
setting && setting.tracked
char.tracked
end)
untracked_count =
characters
|> Enum.count(fn char ->
setting = Enum.find(character_settings, &(&1.character_id == char.id))
setting == nil || !setting.tracked
!char.tracked
end)
user_permissions.track_character &&

View File

@@ -422,14 +422,11 @@ defmodule WandererAppWeb.MapCoreEventHandler do
current_user_characters |> Enum.map(& &1.id)
),
{:ok, map_user_settings} <- WandererApp.MapUserSettingsRepo.get(map_id, current_user_id),
{:ok, character_settings} <-
WandererApp.Character.Activity.get_map_character_settings(map_id),
{:ok, %{characters: available_map_characters}} =
WandererApp.Maps.load_characters(map, character_settings, current_user_id) do
WandererApp.Maps.load_characters(map, current_user_id) do
tracked_data =
get_tracked_data(
available_map_characters,
character_settings,
user_permissions,
only_tracked_characters
)
@@ -473,15 +470,13 @@ defmodule WandererAppWeb.MapCoreEventHandler do
defp get_tracked_data(
available_map_characters,
character_settings,
user_permissions,
only_tracked_characters
) do
tracked_characters =
available_map_characters
|> Enum.filter(fn char ->
setting = Enum.find(character_settings, &(&1.character_id == char.id))
setting != nil && setting.tracked == true
char.tracked
end)
all_tracked? =
@@ -492,7 +487,6 @@ defmodule WandererAppWeb.MapCoreEventHandler do
MapCharactersEventHandler.needs_tracking_setup?(
only_tracked_characters,
available_map_characters,
character_settings,
user_permissions
)

View File

@@ -3,7 +3,7 @@ defmodule WandererApp.MixProject do
@source_url "https://github.com/wanderer-industries/wanderer"
@version "1.77.2"
@version "1.77.4"
def project do
[