adds elevation loss for trails
This commit is contained in:
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,4 +1,14 @@
|
|||||||
|
# v0.10.1
|
||||||
|
## Features
|
||||||
|
- Adds elevation loss to trails. Please note that trails created before this version will have a default elevation loss of 0. Edit & save to update.
|
||||||
|
|
||||||
|
## Bug fixes
|
||||||
|
- Fixes bug that caused auto-added summit logs to not have distance, durtaion etc.
|
||||||
|
- Fixes error in the auto-upload feature
|
||||||
|
- Fixes access permissions for profile page
|
||||||
|
- A summit log is now also created automatically when you upload a trail directly
|
||||||
|
- Fixes link to the API documentation in footer
|
||||||
|
|
||||||
# v0.10.0
|
# v0.10.0
|
||||||
## Features
|
## Features
|
||||||
- A new summit log entry is now added automatically when uploading a new GPX file for a new or existing trail
|
- A new summit log entry is now added automatically when uploading a new GPX file for a new or existing trail
|
||||||
|
|||||||
55
db/migrations/1731151547_updated_trails.go
Normal file
55
db/migrations/1731151547_updated_trails.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
|
m "github.com/pocketbase/pocketbase/migrations"
|
||||||
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
m.Register(func(db dbx.Builder) error {
|
||||||
|
dao := daos.New(db);
|
||||||
|
|
||||||
|
collection, err := dao.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// add
|
||||||
|
new_elevation_loss := &schema.SchemaField{}
|
||||||
|
if err := json.Unmarshal([]byte(`{
|
||||||
|
"system": false,
|
||||||
|
"id": "xutbwpq4",
|
||||||
|
"name": "elevation_loss",
|
||||||
|
"type": "number",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"noDecimal": false
|
||||||
|
}
|
||||||
|
}`), new_elevation_loss); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
collection.Schema.AddField(new_elevation_loss)
|
||||||
|
|
||||||
|
return dao.SaveCollection(collection)
|
||||||
|
}, func(db dbx.Builder) error {
|
||||||
|
dao := daos.New(db);
|
||||||
|
|
||||||
|
collection, err := dao.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove
|
||||||
|
collection.Schema.RemoveField("xutbwpq4")
|
||||||
|
|
||||||
|
return dao.SaveCollection(collection)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
|
|
||||||
function colorKey(i: number) {
|
function colorKey(i: number) {
|
||||||
return $_(
|
return $_(
|
||||||
currentMonthArray[i]?.log?.expand.trails_via_summit_logs?.at(0)
|
currentMonthArray[i]?.log?.expand?.trails_via_summit_logs?.at(0)
|
||||||
?.expand?.category?.name ?? "",
|
?.expand?.category?.name ?? "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,11 +80,11 @@
|
|||||||
type="button"
|
type="button"
|
||||||
on:click={openMap}
|
on:click={openMap}
|
||||||
class="h-20 aspect-square shrink-0 rounded-xl !bg-background hover:!bg-secondary-hover transition-colors"
|
class="h-20 aspect-square shrink-0 rounded-xl !bg-background hover:!bg-secondary-hover transition-colors"
|
||||||
class:hidden={!log.expand.gpx_data}
|
class:hidden={!log.expand?.gpx_data}
|
||||||
id="mini-map-{index}"
|
id="mini-map-{index}"
|
||||||
></button>
|
></button>
|
||||||
</td>
|
</td>
|
||||||
<td class:py-4={!log.expand.gpx_data}
|
<td class:py-4={!log.expand?.gpx_data}
|
||||||
>{new Date(log.date).toLocaleDateString(undefined, {
|
>{new Date(log.date).toLocaleDateString(undefined, {
|
||||||
month: "2-digit",
|
month: "2-digit",
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
{#if showCategory}
|
{#if showCategory}
|
||||||
<td>
|
<td>
|
||||||
{$_(
|
{$_(
|
||||||
log.expand.trails_via_summit_logs?.at(0)?.expand.category
|
log.expand?.trails_via_summit_logs?.at(0)?.expand?.category
|
||||||
?.name ?? "-",
|
?.name ?? "-",
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
class="btn-icon aspect-square"
|
class="btn-icon aspect-square"
|
||||||
href="/trail/view/{log.expand.trails_via_summit_logs?.at(0)
|
href="/trail/view/{log.expand?.trails_via_summit_logs?.at(0)
|
||||||
?.id ?? ''}"
|
?.id ?? ''}"
|
||||||
><i class="fa fa-arrow-up-right-from-square px-[3px]"></i></a
|
><i class="fa fa-arrow-up-right-from-square px-[3px]"></i></a
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -75,20 +75,25 @@
|
|||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex mt-1 gap-4 text-sm text-gray-500 whitespace-nowrap">
|
<div class="grid grid-cols-2 mt-2 gap-1 text-sm text-gray-500 whitespace-nowrap">
|
||||||
<span
|
<span
|
||||||
><i class="fa fa-left-right mr-2"></i>{formatDistance(
|
><i class="fa fa-left-right mr-2"></i>{formatDistance(
|
||||||
trail.distance,
|
trail.distance,
|
||||||
)}</span
|
)}</span
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
><i class="fa fa-up-down mr-2"></i>{formatElevation(
|
><i class="fa fa-clock mr-2"></i>{formatTimeHHMM(
|
||||||
|
trail.duration,
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
><i class="fa fa-arrow-trend-up mr-2"></i>{formatElevation(
|
||||||
trail.elevation_gain,
|
trail.elevation_gain,
|
||||||
)}</span
|
)}</span
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
><i class="fa fa-clock mr-2"></i>{formatTimeHHMM(
|
><i class="fa fa-arrow-trend-down mr-2"></i>{formatElevation(
|
||||||
trail.duration,
|
trail.elevation_loss,
|
||||||
)}</span
|
)}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -246,7 +246,7 @@
|
|||||||
</section>
|
</section>
|
||||||
{#if mode == "overview"}
|
{#if mode == "overview"}
|
||||||
<section
|
<section
|
||||||
class="grid grid-cols-2 sm:grid-cols-4 gap-y-4 justify-around py-8 border-b border-input-border"
|
class="grid grid-cols-2 sm:grid-cols-5 gap-y-4 justify-around py-8 border-b border-input-border"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<span>{$_("distance")}</span>
|
<span>{$_("distance")}</span>
|
||||||
@@ -254,6 +254,12 @@
|
|||||||
>{formatDistance(trail.distance)}</span
|
>{formatDistance(trail.distance)}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<span>{$_("est-duration")}</span>
|
||||||
|
<span class="font-semibold text-lg"
|
||||||
|
>{formatTimeHHMM(trail.duration)}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<span>{$_("elevation-gain")}</span>
|
<span>{$_("elevation-gain")}</span>
|
||||||
<span class="font-semibold text-lg"
|
<span class="font-semibold text-lg"
|
||||||
@@ -261,9 +267,9 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<span>{$_("est-duration")}</span>
|
<span>{$_("elevation-loss")}</span>
|
||||||
<span class="font-semibold text-lg"
|
<span class="font-semibold text-lg"
|
||||||
>{formatTimeHHMM(trail.duration)}</span
|
>{formatElevation(trail.elevation_loss)}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
{#if trail.expand.category}
|
{#if trail.expand.category}
|
||||||
|
|||||||
@@ -64,13 +64,18 @@
|
|||||||
)}</span
|
)}</span
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
><i class="fa fa-up-down mr-2"></i>{formatElevation(
|
><i class="fa fa-clock mr-2"></i>{formatTimeHHMM(
|
||||||
|
trail.duration,
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
><i class="fa fa-arrow-trend-up mr-2"></i>{formatElevation(
|
||||||
trail.elevation_gain,
|
trail.elevation_gain,
|
||||||
)}</span
|
)}</span
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
><i class="fa fa-clock mr-2"></i>{formatTimeHHMM(
|
><i class="fa fa-arrow-trend-down mr-2"></i>{formatElevation(
|
||||||
trail.duration,
|
trail.elevation_loss,
|
||||||
)}</span
|
)}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class SummitLog {
|
|||||||
date: string;
|
date: string;
|
||||||
text?: string;
|
text?: string;
|
||||||
gpx?: string;
|
gpx?: string;
|
||||||
_gpx: File | Blob | null;
|
_gpx: File | null;
|
||||||
distance?: number
|
distance?: number
|
||||||
elevation_gain?: number
|
elevation_gain?: number
|
||||||
elevation_loss?: number
|
elevation_loss?: number
|
||||||
@@ -17,11 +17,15 @@ class SummitLog {
|
|||||||
trails_via_summit_logs?: Trail[];
|
trails_via_summit_logs?: Trail[];
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(date: string, params?: { id?: string, text?: string }) {
|
constructor(date: string, params?: { id?: string, text?: string, distance?: number, elevation_loss?: number, elevation_gain?: number, duration?: number }) {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.id = params?.id;
|
this.id = params?.id;
|
||||||
this.text = params?.text ?? "";
|
this.text = params?.text ?? "";
|
||||||
this.expand = {}
|
this.expand = {}
|
||||||
|
this.distance = params?.distance
|
||||||
|
this.elevation_gain = params?.elevation_gain
|
||||||
|
this.elevation_loss = params?.elevation_loss
|
||||||
|
this.duration = params?.duration
|
||||||
this._gpx = null
|
this._gpx = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class Trail {
|
|||||||
public: boolean;
|
public: boolean;
|
||||||
distance?: number;
|
distance?: number;
|
||||||
elevation_gain?: number;
|
elevation_gain?: number;
|
||||||
|
elevation_loss?: number;
|
||||||
duration?: number;
|
duration?: number;
|
||||||
difficulty?: "easy" | "moderate" | "difficult"
|
difficulty?: "easy" | "moderate" | "difficult"
|
||||||
lat?: number;
|
lat?: number;
|
||||||
@@ -43,6 +44,7 @@ class Trail {
|
|||||||
public?: boolean,
|
public?: boolean,
|
||||||
distance?: number,
|
distance?: number,
|
||||||
elevation_gain?: number,
|
elevation_gain?: number,
|
||||||
|
elevation_loss?: number,
|
||||||
duration?: number,
|
duration?: number,
|
||||||
difficulty?: "easy" | "moderate" | "difficult",
|
difficulty?: "easy" | "moderate" | "difficult",
|
||||||
lat?: number,
|
lat?: number,
|
||||||
@@ -68,6 +70,7 @@ class Trail {
|
|||||||
this.public = params?.public ?? false
|
this.public = params?.public ?? false
|
||||||
this.distance = params?.distance;
|
this.distance = params?.distance;
|
||||||
this.elevation_gain = params?.elevation_gain;
|
this.elevation_gain = params?.elevation_gain;
|
||||||
|
this.elevation_loss = params?.elevation_loss;
|
||||||
this.duration = params?.duration;
|
this.duration = params?.duration;
|
||||||
this.difficulty = params?.difficulty ?? "easy";
|
this.difficulty = params?.difficulty ?? "easy";
|
||||||
this.lat = params?.lat;
|
this.lat = params?.lat;
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export async function gpx2trail(gpxString: string, fallbackName?: string) {
|
|||||||
|
|
||||||
trail.duration = totals.duration / 1000 / 60
|
trail.duration = totals.duration / 1000 / 60
|
||||||
trail.elevation_gain = totals.elevationGain;
|
trail.elevation_gain = totals.elevationGain;
|
||||||
|
trail.elevation_loss = totals.elevationLoss;
|
||||||
trail.distance = totals.distance
|
trail.distance = totals.distance
|
||||||
|
|
||||||
return { gpx: gpx, trail: trail }
|
return { gpx: gpx, trail: trail }
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
$: logCategories = $summitLogs.reduce(
|
$: logCategories = $summitLogs.reduce(
|
||||||
(acc, log) => {
|
(acc, log) => {
|
||||||
const cat =
|
const cat =
|
||||||
log.expand.trails_via_summit_logs?.at(0)?.expand.category
|
log.expand?.trails_via_summit_logs?.at(0)?.expand?.category
|
||||||
?.name ?? "unknown";
|
?.name ?? "unknown";
|
||||||
acc[$_(cat)] = (acc[$_(cat)] || 0) + 1;
|
acc[$_(cat)] = (acc[$_(cat)] || 0) + 1;
|
||||||
return acc;
|
return acc;
|
||||||
|
|||||||
Reference in New Issue
Block a user