1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-08-07 06:05:19 +02:00

feat: add wanderer link support in TrailSerializer and TrailCard; update measurement system handling in location page

This commit is contained in:
Sean Morley 2025-08-05 17:53:57 -04:00
parent eb3c9c2b64
commit c502ae350e
4 changed files with 57 additions and 15 deletions

View file

@ -92,11 +92,24 @@ class CategorySerializer(serializers.ModelSerializer):
class TrailSerializer(CustomModelSerializer):
provider = serializers.SerializerMethodField()
wanderer_data = serializers.SerializerMethodField()
wanderer_link = serializers.SerializerMethodField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._wanderer_integration_cache = {}
class Meta:
model = Trail
fields = ['id', 'user', 'name', 'location', 'created_at','link','wanderer_id', 'provider', 'wanderer_data']
fields = ['id', 'user', 'name', 'location', 'created_at','link','wanderer_id', 'provider', 'wanderer_data', 'wanderer_link']
read_only_fields = ['id', 'created_at', 'user', 'provider']
def _get_wanderer_integration(self, user):
"""Cache wanderer integration to avoid multiple database queries"""
if user.id not in self._wanderer_integration_cache:
from integrations.models import WandererIntegration
self._wanderer_integration_cache[user.id] = WandererIntegration.objects.filter(user=user).first()
return self._wanderer_integration_cache[user.id]
def get_provider(self, obj):
if obj.wanderer_id:
return 'Wanderer'
@ -116,23 +129,39 @@ class TrailSerializer(CustomModelSerializer):
if not obj.wanderer_id:
return None
# Use cached integration
integration = self._get_wanderer_integration(obj.user)
if not integration:
return None
# Fetch the Wanderer trail data
from integrations.models import WandererIntegration
from integrations.wanderer_services import fetch_trail_by_id
try:
integration = WandererIntegration.objects.filter(user=obj.user).first()
if not integration:
return None
# Assuming there's a method to fetch trail data by ID
trail_data = fetch_trail_by_id(integration, obj.wanderer_id)
if not trail_data:
return None
obj.wanderer_data = trail_data
# Cache the trail data and link on the object to avoid refetching
obj._wanderer_data = trail_data
base_url = integration.server_url.rstrip('/')
obj._wanderer_link = f"{base_url}/trails/{obj.wanderer_id}"
return trail_data
except Exception as e:
logger.error(f"Error fetching Wanderer trail data for {obj.wanderer_id}")
logger.error(f"Error fetching Wanderer trail data for {obj.wanderer_id}: {e}")
return None
def get_wanderer_link(self, obj):
if not obj.wanderer_id:
return None
# Use cached integration
integration = self._get_wanderer_integration(obj.user)
if not integration:
return None
base_url = integration.server_url.rstrip('/')
return f"{base_url}/trail/view/@{integration.username}/{obj.wanderer_id}"
class ActivitySerializer(CustomModelSerializer):

View file

@ -140,9 +140,9 @@
{/if}
</div>
{#if trail.link}
{#if trail.link || trail.wanderer_link}
<a
href={trail.link}
href={trail.wanderer_link || trail.link}
target="_blank"
rel="noopener noreferrer"
class="btn btn-sm btn-primary"

View file

@ -330,6 +330,7 @@ export type Trail = {
wanderer_id?: string | null; // Optional ID for integration with Wanderer
provider: string; // Provider of the trail data, e.g., 'wanderer', 'external'
wanderer_data: WandererTrail | null; // Optional data from Wanderer integration
wanderer_link: string | null; // Optional link to the Wanderer trail
};
export type StravaActivity = {

View file

@ -119,6 +119,7 @@
}
export let data: PageData;
let measurementSystem = data.user?.measurement_system || 'metric';
console.log(data);
let adventure: AdditionalLocation;
@ -175,7 +176,7 @@
}
function getTotalDistance(adventure: AdditionalLocation) {
return adventure.visits.reduce(
const totalMeters = adventure.visits.reduce(
(total, visit) =>
total +
(visit.activities
@ -183,10 +184,14 @@
: 0),
0
);
// Convert meters to km, then to miles if using imperial system
const totalKm = totalMeters / 1000;
return measurementSystem === 'imperial' ? totalKm * 0.621371 : totalKm;
}
function getTotalElevationGain(adventure: AdditionalLocation) {
return adventure.visits.reduce(
const totalMeters = adventure.visits.reduce(
(total, visit) =>
total +
(visit.activities
@ -194,6 +199,9 @@
: 0),
0
);
// Convert to feet if using imperial system
return measurementSystem === 'imperial' ? totalMeters * 3.28084 : totalMeters;
}
async function saveEdit(event: CustomEvent<AdditionalLocation>) {
@ -860,7 +868,9 @@
<div class="stat">
<div class="stat-title">Total Distance</div>
<div class="stat-value text-xl">
{getTotalDistance(adventure).toFixed(1)} km
{getTotalDistance(adventure).toFixed(1)}
{#if measurementSystem === 'imperial'}mi
{:else}km{/if}
</div>
</div>
{/if}
@ -868,7 +878,9 @@
<div class="stat">
<div class="stat-title">Total Elevation</div>
<div class="stat-value text-xl">
{getTotalElevationGain(adventure).toFixed(0)} m
{getTotalElevationGain(adventure).toFixed(0)}
{#if measurementSystem === 'imperial'}ft
{:else}m{/if}
</div>
</div>
{/if}