Compare commits

..

9 Commits

Author SHA1 Message Date
CI
e5aa726899 chore: release version v1.64.6
Some checks failed
Build / 🚀 Deploy to test env (fly.io) (push) Has been cancelled
Build / Manual Approval (push) Has been cancelled
Build / 🛠 Build (1.17, 18.x, 27) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/amd64) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/arm64) (push) Has been cancelled
Build / merge (push) Has been cancelled
Build / 🏷 Create Release (push) Has been cancelled
2025-05-15 10:23:04 +00:00
Dmitry Popov
93d1c28ccd Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-05-15 12:02:02 +02:00
Dmitry Popov
b5ba9200bc fix(Core): Added map hubs limits checking & a proper warning message shown 2025-05-15 12:01:59 +02:00
CI
699d866670 chore: release version v1.64.5
Some checks failed
Build / 🚀 Deploy to test env (fly.io) (push) Has been cancelled
Build / Manual Approval (push) Has been cancelled
Build / 🛠 Build (1.17, 18.x, 27) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/amd64) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/arm64) (push) Has been cancelled
Build / merge (push) Has been cancelled
Build / 🏷 Create Release (push) Has been cancelled
2025-05-14 22:13:32 +00:00
Dmitry Popov
c3071344cb chore: Added link to YT channel 2025-05-14 23:59:06 +02:00
Dmitry Popov
9e998dd2b6 Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-05-14 23:24:57 +02:00
Dmitry Popov
c9accf6079 fix(Core): Added character name update on re-auth 2025-05-14 23:24:49 +02:00
CI
1b41a51004 chore: release version v1.64.4 2025-05-14 20:49:45 +00:00
Dmitry Popov
b49d3423fc fix(Core): Added 1 min timeout for ship and location updates on ESI API errors
Some checks failed
Build / 🚀 Deploy to test env (fly.io) (push) Has been cancelled
Build / Manual Approval (push) Has been cancelled
Build / 🛠 Build (1.17, 18.x, 27) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/amd64) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/arm64) (push) Has been cancelled
Build / merge (push) Has been cancelled
Build / 🏷 Create Release (push) Has been cancelled
2025-05-14 16:35:21 +02:00
11 changed files with 366 additions and 31 deletions

View File

@@ -2,6 +2,33 @@
<!-- changelog -->
## [v1.64.6](https://github.com/wanderer-industries/wanderer/compare/v1.64.5...v1.64.6) (2025-05-15)
### Bug Fixes:
* Core: Added map hubs limits checking & a proper warning message shown
## [v1.64.5](https://github.com/wanderer-industries/wanderer/compare/v1.64.4...v1.64.5) (2025-05-14)
### Bug Fixes:
* Core: Added character name update on re-auth
## [v1.64.4](https://github.com/wanderer-industries/wanderer/compare/v1.64.3...v1.64.4) (2025-05-14)
### Bug Fixes:
* Core: Added 1 min timeout for ship and location updates on ESI API errors
## [v1.64.3](https://github.com/wanderer-industries/wanderer/compare/v1.64.2...v1.64.3) (2025-05-14)

View File

@@ -85,7 +85,7 @@ defmodule WandererApp.Api.Character do
update :update do
require_atomic? false
accept([:access_token, :refresh_token, :expires_at, :scopes])
accept([:name, :access_token, :refresh_token, :expires_at, :scopes])
change(set_attribute(:deleted, false))
end

View File

@@ -139,6 +139,13 @@ defmodule WandererApp.Character.Tracker do
{:error, error} ->
Logger.error("#{__MODULE__} failed to update_ship: #{inspect(error)}")
WandererApp.Cache.put(
"character:#{character_id}:ship_forbidden",
true,
ttl: @forbidden_ttl
)
{:error, error}
end
end
@@ -191,6 +198,13 @@ defmodule WandererApp.Character.Tracker do
{:error, error} ->
Logger.error("#{__MODULE__} failed to update_location: #{inspect(error)}")
WandererApp.Cache.put(
"character:#{character_id}:location_forbidden",
true,
ttl: @forbidden_ttl
)
{:error, error}
end

View File

@@ -17,7 +17,7 @@ defmodule WandererApp.Maps do
:is_shattered
]
def find_routes(map_id, hubs, origin, routes_settings) do
def find_routes(map_id, hubs, origin, routes_settings, false) do
{:ok, routes} =
WandererApp.Esi.find_routes(
map_id,
@@ -48,6 +48,19 @@ defmodule WandererApp.Maps do
{:ok, %{routes: routes, systems_static_data: systems_static_data}}
end
def find_routes(map_id, hubs, origin, routes_settings, true) do
origin = origin |> String.to_integer()
hubs = hubs |> Enum.map(&(&1 |> String.to_integer()))
routes =
hubs
|> Enum.map(fn hub ->
%{origin: origin, destination: hub, success: false, systems: [], has_connection: false}
end)
{:ok, %{routes: routes, systems_static_data: []}}
end
def get_available_maps() do
case WandererApp.Api.Map.available() do
{:ok, maps} -> {:ok, maps}

View File

@@ -66,12 +66,44 @@ defmodule WandererAppWeb.Layouts do
"""
end
def youtube_container(assigns) do
~H"""
<.link
href="https://www.youtube.com/@wanderer_ltd"
class="flex flex-col p-4 items-center absolute bottom-52 left-0 gap-2 tooltip tooltip-right text-gray-400 hover:text-white"
>
<svg
width="24px"
height="24px"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20.5245 6.00694C20.3025 5.81544 20.0333 5.70603 19.836 5.63863C19.6156 5.56337 19.3637 5.50148 19.0989 5.44892C18.5677 5.34348 17.9037 5.26005 17.1675 5.19491C15.6904 5.06419 13.8392 5 12 5C10.1608 5 8.30956 5.06419 6.83246 5.1949C6.09632 5.26005 5.43231 5.34348 4.9011 5.44891C4.63628 5.50147 4.38443 5.56337 4.16403 5.63863C3.96667 5.70603 3.69746 5.81544 3.47552 6.00694C3.26514 6.18846 3.14612 6.41237 3.07941 6.55976C3.00507 6.724 2.94831 6.90201 2.90314 7.07448C2.81255 7.42043 2.74448 7.83867 2.69272 8.28448C2.58852 9.18195 2.53846 10.299 2.53846 11.409C2.53846 12.5198 2.58859 13.6529 2.69218 14.5835C2.74378 15.047 2.81086 15.4809 2.89786 15.8453C2.97306 16.1603 3.09841 16.5895 3.35221 16.9023C3.58757 17.1925 3.92217 17.324 4.08755 17.3836C4.30223 17.461 4.55045 17.5218 4.80667 17.572C5.32337 17.6733 5.98609 17.7527 6.72664 17.8146C8.2145 17.9389 10.1134 18 12 18C13.8865 18 15.7855 17.9389 17.2733 17.8146C18.0139 17.7527 18.6766 17.6733 19.1933 17.572C19.4495 17.5218 19.6978 17.461 19.9124 17.3836C20.0778 17.324 20.4124 17.1925 20.6478 16.9023C20.9016 16.5895 21.0269 16.1603 21.1021 15.8453C21.1891 15.4809 21.2562 15.047 21.3078 14.5835C21.4114 13.6529 21.4615 12.5198 21.4615 11.409C21.4615 10.299 21.4115 9.18195 21.3073 8.28448C21.2555 7.83868 21.1874 7.42043 21.0969 7.07448C21.0517 6.90201 20.9949 6.72401 20.9206 6.55976C20.8539 6.41236 20.7349 6.18846 20.5245 6.00694Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M14.5385 11.5L10.0962 14.3578L10.0962 8.64207L14.5385 11.5Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</.link>
"""
end
def donate_container(assigns) do
~H"""
<.link
href="https://www.patreon.com/WandererLtd"
target="_blank"
class="flex flex-col p-4 items-center absolute bottom-52 left-1 gap-2 tooltip tooltip-right text-gray-400 hover:text-white"
class="flex flex-col p-4 items-center absolute bottom-64 left-1 gap-2 tooltip tooltip-right text-gray-400 hover:text-white"
>
<.icon name="hero-banknotes-solid" class="h-4 w-4" />
</.link>

View File

@@ -19,6 +19,7 @@
<.ping_container rtt_class={@rtt_class} />
<.donate_container />
<.feedback_container />
<.youtube_container />
<.new_version_banner app_version={@app_version} enabled={@map_subscriptions_enabled?} />
</div>

View File

@@ -25,6 +25,7 @@ defmodule WandererAppWeb.AuthController do
case WandererApp.Api.Character.by_eve_id(character_data.eve_id) do
{:ok, character} ->
character_update = %{
name: auth.info.name,
access_token: auth.credentials.token,
refresh_token: auth.credentials.refresh_token,
expires_at: auth.credentials.expires_at,

View File

@@ -1,17 +1,9 @@
<div>
<div class="flex mt-20px max-h-[calc(100vh-50px)] max-w-[100vw] flex-col items-center justify-start xl:flex-row xl:items-start xl:justify-between">
<div class="shrink xl:w-1/2">
<div class="flex min-h-[calc(100vh-100px)] items-center justify-center px-2 py-10 text-center xl:justify-start xl:pe-0 xl:ps-10 xl:text-start">
<div class="flex mt-20px max-h-[calc(100vh-50px)] max-w-[100vw] flex-col items-center">
<div class="shrink">
<div class="flex min-h-[calc(100vh-100px)] items-center justify-center px-2 py-10 text-center xl:pe-0 xl:ps-10">
<div>
<div class="flex flex-col items-center gap-6 xl:flex-row">
<div class="tooltip tooltip-accent" data-tip="copy">
<button class="btn btn-sm cursor-copy rounded-full font-mono font-light">
<pre><code>From: Wanderer Team</code></pre>
</button>
</div>
</div>
<div class="h-3"></div>
<h1 class="font-title text-center text-[clamp(2rem,6vw,4.2rem)] font-black leading-[1.1] [word-break:auto-phrase] xl:w-[115%] xl:text-start [:root[dir=rtl]_&amp;]:leading-[1.35]">
<h1 class="text-center text-[clamp(2rem,6vw,4rem)] font-black leading-[1.1] [word-break:auto-phrase] xl:w-[115%] xl:text-start [:root[dir=rtl]_&amp;]:leading-[1.35]">
<span class="[&amp;::selection]:text-base-content brightness-150 contrast-150 [&amp;::selection]:bg-blue-700/20">
Join or support us!
<!---->
@@ -19,7 +11,7 @@
</h1>
<div class="h-10"></div>
<div>
<div class="inline-flex w-full flex-col items-stretch justify-center gap-2 px-4 md:flex-row xl:justify-start xl:px-0">
<div class="inline-flex w-full items-stretch justify-center gap-2 px-4 flex-col">
<.link
href="https://discord.gg/cafERvDD2k"
class="btn md:btn-lg group shrink-0 rounded-full [@media(min-width:768px)]:px-10 bg-[oklch(64.74%_0.124_270.62)] border-[oklch(64.74%_0.124_270.62)] hover:bg-[oklch(60%_0.124_270.62)] hover:border-[oklch(60%_0.124_270.62)]"
@@ -226,6 +218,52 @@
</path>
</svg>
</a>
<a
href="https://www.youtube.com/@wanderer_ltd"
rel="noopener noreferrer"
aria-label="YouTube"
class="btn md:btn-lg group shrink-0 rounded-full [@media(min-width:768px)]:px-10 bg-[#ff0033] border-[#ff0033] hover:bg-[#ff0033] hover:border-[#ff0033] text-white"
>
<svg
width="48px"
height="48px"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="transition-opacity opacity-100 group-hover:opacity-0"
>
<path
d="M20.5245 6.00694C20.3025 5.81544 20.0333 5.70603 19.836 5.63863C19.6156 5.56337 19.3637 5.50148 19.0989 5.44892C18.5677 5.34348 17.9037 5.26005 17.1675 5.19491C15.6904 5.06419 13.8392 5 12 5C10.1608 5 8.30956 5.06419 6.83246 5.1949C6.09632 5.26005 5.43231 5.34348 4.9011 5.44891C4.63628 5.50147 4.38443 5.56337 4.16403 5.63863C3.96667 5.70603 3.69746 5.81544 3.47552 6.00694C3.26514 6.18846 3.14612 6.41237 3.07941 6.55976C3.00507 6.724 2.94831 6.90201 2.90314 7.07448C2.81255 7.42043 2.74448 7.83867 2.69272 8.28448C2.58852 9.18195 2.53846 10.299 2.53846 11.409C2.53846 12.5198 2.58859 13.6529 2.69218 14.5835C2.74378 15.047 2.81086 15.4809 2.89786 15.8453C2.97306 16.1603 3.09841 16.5895 3.35221 16.9023C3.58757 17.1925 3.92217 17.324 4.08755 17.3836C4.30223 17.461 4.55045 17.5218 4.80667 17.572C5.32337 17.6733 5.98609 17.7527 6.72664 17.8146C8.2145 17.9389 10.1134 18 12 18C13.8865 18 15.7855 17.9389 17.2733 17.8146C18.0139 17.7527 18.6766 17.6733 19.1933 17.572C19.4495 17.5218 19.6978 17.461 19.9124 17.3836C20.0778 17.324 20.4124 17.1925 20.6478 16.9023C20.9016 16.5895 21.0269 16.1603 21.1021 15.8453C21.1891 15.4809 21.2562 15.047 21.3078 14.5835C21.4114 13.6529 21.4615 12.5198 21.4615 11.409C21.4615 10.299 21.4115 9.18195 21.3073 8.28448C21.2555 7.83868 21.1874 7.42043 21.0969 7.07448C21.0517 6.90201 20.9949 6.72401 20.9206 6.55976C20.8539 6.41236 20.7349 6.18846 20.5245 6.00694Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M14.5385 11.5L10.0962 14.3578L10.0962 8.64207L14.5385 11.5Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="text-lg font-bold transition-opacity opacity-100 group-hover:opacity-0 ml-2">
YouTube
</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
class="inline-block absolute w-6 fill-white transition-all scale-90 group-hover:scale-100 opacity-0 group-hover:opacity-100"
>
<path
fill-rule="evenodd"
d="M19,14 L19,19 C19,20.1045695 18.1045695,21 17,21 L5,21 C3.8954305,21 3,20.1045695 3,19 L3,7 C3,5.8954305 3.8954305,5 5,5 L10,5 L10,7 L5,7 L5,19 L17,19 L17,14 L19,14 Z M18.9971001,6.41421356 L11.7042068,13.7071068 L10.2899933,12.2928932 L17.5828865,5 L12.9971001,5 L12.9971001,3 L20.9971001,3 L20.9971001,11 L18.9971001,11 L18.9971001,6.41421356 Z"
>
</path>
</svg>
</a>
</div>
</div>
</div>

View File

@@ -51,21 +51,36 @@ defmodule WandererAppWeb.MapRoutesEventHandler do
%{"system_id" => solar_system_id, "routes_settings" => routes_settings} = _event,
%{assigns: %{map_id: map_id, map_loaded?: true}} = socket
) do
Task.async(fn ->
{:ok, hubs} = map_id |> WandererApp.Map.list_hubs()
{:ok, map} = map_id |> WandererApp.Map.get_map()
hubs_limit = map |> Map.get(:hubs_limit, 20)
{:ok, hubs} = map_id |> WandererApp.Map.list_hubs()
is_hubs_limit_reached = hubs |> Enum.count() > hubs_limit
Task.async(fn ->
{:ok, routes} =
WandererApp.Maps.find_routes(
map_id,
hubs,
solar_system_id,
get_routes_settings(routes_settings)
get_routes_settings(routes_settings),
is_hubs_limit_reached
)
{:routes, {solar_system_id, routes}}
end)
{:noreply, socket}
if is_hubs_limit_reached do
{:noreply,
socket
|> put_flash(
:warning,
"The Map hubs limit has been reached, please try to remove some hubs first, or contact the map administrators."
)}
else
{:noreply, socket}
end
end
def handle_ui_event(
@@ -80,16 +95,22 @@ defmodule WandererAppWeb.MapRoutesEventHandler do
}
} = socket
) do
{:ok, map} = map_id |> WandererApp.Map.get_map()
hubs_limit = map |> Map.get(:hubs_limit, 20)
{:ok, hubs} = WandererApp.MapUserSettingsRepo.get_hubs(map_id, current_user.id)
is_hubs_limit_reached = hubs |> Enum.count() > hubs_limit
Task.async(fn ->
if is_subscription_active? do
{:ok, hubs} = WandererApp.MapUserSettingsRepo.get_hubs(map_id, current_user.id)
{:ok, routes} =
WandererApp.Maps.find_routes(
map_id,
hubs,
solar_system_id,
get_routes_settings(routes_settings)
get_routes_settings(routes_settings),
is_hubs_limit_reached
)
{:user_routes, {solar_system_id, routes}}
@@ -98,9 +119,197 @@ defmodule WandererAppWeb.MapRoutesEventHandler do
end
end)
if is_hubs_limit_reached do
{:noreply,
socket
|> put_flash(
:warning,
"The user hubs limit has been reached, please try to remove some hubs first, or contact the map administrators."
)}
else
{:noreply, socket}
end
end
def handle_ui_event(
"add_hub",
%{"system_id" => solar_system_id} = _event,
%{
assigns: %{
map_id: map_id,
current_user: current_user,
main_character_id: main_character_id,
has_tracked_characters?: true,
user_permissions: %{update_system: true}
}
} =
socket
)
when not is_nil(main_character_id) do
{:ok, map} = map_id |> WandererApp.Map.get_map()
hubs_limit = map |> Map.get(:hubs_limit, 20)
{:ok, hubs} = map_id |> WandererApp.Map.list_hubs()
if hubs |> Enum.count() < hubs_limit do
map_id
|> WandererApp.Map.Server.add_hub(%{
solar_system_id: solar_system_id
})
{:ok, _} =
WandererApp.User.ActivityTracker.track_map_event(:hub_added, %{
character_id: main_character_id,
user_id: current_user.id,
map_id: map_id,
solar_system_id: solar_system_id
})
{:noreply, socket}
else
{:noreply,
socket
|> put_flash(
:warning,
"The Map hubs limit has been reached, please try to remove some hubs first, or contact the map administrators."
)}
end
end
def handle_ui_event(
"delete_hub",
%{"system_id" => solar_system_id} = _event,
%{
assigns: %{
map_id: map_id,
current_user: current_user,
main_character_id: main_character_id,
has_tracked_characters?: true,
user_permissions: %{update_system: true}
}
} =
socket
)
when not is_nil(main_character_id) do
map_id
|> WandererApp.Map.Server.remove_hub(%{
solar_system_id: solar_system_id
})
{:ok, _} =
WandererApp.User.ActivityTracker.track_map_event(:hub_removed, %{
character_id: main_character_id,
user_id: current_user.id,
map_id: map_id,
solar_system_id: solar_system_id
})
{:noreply, socket}
end
def handle_ui_event(
"get_user_hubs",
_event,
%{
assigns: %{
map_id: map_id,
current_user: current_user
}
} =
socket
) do
{:ok, hubs} = WandererApp.MapUserSettingsRepo.get_hubs(map_id, current_user.id)
{:reply, %{hubs: hubs}, socket}
end
def handle_ui_event(
"add_user_hub",
%{"system_id" => solar_system_id} = _event,
%{
assigns: %{
map_id: map_id,
current_user: current_user
}
} =
socket
) do
{:ok, map} = map_id |> WandererApp.Map.get_map()
hubs_limit = map |> Map.get(:hubs_limit, 20)
{:ok, hubs} = WandererApp.MapUserSettingsRepo.get_hubs(map_id, current_user.id)
if hubs |> Enum.count() < hubs_limit do
hubs = hubs ++ ["#{solar_system_id}"]
{:ok, _} =
WandererApp.MapUserSettingsRepo.update_hubs(
map_id,
current_user.id,
hubs
)
{:noreply,
socket
|> MapEventHandler.push_map_event(
"map_updated",
%{user_hubs: hubs}
)}
else
{:noreply,
socket
|> MapEventHandler.push_map_event(
"map_updated",
%{user_hubs: hubs}
)
|> put_flash(
:warning,
"The user hubs limit has been reached, please try to remove some user hubs first, or contact the map administrators."
)}
end
end
def handle_ui_event(
"delete_user_hub",
%{"system_id" => solar_system_id} = _event,
%{
assigns: %{
map_id: map_id,
current_user: current_user
}
} =
socket
) do
{:ok, hubs} = WandererApp.MapUserSettingsRepo.get_hubs(map_id, current_user.id)
case hubs |> Enum.member?("#{solar_system_id}") do
true ->
hubs = hubs |> Enum.reject(fn hub -> hub == "#{solar_system_id}" end)
{:ok, _} =
WandererApp.MapUserSettingsRepo.update_hubs(
map_id,
current_user.id,
hubs
)
{:noreply,
socket
|> MapEventHandler.push_map_event(
"map_updated",
%{user_hubs: hubs}
)}
_ ->
{:noreply,
socket
|> MapEventHandler.push_map_event(
"map_updated",
%{user_hubs: hubs}
)}
end
end
def handle_ui_event(
"set_autopilot_waypoint",
%{

View File

@@ -42,8 +42,6 @@ defmodule WandererAppWeb.MapEventHandler do
]
@map_system_ui_events [
"add_hub",
"delete_hub",
"delete_systems",
"get_system_static_infos",
"manual_add_system",
@@ -56,10 +54,7 @@ defmodule WandererAppWeb.MapEventHandler do
"update_system_locked",
"update_system_tag",
"update_system_temporary_name",
"update_system_status",
"get_user_hubs",
"add_user_hub",
"delete_user_hub"
"update_system_status"
]
@map_system_comments_events [
@@ -108,7 +103,12 @@ defmodule WandererAppWeb.MapEventHandler do
@map_routes_ui_events [
"get_routes",
"get_user_routes",
"set_autopilot_waypoint"
"set_autopilot_waypoint",
"add_hub",
"delete_hub",
"get_user_hubs",
"add_user_hub",
"delete_user_hub"
]
@map_signatures_events [

View File

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