adds list link sharing
This commit is contained in:
@@ -76,7 +76,7 @@
|
|||||||
<Dropdown items={dropdownItems} on:change></Dropdown>
|
<Dropdown items={dropdownItems} on:change></Dropdown>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex mt-1 gap-4 text-sm text-gray-500 whitespace-nowrap">
|
<div class="flex mt-1 gap-x-4 text-sm text-gray-500 whitespace-nowrap flex-wrap">
|
||||||
<span
|
<span
|
||||||
><i class="fa fa-left-right mr-2"></i>{formatDistance(
|
><i class="fa fa-left-right mr-2"></i>{formatDistance(
|
||||||
cumulativeDistance,
|
cumulativeDistance,
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
list_share_delete,
|
list_share_delete,
|
||||||
list_share_index,
|
list_share_index,
|
||||||
list_share_update,
|
list_share_update,
|
||||||
shares,
|
shares
|
||||||
} from "$lib/stores/list_share_store";
|
} from "$lib/stores/list_share_store";
|
||||||
|
import { lists } from "$lib/stores/list_store";
|
||||||
import { show_toast } from "$lib/stores/toast_store";
|
import { show_toast } from "$lib/stores/toast_store";
|
||||||
import {
|
import {
|
||||||
trail_share_create,
|
trail_share_create,
|
||||||
@@ -25,8 +26,6 @@
|
|||||||
import Search, { type SearchItem } from "../base/search.svelte";
|
import Search, { type SearchItem } from "../base/search.svelte";
|
||||||
import type { SelectItem } from "../base/select.svelte";
|
import type { SelectItem } from "../base/select.svelte";
|
||||||
import Select from "../base/select.svelte";
|
import Select from "../base/select.svelte";
|
||||||
import { useFBO } from "@threlte/extras";
|
|
||||||
import { lists } from "$lib/stores/list_store";
|
|
||||||
|
|
||||||
let openModal: (() => void) | undefined = undefined;
|
let openModal: (() => void) | undefined = undefined;
|
||||||
export let closeModal: (() => void) | undefined = undefined;
|
export let closeModal: (() => void) | undefined = undefined;
|
||||||
@@ -72,7 +71,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function copyURLToClipboard() {
|
function copyURLToClipboard() {
|
||||||
navigator.clipboard.writeText(window.location.href);
|
navigator.clipboard.writeText(window.location.href.split('?')[0] + '?list=' + list.id);
|
||||||
|
|
||||||
copyButtonText = $_("link-copied");
|
copyButtonText = $_("link-copied");
|
||||||
setTimeout(() => (copyButtonText = $_("copy-link")), 3000);
|
setTimeout(() => (copyButtonText = $_("copy-link")), 3000);
|
||||||
@@ -135,6 +134,7 @@
|
|||||||
trails: list.expand?.trails ?? [],
|
trails: list.expand?.trails ?? [],
|
||||||
list_share_via_list: fetchedShares,
|
list_share_via_list: fetchedShares,
|
||||||
};
|
};
|
||||||
|
lists.set($lists)
|
||||||
sharesLoading = false;
|
sharesLoading = false;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -36,9 +36,9 @@
|
|||||||
(gpxData.length != gpxGroup._tracks.length ||
|
(gpxData.length != gpxGroup._tracks.length ||
|
||||||
gpxGroup?._tracks[0] !== gpxData[0])
|
gpxGroup?._tracks[0] !== gpxData[0])
|
||||||
) {
|
) {
|
||||||
if (gpxData.length == 0) {
|
// if (gpxData.length == 0) {
|
||||||
map?.setView([0, 0], 4);
|
// map?.setView([0, 0], 4);
|
||||||
}
|
// }
|
||||||
gpxGroup._elevation.updateOptions({
|
gpxGroup._elevation.updateOptions({
|
||||||
autofitBounds: options.autofitBounds ?? true,
|
autofitBounds: options.autofitBounds ?? true,
|
||||||
});
|
});
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
closeBtn: false,
|
closeBtn: false,
|
||||||
followMarker: true,
|
followMarker: true,
|
||||||
autofitBounds: true,
|
autofitBounds: true,
|
||||||
imperial: $page.data.settings?.unit == "imperial" ?? false,
|
imperial: $page.data.settings?.unit == "imperial",
|
||||||
reverseCoords: false,
|
reverseCoords: false,
|
||||||
acceleration: false,
|
acceleration: false,
|
||||||
slope: true,
|
slope: true,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import TrailCard from "./trail_card.svelte";
|
import TrailCard from "./trail_card.svelte";
|
||||||
import TrailListItem from "./trail_list_item.svelte";
|
import TrailListItem from "./trail_list_item.svelte";
|
||||||
|
|
||||||
export let filter: TrailFilter;
|
export let filter: TrailFilter | null = null;
|
||||||
export let trails: Trail[];
|
export let trails: Trail[];
|
||||||
export let pagination: { page: number; totalPages: number } = {
|
export let pagination: { page: number; totalPages: number } = {
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -41,10 +41,10 @@
|
|||||||
if (storedDisplayOption) {
|
if (storedDisplayOption) {
|
||||||
selectedDisplayOption = storedDisplayOption;
|
selectedDisplayOption = storedDisplayOption;
|
||||||
}
|
}
|
||||||
if (storedSort) {
|
if (filter && storedSort) {
|
||||||
filter.sort = storedSort as typeof filter.sort;
|
filter.sort = storedSort as typeof filter.sort;
|
||||||
}
|
}
|
||||||
if (storedSortOrder) {
|
if (filter && storedSortOrder) {
|
||||||
filter.sortOrder = storedSortOrder as typeof filter.sortOrder;
|
filter.sortOrder = storedSortOrder as typeof filter.sortOrder;
|
||||||
}
|
}
|
||||||
if (storedSort || storedSortOrder) {
|
if (storedSort || storedSortOrder) {
|
||||||
@@ -57,11 +57,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setSort() {
|
function setSort() {
|
||||||
|
if(!filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
localStorage.setItem("sort", filter.sort);
|
localStorage.setItem("sort", filter.sort);
|
||||||
dispatch("update", filter);
|
dispatch("update", filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSortOrder() {
|
function setSortOrder() {
|
||||||
|
if(!filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (filter.sortOrder === "+") {
|
if (filter.sortOrder === "+") {
|
||||||
filter.sortOrder = "-";
|
filter.sortOrder = "-";
|
||||||
} else {
|
} else {
|
||||||
@@ -81,6 +87,7 @@
|
|||||||
on:pagination
|
on:pagination
|
||||||
></Pagination>
|
></Pagination>
|
||||||
</div>
|
</div>
|
||||||
|
{#if filter}
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<p class="text-sm text-gray-500 pb-2">{$_("sort")}</p>
|
<p class="text-sm text-gray-500 pb-2">{$_("sort")}</p>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
@@ -98,6 +105,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<p class="text-sm text-gray-500 pb-2">{$_("display-as")}</p>
|
<p class="text-sm text-gray-500 pb-2">{$_("display-as")}</p>
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const endIcon = () => L.divIcon({
|
|||||||
|
|
||||||
export function createMarkerFromWaypoint(L: any, waypoint: Waypoint, onDragEnd?: (event: LeafletEvent) => void): Marker {
|
export function createMarkerFromWaypoint(L: any, waypoint: Waypoint, onDragEnd?: (event: LeafletEvent) => void): Marker {
|
||||||
const icon = L.divIcon({
|
const icon = L.divIcon({
|
||||||
html: `<i class="px-2 py-2 text-white bg-gray-500 rounded-lg fa fa-${waypoint.icon}"></i>`,
|
html: `<i class="px-2 py-2 text-white bg-gray-500 rounded-full fa fa-${waypoint.icon}"></i>`,
|
||||||
className: 'waypoint-icon'
|
className: 'waypoint-icon'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|||||||
Object.assign(this.options, options)
|
Object.assign(this.options, options)
|
||||||
if (!this.options.showStartEnd) {
|
if (!this.options.showStartEnd) {
|
||||||
this._circleMarkers.remove();
|
this._circleMarkers.remove();
|
||||||
} else if (this._data.length) {
|
} else if (this._data.length && this._map) {
|
||||||
this._circleMarkers.addTo(this._map);
|
this._circleMarkers.addTo(this._map);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,19 +24,27 @@
|
|||||||
import "leaflet.awesome-markers/dist/leaflet.awesome-markers.css";
|
import "leaflet.awesome-markers/dist/leaflet.awesome-markers.css";
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
import { tick } from "svelte";
|
import { onMount, tick } from "svelte";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
|
|
||||||
let openListModal: () => void;
|
let openListModal: () => void;
|
||||||
let openConfirmModal: () => void;
|
let openConfirmModal: () => void;
|
||||||
let openShareModal: () => void;
|
let openShareModal: () => void;
|
||||||
|
|
||||||
let filter: TrailFilter = $page.data.filter;
|
|
||||||
let listToBeDeleted: List | null = null;
|
let listToBeDeleted: List | null = null;
|
||||||
|
|
||||||
let map: Map;
|
let map: Map;
|
||||||
let showMap: boolean = true;
|
let showMap: boolean = true;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if ($page.url.searchParams.get("list")) {
|
||||||
|
const listToFocus = $lists.find((l) => l.id == $page.url.searchParams.get("list"));
|
||||||
|
if(listToFocus) {
|
||||||
|
setCurrentList(listToFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function toggleMap() {
|
async function toggleMap() {
|
||||||
showMap = !showMap;
|
showMap = !showMap;
|
||||||
if (showMap) {
|
if (showMap) {
|
||||||
@@ -99,7 +107,7 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
<main class="grid grid-cols-1 md:grid-cols-[430px_1fr] gap-4 lg:gap-4 mx-4">
|
<main class="grid grid-cols-1 md:grid-cols-[430px_1fr] gap-4 lg:gap-4 mx-4">
|
||||||
<ul
|
<ul
|
||||||
class="list-list mx-4 md:mx-auto rounded-xl border border-input-border max-h-full"
|
class="list-list md:mx-auto rounded-xl border border-input-border max-h-full"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex gap-x-4 items-center justify-between p-4 bg-background z-50 rounded-xl"
|
class="flex gap-x-4 items-center justify-between p-4 bg-background z-50 rounded-xl"
|
||||||
@@ -139,11 +147,7 @@
|
|||||||
></MapWithElevationMultiple>
|
></MapWithElevationMultiple>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0" class:hidden={showMap}>
|
<div class="min-w-0" class:hidden={showMap}>
|
||||||
<TrailList
|
<TrailList trails={$list.expand?.trails ?? []}></TrailList>
|
||||||
bind:filter
|
|
||||||
trails={$list.expand?.trails ?? []}
|
|
||||||
on:update={async () => await lists_index()}
|
|
||||||
></TrailList>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ListModal bind:openModal={openListModal} on:save={saveList}></ListModal>
|
<ListModal bind:openModal={openListModal} on:save={saveList}></ListModal>
|
||||||
|
|||||||
@@ -1,25 +1,6 @@
|
|||||||
import type { TrailFilter } from "$lib/models/trail";
|
|
||||||
import { lists_index } from "$lib/stores/list_store";
|
import { lists_index } from "$lib/stores/list_store";
|
||||||
import type { Load } from "@sveltejs/kit";
|
import type { Load } from "@sveltejs/kit";
|
||||||
|
|
||||||
export const load: Load = async ({ params, fetch }) => {
|
export const load: Load = async ({ params, fetch, url }) => {
|
||||||
const filter: TrailFilter = {
|
|
||||||
q: "",
|
|
||||||
category: [],
|
|
||||||
difficulty: ["easy", "moderate", "difficult"],
|
|
||||||
near: {
|
|
||||||
radius: 2000,
|
|
||||||
},
|
|
||||||
distanceMin: 0,
|
|
||||||
distanceMax: 20000,
|
|
||||||
distanceLimit: 20000,
|
|
||||||
elevationGainMin: 0,
|
|
||||||
elevationGainMax: 4000,
|
|
||||||
elevationGainLimit: 4000,
|
|
||||||
sort: "created",
|
|
||||||
sortOrder: "+",
|
|
||||||
};
|
|
||||||
await lists_index(undefined, fetch);
|
await lists_index(undefined, fetch);
|
||||||
|
|
||||||
return {filter};
|
|
||||||
};
|
};
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deleteTrail(trail: Trail) {
|
function deleteTrail(trail: Trail) {
|
||||||
$form.trails?.filter((id) => id !== trail.id);
|
$form.trails = $form.trails?.filter((id) => id !== trail.id);
|
||||||
$form.expand!.trails = $form.expand!.trails.filter(
|
$form.expand!.trails = $form.expand!.trails.filter(
|
||||||
(t) => t.id !== trail.id,
|
(t) => t.id !== trail.id,
|
||||||
);
|
);
|
||||||
@@ -185,7 +185,6 @@
|
|||||||
<form
|
<form
|
||||||
id="list-form"
|
id="list-form"
|
||||||
class="flex flex-col gap-4 px-8 order-1 md:order-none mt-8 md:mt-0 overflow-y-scroll"
|
class="flex flex-col gap-4 px-8 order-1 md:order-none mt-8 md:mt-0 overflow-y-scroll"
|
||||||
style="max-height: calc(100vh - 124px)"
|
|
||||||
on:submit={handleSubmit}
|
on:submit={handleSubmit}
|
||||||
>
|
>
|
||||||
<h2 class="text-2xl font-semibold">
|
<h2 class="text-2xl font-semibold">
|
||||||
@@ -338,7 +337,7 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
@media only screen and (min-width: 768px) {
|
@media only screen and (min-width: 768px) {
|
||||||
#trail-map {
|
#trail-map, #list-form {
|
||||||
height: calc(100vh - 124px);
|
height: calc(100vh - 124px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,7 +217,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class:hidden={!showMap && browser && window.innerWidth < 768}>
|
<div id="trail-map" class:hidden={!showMap && browser && window.innerWidth < 768}>
|
||||||
<MapWithElevationMultiple
|
<MapWithElevationMultiple
|
||||||
on:moveend={handleMapMove}
|
on:moveend={handleMapMove}
|
||||||
on:init={handleMapInit}
|
on:init={handleMapInit}
|
||||||
@@ -230,11 +230,11 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#map {
|
#trail-map {
|
||||||
height: calc(100vh - 180px);
|
height: calc(100vh - 180px);
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 768px) {
|
@media only screen and (min-width: 768px) {
|
||||||
#map,
|
#trail-map,
|
||||||
#trail-list {
|
#trail-list {
|
||||||
height: calc(100vh - 124px);
|
height: calc(100vh - 124px);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user