mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-02 16:52:31 +00:00
finished embedding
This commit is contained in:
@@ -14,7 +14,9 @@
|
|||||||
import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public';
|
import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public';
|
||||||
|
|
||||||
export let accessToken = PUBLIC_MAPBOX_TOKEN;
|
export let accessToken = PUBLIC_MAPBOX_TOKEN;
|
||||||
|
export let geolocate = true;
|
||||||
export let geocoder = true;
|
export let geocoder = true;
|
||||||
|
export let hash = true;
|
||||||
|
|
||||||
mapboxgl.accessToken = accessToken;
|
mapboxgl.accessToken = accessToken;
|
||||||
|
|
||||||
@@ -35,7 +37,7 @@
|
|||||||
container: 'map',
|
container: 'map',
|
||||||
style: { version: 8, sources: {}, layers: [] },
|
style: { version: 8, sources: {}, layers: [] },
|
||||||
projection: { name: 'mercator' },
|
projection: { name: 'mercator' },
|
||||||
hash: true,
|
hash: hash,
|
||||||
language: get(locale),
|
language: get(locale),
|
||||||
attributionControl: false,
|
attributionControl: false,
|
||||||
logoPosition: 'bottom-right',
|
logoPosition: 'bottom-right',
|
||||||
@@ -66,16 +68,18 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
newMap.addControl(
|
if (geolocate) {
|
||||||
new mapboxgl.GeolocateControl({
|
newMap.addControl(
|
||||||
positionOptions: {
|
new mapboxgl.GeolocateControl({
|
||||||
enableHighAccuracy: true
|
positionOptions: {
|
||||||
},
|
enableHighAccuracy: true
|
||||||
fitBoundsOptions,
|
},
|
||||||
trackUserLocation: true,
|
fitBoundsOptions,
|
||||||
showUserHeading: true
|
trackUserLocation: true,
|
||||||
})
|
showUserHeading: true
|
||||||
);
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
newMap.addControl(scaleControl);
|
newMap.addControl(scaleControl);
|
||||||
|
|
||||||
|
@@ -74,6 +74,11 @@
|
|||||||
@apply hover:underline;
|
@apply hover:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.markdown li > a) {
|
||||||
|
@apply text-blue-500;
|
||||||
|
@apply hover:underline;
|
||||||
|
}
|
||||||
|
|
||||||
:global(.markdown kbd) {
|
:global(.markdown kbd) {
|
||||||
@apply p-1;
|
@apply p-1;
|
||||||
@apply rounded-md;
|
@apply rounded-md;
|
||||||
|
@@ -9,3 +9,10 @@
|
|||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
div :global(a) {
|
||||||
|
@apply text-blue-500;
|
||||||
|
@apply hover:underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@@ -18,14 +18,25 @@
|
|||||||
|
|
||||||
$embedding = true;
|
$embedding = true;
|
||||||
|
|
||||||
const { currentBasemap, distanceUnits, velocityUnits, temperatureUnits, fileOrder } = settings;
|
const {
|
||||||
|
currentBasemap,
|
||||||
|
distanceUnits,
|
||||||
|
velocityUnits,
|
||||||
|
temperatureUnits,
|
||||||
|
fileOrder,
|
||||||
|
distanceMarkers,
|
||||||
|
directionMarkers
|
||||||
|
} = settings;
|
||||||
|
|
||||||
export let options: EmbeddingOptions;
|
export let options: EmbeddingOptions;
|
||||||
|
export let hash: string;
|
||||||
|
|
||||||
let prevUnits = {
|
let prevSettings = {
|
||||||
distance: '',
|
distanceMarkers: false,
|
||||||
velocity: '',
|
directionMarkers: false,
|
||||||
temperature: ''
|
distanceUnits: 'metric',
|
||||||
|
velocityUnits: 'speed',
|
||||||
|
temperatureUnits: 'celsius'
|
||||||
};
|
};
|
||||||
|
|
||||||
function applyOptions() {
|
function applyOptions() {
|
||||||
@@ -97,29 +108,39 @@
|
|||||||
return $selection;
|
return $selection;
|
||||||
});
|
});
|
||||||
|
|
||||||
map.subscribe(($map) => {
|
if (hash.length === 0) {
|
||||||
if ($map) {
|
map.subscribe(($map) => {
|
||||||
$map.fitBounds(
|
if ($map) {
|
||||||
[
|
$map.fitBounds(
|
||||||
bounds.southWest.lon,
|
[
|
||||||
bounds.southWest.lat,
|
bounds.southWest.lon,
|
||||||
bounds.northEast.lon,
|
bounds.southWest.lat,
|
||||||
bounds.northEast.lat
|
bounds.northEast.lon,
|
||||||
],
|
bounds.northEast.lat
|
||||||
{
|
],
|
||||||
padding: 80,
|
{
|
||||||
linear: true,
|
padding: 80,
|
||||||
easing: () => 1
|
linear: true,
|
||||||
}
|
easing: () => 1
|
||||||
);
|
}
|
||||||
}
|
);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.basemap !== $currentBasemap && allowedEmbeddingBasemaps.includes(options.basemap)) {
|
if (options.basemap !== $currentBasemap && allowedEmbeddingBasemaps.includes(options.basemap)) {
|
||||||
$currentBasemap = options.basemap;
|
$currentBasemap = options.basemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.distanceMarkers !== $distanceMarkers) {
|
||||||
|
$distanceMarkers = options.distanceMarkers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.directionMarkers !== $directionMarkers) {
|
||||||
|
$directionMarkers = options.directionMarkers;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.distanceUnits !== $distanceUnits) {
|
if (options.distanceUnits !== $distanceUnits) {
|
||||||
$distanceUnits = options.distanceUnits;
|
$distanceUnits = options.distanceUnits;
|
||||||
}
|
}
|
||||||
@@ -134,9 +155,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
prevUnits.distance = $distanceUnits;
|
prevSettings.distanceMarkers = $distanceMarkers;
|
||||||
prevUnits.velocity = $velocityUnits;
|
prevSettings.directionMarkers = $directionMarkers;
|
||||||
prevUnits.temperature = $temperatureUnits;
|
prevSettings.distanceUnits = $distanceUnits;
|
||||||
|
prevSettings.velocityUnits = $velocityUnits;
|
||||||
|
prevSettings.temperatureUnits = $temperatureUnits;
|
||||||
});
|
});
|
||||||
|
|
||||||
$: if (options) {
|
$: if (options) {
|
||||||
@@ -144,16 +167,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if ($distanceUnits !== prevUnits.distance) {
|
if ($distanceMarkers !== prevSettings.distanceMarkers) {
|
||||||
$distanceUnits = prevUnits.distance;
|
$distanceMarkers = prevSettings.distanceMarkers;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($velocityUnits !== prevUnits.velocity) {
|
if ($directionMarkers !== prevSettings.directionMarkers) {
|
||||||
$velocityUnits = prevUnits.velocity;
|
$directionMarkers = prevSettings.directionMarkers;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($temperatureUnits !== prevUnits.temperature) {
|
if ($distanceUnits !== prevSettings.distanceUnits) {
|
||||||
$temperatureUnits = prevUnits.temperature;
|
$distanceUnits = prevSettings.distanceUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($velocityUnits !== prevSettings.velocityUnits) {
|
||||||
|
$velocityUnits = prevSettings.velocityUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($temperatureUnits !== prevSettings.temperatureUnits) {
|
||||||
|
$temperatureUnits = prevSettings.temperatureUnits;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileOrder = $fileOrder.filter((id) => !id.includes('embed'));
|
$fileOrder = $fileOrder.filter((id) => !id.includes('embed'));
|
||||||
@@ -166,6 +197,8 @@
|
|||||||
class="h-full {$fileObservers.size > 1 ? 'horizontal' : ''}"
|
class="h-full {$fileObservers.size > 1 ? 'horizontal' : ''}"
|
||||||
accessToken={options.token}
|
accessToken={options.token}
|
||||||
geocoder={false}
|
geocoder={false}
|
||||||
|
geolocate={false}
|
||||||
|
hash={false}
|
||||||
/>
|
/>
|
||||||
<OpenIn bind:files={options.files} />
|
<OpenIn bind:files={options.files} />
|
||||||
<LayerControl />
|
<LayerControl />
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import { basemaps } from "$lib/assets/layers";
|
||||||
|
|
||||||
export type EmbeddingOptions = {
|
export type EmbeddingOptions = {
|
||||||
token: string;
|
token: string;
|
||||||
files: string[];
|
files: string[];
|
||||||
@@ -13,6 +15,8 @@ export type EmbeddingOptions = {
|
|||||||
temp: boolean,
|
temp: boolean,
|
||||||
power: boolean,
|
power: boolean,
|
||||||
},
|
},
|
||||||
|
distanceMarkers: boolean,
|
||||||
|
directionMarkers: boolean,
|
||||||
distanceUnits: 'metric' | 'imperial',
|
distanceUnits: 'metric' | 'imperial',
|
||||||
velocityUnits: 'speed' | 'pace',
|
velocityUnits: 'speed' | 'pace',
|
||||||
temperatureUnits: 'celsius' | 'fahrenheit',
|
temperatureUnits: 'celsius' | 'fahrenheit',
|
||||||
@@ -33,6 +37,8 @@ export const defaultEmbeddingOptions = {
|
|||||||
temp: false,
|
temp: false,
|
||||||
power: false,
|
power: false,
|
||||||
},
|
},
|
||||||
|
distanceMarkers: false,
|
||||||
|
directionMarkers: false,
|
||||||
distanceUnits: 'metric',
|
distanceUnits: 'metric',
|
||||||
velocityUnits: 'speed',
|
velocityUnits: 'speed',
|
||||||
temperatureUnits: 'celsius',
|
temperatureUnits: 'celsius',
|
||||||
@@ -57,7 +63,4 @@ export function getCleanedEmbeddingOptions(options: any, defaultOptions: any = d
|
|||||||
return cleanedOptions;
|
return cleanedOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const allowedEmbeddingBasemaps = [
|
export const allowedEmbeddingBasemaps = Object.keys(basemaps).filter(basemap => !['ordnanceSurvey'].includes(basemap));
|
||||||
'mapboxOutdoors',
|
|
||||||
'mapboxSatellite',
|
|
||||||
];
|
|
@@ -5,7 +5,16 @@
|
|||||||
import * as Select from '$lib/components/ui/select';
|
import * as Select from '$lib/components/ui/select';
|
||||||
import { Checkbox } from '$lib/components/ui/checkbox';
|
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||||
import * as RadioGroup from '$lib/components/ui/radio-group';
|
import * as RadioGroup from '$lib/components/ui/radio-group';
|
||||||
import { Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import {
|
||||||
|
Zap,
|
||||||
|
HeartPulse,
|
||||||
|
Orbit,
|
||||||
|
Thermometer,
|
||||||
|
SquareActivity,
|
||||||
|
Coins,
|
||||||
|
Milestone,
|
||||||
|
Video
|
||||||
|
} from 'lucide-svelte';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import {
|
import {
|
||||||
allowedEmbeddingBasemaps,
|
allowedEmbeddingBasemaps,
|
||||||
@@ -35,11 +44,11 @@
|
|||||||
|
|
||||||
let manualCamera = false;
|
let manualCamera = false;
|
||||||
|
|
||||||
let zoom = 0;
|
let zoom = '0';
|
||||||
let lat = 0;
|
let lat = '0';
|
||||||
let lon = 0;
|
let lon = '0';
|
||||||
let bearing = 0;
|
let bearing = '0';
|
||||||
let pitch = 0;
|
let pitch = '0';
|
||||||
|
|
||||||
$: hash = manualCamera ? `#${zoom}/${lat}/${lon}/${bearing}/${pitch}` : '';
|
$: hash = manualCamera ? `#${zoom}/${lat}/${lon}/${bearing}/${pitch}` : '';
|
||||||
|
|
||||||
@@ -58,6 +67,21 @@
|
|||||||
$: if (options.elevation.height || options.elevation.show) {
|
$: if (options.elevation.height || options.elevation.show) {
|
||||||
resizeMap();
|
resizeMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateCamera() {
|
||||||
|
if ($map) {
|
||||||
|
let center = $map.getCenter();
|
||||||
|
lat = center.lat.toFixed(4);
|
||||||
|
lon = center.lng.toFixed(4);
|
||||||
|
zoom = $map.getZoom().toFixed(2);
|
||||||
|
bearing = $map.getBearing().toFixed(1);
|
||||||
|
pitch = $map.getPitch().toFixed(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if ($map) {
|
||||||
|
$map.on('moveend', updateCamera);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card.Root>
|
<Card.Root>
|
||||||
@@ -164,6 +188,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<div class="flex flex-row items-center gap-2">
|
||||||
|
<Checkbox id="distance-markers" bind:checked={options.distanceMarkers} />
|
||||||
|
<Label for="distance-markers" class="flex flex-row items-center gap-1">
|
||||||
|
<Coins size="16" />
|
||||||
|
{$_('menu.distance_markers')}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row items-center gap-2">
|
||||||
|
<Checkbox id="direction-markers" bind:checked={options.directionMarkers} />
|
||||||
|
<Label for="direction-markers" class="flex flex-row items-center gap-1">
|
||||||
|
<Milestone size="16" />
|
||||||
|
{$_('menu.direction_markers')}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
<div class="flex flex-row flex-wrap justify-between gap-3">
|
<div class="flex flex-row flex-wrap justify-between gap-3">
|
||||||
<Label class="flex flex-col items-start gap-2">
|
<Label class="flex flex-col items-start gap-2">
|
||||||
{$_('menu.distance_units')}
|
{$_('menu.distance_units')}
|
||||||
@@ -205,18 +243,52 @@
|
|||||||
</RadioGroup.Root>
|
</RadioGroup.Root>
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col gap-3 p-3 border rounded-md">
|
||||||
|
<div class="flex flex-row items-center gap-2">
|
||||||
|
<Checkbox id="manual-camera" bind:checked={manualCamera} />
|
||||||
|
<Label for="manual-camera" class="flex flex-row items-center gap-1">
|
||||||
|
<Video size="16" />
|
||||||
|
{$_('embedding.manual_camera')}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-muted-foreground">
|
||||||
|
{$_('embedding.manual_camera_description')}
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-row flex-wrap items-center gap-6">
|
||||||
|
<Label class="flex flex-col gap-1">
|
||||||
|
<span>{$_('embedding.latitude')}</span>
|
||||||
|
<span>{lat}</span>
|
||||||
|
</Label>
|
||||||
|
<Label class="flex flex-col gap-1">
|
||||||
|
<span>{$_('embedding.longitude')}</span>
|
||||||
|
<span>{lon}</span>
|
||||||
|
</Label>
|
||||||
|
<Label class="flex flex-col gap-1">
|
||||||
|
<span>{$_('embedding.zoom')}</span>
|
||||||
|
<span>{zoom}</span>
|
||||||
|
</Label>
|
||||||
|
<Label class="flex flex-col gap-1">
|
||||||
|
<span>{$_('embedding.bearing')}</span>
|
||||||
|
<span>{bearing}</span>
|
||||||
|
</Label>
|
||||||
|
<Label class="flex flex-col gap-1">
|
||||||
|
<span>{$_('embedding.pitch')}</span>
|
||||||
|
<span>{pitch}</span>
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Label>
|
<Label>
|
||||||
{$_('embedding.preview')}
|
{$_('embedding.preview')}
|
||||||
</Label>
|
</Label>
|
||||||
<div class="relative h-[600px]">
|
<div class="relative h-[600px]">
|
||||||
<Embedding bind:options={iframeOptions} />
|
<Embedding bind:options={iframeOptions} bind:hash />
|
||||||
</div>
|
</div>
|
||||||
<Label>
|
<Label>
|
||||||
{$_('embedding.code')}
|
{$_('embedding.code')}
|
||||||
</Label>
|
</Label>
|
||||||
<pre class="bg-primary text-primary-foreground p-3 rounded-md whitespace-normal break-all">
|
<pre class="bg-primary text-primary-foreground p-3 rounded-md whitespace-normal break-all">
|
||||||
<code class="language-html">
|
<code class="language-html">
|
||||||
{`<iframe src="https://gpx.studio${base}/embed?options=${encodeURIComponent(JSON.stringify(getCleanedEmbeddingOptions(options)))}${hash}" width="100%" height="600px" frameborder="0" />`}
|
{`<iframe src="https://gpx.studio${base}/embed?options=${encodeURIComponent(JSON.stringify(getCleanedEmbeddingOptions(options)))}${hash}" width="100%" height="600px" frameborder="0" style="outline: none;"/>`}
|
||||||
</code>
|
</code>
|
||||||
</pre>
|
</pre>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="absolute top-0 flex-wrap h-fit bg-background font-semibold rounded-md py-1 px-2 gap-1.5 xs:text-base mt-2.5 ml-2.5 mr-12"
|
class="absolute top-0 flex-wrap h-fit bg-background font-semibold rounded-md py-1 px-2 gap-1.5 xs:text-base mt-2.5 ml-2.5 mr-12"
|
||||||
href="{getURLForLanguage($locale, '/embed')}?files={encodeURIComponent(JSON.stringify(files))}"
|
href="{getURLForLanguage($locale, '/app')}?files={encodeURIComponent(JSON.stringify(files))}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
{$_('menu.open_in')}
|
{$_('menu.open_in')}
|
||||||
|
@@ -9,8 +9,16 @@ title: Integration
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
<DocsNote>
|
You can use **gpx.studio** to create maps showing your GPX files and embed them in your website.
|
||||||
This section is a work in progress.
|
|
||||||
|
All you need is:
|
||||||
|
1. A <a href="https://account.mapbox.com/auth/signup" target="_blank">Mapbox access token</a> to load the map, and
|
||||||
|
1. GPX files hosted on your server or a public URL.
|
||||||
|
|
||||||
|
You can then play with the configurator below to customize your map and generate the corresponding HTML code.
|
||||||
|
|
||||||
|
<DocsNote type="warning">
|
||||||
|
You will need to set up <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">Cross-Origin Resource Sharing (CORS)</a> headers on your server to allow <b>gpx.studio</b> to load your GPX files.
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
<EmbeddingPlaygound />
|
<EmbeddingPlaygound />
|
||||||
|
@@ -25,7 +25,7 @@ You can use the search bar to look for an address and navigate to it on the map.
|
|||||||
The locate button will center the map on your current location.
|
The locate button will center the map on your current location.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
This only works if you have allowed your browser and the website to access your location.
|
This only works if you have allowed your browser and <b>gpx.studio</b> to access your location.
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Street view
|
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Street view
|
||||||
|
@@ -44,5 +44,5 @@ Open the export dialog to save the currently selected files to your computer.
|
|||||||
Open the export dialog to save all files to your computer.
|
Open the export dialog to save all files to your computer.
|
||||||
|
|
||||||
<DocsNote type="warning">
|
<DocsNote type="warning">
|
||||||
If your download does not start after clicking the download button, please check your browser settings to allow downloads from this website.
|
If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
|
||||||
</DocsNote>
|
</DocsNote>
|
@@ -20,5 +20,5 @@ Applying the tool to a file containing multiple tracks will create a new file fo
|
|||||||
Similarly, applying the tool to a track containing multiple segments will create (in the same file) a new track for each of the segments it contains.
|
Similarly, applying the tool to a track containing multiple segments will create (in the same file) a new track for each of the segments it contains.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
When extracting the tracks of a file containing [points of interest](../gpx), the tool will automatically assign each point of interest to the track it is closest to.
|
When extracting the tracks of a file containing <a href="../gpx">points of interest</a>, the tool will automatically assign each point of interest to the track it is closest to.
|
||||||
</DocsNote>
|
</DocsNote>
|
@@ -382,9 +382,9 @@
|
|||||||
"show_controls": "Show controls",
|
"show_controls": "Show controls",
|
||||||
"manual_camera": "Manual camera",
|
"manual_camera": "Manual camera",
|
||||||
"manual_camera_description": "You can move the map below to adjust the camera position.",
|
"manual_camera_description": "You can move the map below to adjust the camera position.",
|
||||||
"zoom": "Zoom",
|
|
||||||
"latitude": "Latitude",
|
"latitude": "Latitude",
|
||||||
"longitude": "Longitude",
|
"longitude": "Longitude",
|
||||||
|
"zoom": "Zoom",
|
||||||
"pitch": "Pitch",
|
"pitch": "Pitch",
|
||||||
"bearing": "Bearing",
|
"bearing": "Bearing",
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
|
@@ -23,5 +23,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if embeddingOptions}
|
{#if embeddingOptions}
|
||||||
<Embedding options={embeddingOptions} />
|
<Embedding options={embeddingOptions} hash={$page.url.hash} />
|
||||||
{/if}
|
{/if}
|
||||||
|
Reference in New Issue
Block a user