adds list link sharing
This commit is contained in:
@@ -76,7 +76,7 @@
|
||||
<Dropdown items={dropdownItems} on:change></Dropdown>
|
||||
{/if}
|
||||
</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
|
||||
><i class="fa fa-left-right mr-2"></i>{formatDistance(
|
||||
cumulativeDistance,
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
import { TrailShare } from "$lib/models/trail_share";
|
||||
import type { User } from "$lib/models/user";
|
||||
import {
|
||||
list_share_create,
|
||||
list_share_create,
|
||||
list_share_delete,
|
||||
list_share_index,
|
||||
list_share_update,
|
||||
shares,
|
||||
shares
|
||||
} from "$lib/stores/list_share_store";
|
||||
import { lists } from "$lib/stores/list_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import {
|
||||
trail_share_create,
|
||||
@@ -25,8 +26,6 @@
|
||||
import Search, { type SearchItem } from "../base/search.svelte";
|
||||
import type { SelectItem } 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;
|
||||
export let closeModal: (() => void) | undefined = undefined;
|
||||
@@ -72,7 +71,7 @@
|
||||
}
|
||||
|
||||
function copyURLToClipboard() {
|
||||
navigator.clipboard.writeText(window.location.href);
|
||||
navigator.clipboard.writeText(window.location.href.split('?')[0] + '?list=' + list.id);
|
||||
|
||||
copyButtonText = $_("link-copied");
|
||||
setTimeout(() => (copyButtonText = $_("copy-link")), 3000);
|
||||
@@ -135,6 +134,7 @@
|
||||
trails: list.expand?.trails ?? [],
|
||||
list_share_via_list: fetchedShares,
|
||||
};
|
||||
lists.set($lists)
|
||||
sharesLoading = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
(gpxData.length != gpxGroup._tracks.length ||
|
||||
gpxGroup?._tracks[0] !== gpxData[0])
|
||||
) {
|
||||
if (gpxData.length == 0) {
|
||||
map?.setView([0, 0], 4);
|
||||
}
|
||||
// if (gpxData.length == 0) {
|
||||
// map?.setView([0, 0], 4);
|
||||
// }
|
||||
gpxGroup._elevation.updateOptions({
|
||||
autofitBounds: options.autofitBounds ?? true,
|
||||
});
|
||||
@@ -162,7 +162,7 @@
|
||||
closeBtn: false,
|
||||
followMarker: true,
|
||||
autofitBounds: true,
|
||||
imperial: $page.data.settings?.unit == "imperial" ?? false,
|
||||
imperial: $page.data.settings?.unit == "imperial",
|
||||
reverseCoords: false,
|
||||
acceleration: false,
|
||||
slope: true,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import TrailCard from "./trail_card.svelte";
|
||||
import TrailListItem from "./trail_list_item.svelte";
|
||||
|
||||
export let filter: TrailFilter;
|
||||
export let filter: TrailFilter | null = null;
|
||||
export let trails: Trail[];
|
||||
export let pagination: { page: number; totalPages: number } = {
|
||||
page: 1,
|
||||
@@ -41,10 +41,10 @@
|
||||
if (storedDisplayOption) {
|
||||
selectedDisplayOption = storedDisplayOption;
|
||||
}
|
||||
if (storedSort) {
|
||||
if (filter && storedSort) {
|
||||
filter.sort = storedSort as typeof filter.sort;
|
||||
}
|
||||
if (storedSortOrder) {
|
||||
if (filter && storedSortOrder) {
|
||||
filter.sortOrder = storedSortOrder as typeof filter.sortOrder;
|
||||
}
|
||||
if (storedSort || storedSortOrder) {
|
||||
@@ -57,11 +57,17 @@
|
||||
}
|
||||
|
||||
function setSort() {
|
||||
if(!filter) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("sort", filter.sort);
|
||||
dispatch("update", filter);
|
||||
}
|
||||
|
||||
function setSortOrder() {
|
||||
if(!filter) {
|
||||
return;
|
||||
}
|
||||
if (filter.sortOrder === "+") {
|
||||
filter.sortOrder = "-";
|
||||
} else {
|
||||
@@ -81,23 +87,25 @@
|
||||
on:pagination
|
||||
></Pagination>
|
||||
</div>
|
||||
<div class="shrink-0">
|
||||
<p class="text-sm text-gray-500 pb-2">{$_("sort")}</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<Select
|
||||
bind:value={filter.sort}
|
||||
items={sortOptions}
|
||||
on:change={setSort}
|
||||
></Select>
|
||||
<button
|
||||
id="sort-order-btn"
|
||||
class="btn-icon"
|
||||
class:rotated={filter.sortOrder == "-"}
|
||||
on:click={() => setSortOrder()}
|
||||
><i class="fa fa-arrow-up"></i></button
|
||||
>
|
||||
{#if filter}
|
||||
<div class="shrink-0">
|
||||
<p class="text-sm text-gray-500 pb-2">{$_("sort")}</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<Select
|
||||
bind:value={filter.sort}
|
||||
items={sortOptions}
|
||||
on:change={setSort}
|
||||
></Select>
|
||||
<button
|
||||
id="sort-order-btn"
|
||||
class="btn-icon"
|
||||
class:rotated={filter.sortOrder == "-"}
|
||||
on:click={() => setSortOrder()}
|
||||
><i class="fa fa-arrow-up"></i></button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="shrink-0">
|
||||
<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 {
|
||||
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'
|
||||
});
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
||||
Object.assign(this.options, options)
|
||||
if (!this.options.showStartEnd) {
|
||||
this._circleMarkers.remove();
|
||||
} else if (this._data.length) {
|
||||
} else if (this._data.length && this._map) {
|
||||
this._circleMarkers.addTo(this._map);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -24,19 +24,27 @@
|
||||
import "leaflet.awesome-markers/dist/leaflet.awesome-markers.css";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
|
||||
import { tick } from "svelte";
|
||||
import { onMount, tick } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let openListModal: () => void;
|
||||
let openConfirmModal: () => void;
|
||||
let openShareModal: () => void;
|
||||
|
||||
let filter: TrailFilter = $page.data.filter;
|
||||
let listToBeDeleted: List | null = null;
|
||||
|
||||
let map: Map;
|
||||
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() {
|
||||
showMap = !showMap;
|
||||
if (showMap) {
|
||||
@@ -99,7 +107,7 @@
|
||||
</svelte:head>
|
||||
<main class="grid grid-cols-1 md:grid-cols-[430px_1fr] gap-4 lg:gap-4 mx-4">
|
||||
<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
|
||||
class="flex gap-x-4 items-center justify-between p-4 bg-background z-50 rounded-xl"
|
||||
@@ -139,11 +147,7 @@
|
||||
></MapWithElevationMultiple>
|
||||
</div>
|
||||
<div class="min-w-0" class:hidden={showMap}>
|
||||
<TrailList
|
||||
bind:filter
|
||||
trails={$list.expand?.trails ?? []}
|
||||
on:update={async () => await lists_index()}
|
||||
></TrailList>
|
||||
<TrailList trails={$list.expand?.trails ?? []}></TrailList>
|
||||
</div>
|
||||
|
||||
<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 type { Load } from "@sveltejs/kit";
|
||||
|
||||
export const load: Load = async ({ params, fetch }) => {
|
||||
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: "+",
|
||||
};
|
||||
export const load: Load = async ({ params, fetch, url }) => {
|
||||
await lists_index(undefined, fetch);
|
||||
|
||||
return {filter};
|
||||
};
|
||||
@@ -130,10 +130,10 @@
|
||||
}
|
||||
|
||||
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(
|
||||
(t) => t.id !== trail.id,
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
async function findNewTrailShares() {
|
||||
@@ -185,7 +185,6 @@
|
||||
<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"
|
||||
style="max-height: calc(100vh - 124px)"
|
||||
on:submit={handleSubmit}
|
||||
>
|
||||
<h2 class="text-2xl font-semibold">
|
||||
@@ -338,7 +337,7 @@
|
||||
|
||||
<style>
|
||||
@media only screen and (min-width: 768px) {
|
||||
#trail-map {
|
||||
#trail-map, #list-form {
|
||||
height: calc(100vh - 124px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
<div class:hidden={!showMap && browser && window.innerWidth < 768}>
|
||||
<div id="trail-map" class:hidden={!showMap && browser && window.innerWidth < 768}>
|
||||
<MapWithElevationMultiple
|
||||
on:moveend={handleMapMove}
|
||||
on:init={handleMapInit}
|
||||
@@ -230,11 +230,11 @@
|
||||
</main>
|
||||
|
||||
<style>
|
||||
#map {
|
||||
#trail-map {
|
||||
height: calc(100vh - 180px);
|
||||
}
|
||||
@media only screen and (min-width: 768px) {
|
||||
#map,
|
||||
#trail-map,
|
||||
#trail-list {
|
||||
height: calc(100vh - 124px);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user