aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-10-16 15:34:26 -0700
committerAdam Soltys <[email protected]>2023-10-16 15:34:26 -0700
commit829c2efb9c4415c64466988f1e189184ffb88478 (patch)
tree23f9e5fd83be3d4ee3943d254e4d3d2ce194819a /src/components
parent16475fffdb0d20a2933cfaf6922afc7c137bb7fe (diff)
parent0212fe0032eb0c5d6bfb74ebaab42543b73d6d6b (diff)
downloadcoinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.tar.gz
coinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.zip
Merge branch 'master' into swapee
Diffstat (limited to 'src/components')
-rw-r--r--src/components/AppHeader.svelte4
-rw-r--r--src/components/Balance.svelte4
-rw-r--r--src/components/Code.svelte4
-rw-r--r--src/components/Footer.svelte2
-rw-r--r--src/components/LocationsMap.svelte268
-rw-r--r--src/components/RegisterOrLogin.svelte6
6 files changed, 114 insertions, 174 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index 5f6f02a5..91d31a56 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -17,6 +17,8 @@
menuButtons = [
{ key: 'nav.settings', icon: 'settings', href: `/${user.username}/settings` },
{ key: 'nav.support', icon: 'support', href: `/support` },
+ { key: 'nav.map', icon: 'map', href: `/${user.username}/map` },
+ { key: 'nav.merch', icon: 'shirt', href: `https://coinosmerch.com` },
{ key: 'nav.signOut', icon: 'logout', href: `/logout` }
];
@@ -119,7 +121,7 @@
</OutClick>
</div>
{:else}
- <a href={`/login?redirect=${$page.url.pathname}`}>
+ <a href={`/login?redirect=${$page.url.pathname}`}>
<button class="bg-white px-5 py-2 rounded-xl font-semibold text-sm"
>{$t('nav.signIn')}</button
>
diff --git a/src/components/Balance.svelte b/src/components/Balance.svelte
index 96edf630..0e4f2ec2 100644
--- a/src/components/Balance.svelte
+++ b/src/components/Balance.svelte
@@ -9,14 +9,14 @@
</script>
{#if show && user.haspin && $pin?.length !== 6}
- <Pin cancel={() => (show = false)} />
+ <Pin cancel={() => (show = false)} />
{/if}
<div class="space-y-2">
{#if user.haspin && !$pin}
<button
class="text-sm md:text-lg rounded-full border py-2 px-4 hover:opacity-80 min-w-[72px] bg-black text-white"
- on:click={() => (show = true)}>{$t('user.showBalance')}</button
+ on:click={() => (show = true)}>{$t('user.showBalance')}</button
>
{:else}
<div class="text-5xl font-bold tabular-nums">
diff --git a/src/components/Code.svelte b/src/components/Code.svelte
index dd0cecf2..ffca98a4 100644
--- a/src/components/Code.svelte
+++ b/src/components/Code.svelte
@@ -9,9 +9,7 @@
<div class="overflow-x-scroll max-w-full scrollbar-hide">
<div class="break-all min-w-[800px]">{samples[sample]}</div>
</div>
- <button
- class="ml-auto my-auto invert opacity-90"
- on:click={() => copy(samples[sample])}
+ <button class="ml-auto my-auto invert opacity-90" on:click={() => copy(samples[sample])}
><Icon icon="copy" style="w-10 max-w-none" /></button
>
</div>
diff --git a/src/components/Footer.svelte b/src/components/Footer.svelte
index 7caaccc6..b1d50017 100644
--- a/src/components/Footer.svelte
+++ b/src/components/Footer.svelte
@@ -10,7 +10,7 @@
const companyLinks = [
{ url: '/docs', titleID: 'documentation' },
- { url: '/support', titleID: 'support' },
+ { url: '/support', titleID: 'support' }
];
</script>
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte
index 277d75a6..7876659a 100644
--- a/src/components/LocationsMap.svelte
+++ b/src/components/LocationsMap.svelte
@@ -1,205 +1,141 @@
<script>
- export let locations;
-
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
-
import html2canvas from 'html2canvas';
- function captureHighResMap(mapElement, scale = 2) {
- // Backup original size
- let originalWidth = mapElement.offsetWidth;
- let originalHeight = mapElement.offsetHeight;
-
- // Scale the map element
- mapElement.style.transform = `scale(${scale})`;
- mapElement.style.transformOrigin = 'top left';
- mapElement.style.width = originalWidth * scale + 'px';
- mapElement.style.height = originalHeight * scale + 'px';
-
- return html2canvas(mapElement, {
- width: originalWidth * scale,
- height: originalHeight * scale,
- scale: scale
- }).then((canvas) => {
- // Restore the original size
- mapElement.style.transform = '';
- mapElement.style.width = originalWidth + 'px';
- mapElement.style.height = originalHeight + 'px';
-
- return canvas;
- });
- }
+ import 'maplibre-gl/dist/maplibre-gl.css';
- let mapElement;
+ export let locations;
let map;
+ let mapContainer;
+ let markers = [];
- onMount(async () => {
- if (browser) {
- const L = await import('leaflet');
-
- map = L.map(mapElement, {
- zoomSnap: 0,
- attributionControl: false,
- }).setView([49.26, -123.05], 12);
-
-
- const myCustomColour = '#F7931A';
+ let checkAddress = (location) => {
+ if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) {
+ return `${
+ location['addr:housenumber'] + ' ' + location['addr:street'] + ', ' + location['addr:city']
+ }`;
+ } else if (location['addr:street'] && location['addr:city']) {
+ return `${location['addr:street'] + ', ' + location['addr:city']}`;
+ } else if (location['addr:city']) {
+ return `${location['addr:city']}`;
+ } else {
+ return '';
+ }
+ };
- const markerHtmlStyles = `
- background-color: ${myCustomColour};
- width: 1.2rem;
- height: 1.2rem;
- display: block;
- position: relative;
- border-radius: 100% 100% 0;
- transform: rotate(45deg);
- opacity: 0.9;
- border: 1px solid #666`;
+ function updateLabelVisibility() {
+ if (!map) return;
+ let zoom = map.getZoom();
+ let bounds = map.getBounds();
- const icon = L.divIcon({
- className: 'my-custom-pin',
- iconAnchor: [0, 24],
- labelAnchor: [-6, 0],
- popupAnchor: [0, -36],
- html: `<span style="${markerHtmlStyles}" />`
- });
+ for (let marker of markers) {
+ let isInView = bounds.contains(marker.getLngLat());
+ let popup = marker.getPopup();
+ let { tags } = marker;
- locations = locations.filter(
- (location) =>
- location['osm_json'].tags &&
- location['osm_json'].tags['payment:swapee'] === 'yes' &&
- location['osm_json'].lat &&
- location['osm_json'].lon
- );
+ if (zoom > 13 && isInView) {
+ popup.setHTML(`<span class='block font-bold'>${tags.name}</span>`).addTo(map);
+ } else {
+ popup.remove();
+ popup.setHTML(html(tags));
+ }
+ }
+ }
- L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png', {
- maxZoom: 18,
- subdomains: ['a', 'b', 'c', 'd']
- }).addTo(map);
+ let html = (tags) => `${
+ tags && tags.name ? `<span class='block font-bold'>${tags.name}</span>` : ''
+ }
- const checkAddress = (location) => {
- if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) {
- return `${
- location['addr:housenumber'] +
- ' ' +
- location['addr:street'] +
- ', ' +
- location['addr:city']
- }`;
- } else if (location['addr:street'] && location['addr:city']) {
- return `${location['addr:street'] + ', ' + location['addr:city']}`;
- } else if (location['addr:city']) {
- return `${location['addr:city']}`;
- } else {
- return '';
- }
- };
+ <span class='block'>${tags && checkAddress(tags)}</span>
- locations.forEach((location) => {
- if (location['deleted_at']) return;
+ ${tags && tags.phone ? `<a href='tel:${tags.phone}' class='block'>${tags.phone}</a>` : ''}
- location = location['osm_json'];
- let marker = L.marker([location.lat, location.lon], { icon });
+ ${
+ tags && tags.website
+ ? `<a href=${tags.website} target="_blank" rel="noreferrer" class='block text-blue-400'>${tags.website}</a>`
+ : ''
+ }`;
- if (location.tags && location.tags.name) {
- marker.bindTooltip(location.tags.name, { permanent: true }).openTooltip();
- }
+ onMount(() => {
+ if (browser) {
+ import('maplibre-gl').then(({ default: maplibre }) => {
+ map = new maplibre.Map({
+ container: mapContainer,
+ style: 'https://tiles.stadiamaps.com/styles/stamen_toner.json',
+ center: [-123.05, 49.26],
+ zoom: 10.5
+ });
- marker.bindPopup(
- `${
- location.tags && location.tags.name
- ? `<span class='block'>${location.tags.name}</span>`
- : ''
- }
+ map.on('load', () => {
+ locations.forEach((location) => {
+ if (location['deleted_at']) return;
- <span class='block'>${location.tags && checkAddress(location.tags)}</span>
+ let { lat, lon, tags } = location['osm_json'];
+ if (!(lat && lon)) return;
- ${
- location.tags && location.tags.phone
- ? `<a href='tel:${location.tags.phone}' class='block'>${location.tags.phone}</a>`
- : ''
- }
+ let element = document.createElement('div');
+ element.className = 'marker';
- ${
- location.tags && location.tags.website
- ? `<a href=${location.tags.website} target="_blank" rel="noreferrer" class='block'>${location.tags.website}</a>`
- : ''
- }
+ let marker = new maplibre.Marker({ color: '#F7931A' })
+ .setLngLat([lon, lat])
+ .setPopup(new maplibre.Popup().setHTML(html(tags)))
+ .addTo(map);
- ${
- location.tags && location.tags['contact:twitter']
- ? `<a href=${
- location.tags['contact:twitter'].startsWith('http')
- ? location.tags['contact:twitter']
- : `https://twitter.com/${location.tags['contact:twitter']}`
- } target="_blank" rel="noreferrer" class='block'>TWT: ${
- location.tags['contact:twitter']
- }</a>`
- : ''
- }
+ marker.getElement().addEventListener('click', () => {
+ let h = html(marker.tags);
+ let popup = marker.getPopup();
+ popup.setHTML(h);
+ });
- ${
- location.tags && location.tags['contact:instagram']
- ? `<a href=${
- location.tags['contact:instagram'].startsWith('http')
- ? location.tags['contact:instagram']
- : `https://instagram.com/${location.tags['contact:instagram']}`
- } target="_blank" rel="noreferrer" class='block'>IG: ${
- location.tags['contact:instagram']
- }</a>`
- : ''
- }
+ marker.tags = tags;
- ${
- location.tags && location.tags['contact:facebook']
- ? `<a href=${
- location.tags['contact:facebook'].startsWith('http')
- ? location.tags['contact:facebook']
- : `https://facebook.com/${location.tags['contact:facebook']}`
- } target="_blank" rel="noreferrer" class='block'>FB: ${
- location.tags['contact:facebook']
- }</a>`
- : ''
- }
+ markers.push(marker);
+ });
- ${
- location.tags && location.tags['contact:linkedin']
- ? `<a href=${
- location.tags['contact:linkedin'].startsWith('http')
- ? location.tags['contact:linkedin']
- : `https://linkedin.com/${location.tags['contact:linkedin']}`
- } target="_blank" rel="noreferrer" class='block'>LI: ${
- location.tags['contact:linkedin']
- }</a>`
- : ''
- }`
- );
- marker.addTo(map);
+ // updateLabelVisibility();
+ // map.on('moveend', updateLabelVisibility);
+ // map.on('zoomend', updateLabelVisibility);
+ });
});
-
- // map.fitBounds(locations.map(({ osm_json: { lat, lon } }) => [lat, lon]));
}
});
- onDestroy(async () => map && map.remove());
+ onDestroy(() => {
+ if (map) {
+ // map.off('moveend', updateLabelVisibility);
+ // map.off('zoomend', updateLabelVisibility);
+ map.remove();
+ }
+ });
</script>
<div class="container mx-auto max-w-4xl">
- <div class="flex w-full">
- <div class="mx-auto h-[550px] w-full z-0" bind:this={mapElement} />
- </div>
+ <div class="flex w-full">
+ <div class="mx-auto h-[550px] w-full z-0" bind:this={mapContainer} />
+ </div>
</div>
<style>
- @import 'leaflet/dist/leaflet.css';
+ :global(.maplibregl-popup-close-button) {
+ font-size: 18px;
+ padding: 8px;
+ }
+
+ :global(.maplibregl-popup :focus) {
+ outline: none;
+ }
+
+ :global(.maplibregl-ctrl-attrib) {
+ display: none;
+ }
- :global(.leaflet-tooltip) {
- border: none;
+ :global(.maplibregl-popup-content) {
+ padding: 0.5em 1em;
border-radius: 4px;
- font-size: 12px;
- font-weight: bolder;
+ font-size: 14px;
color: black;
- background-color: rgba(255, 255, 255, 0.5);
+ background-color: white;
+ overflow: hidden;
}
</style>
diff --git a/src/components/RegisterOrLogin.svelte b/src/components/RegisterOrLogin.svelte
index afe85db5..da6c387d 100644
--- a/src/components/RegisterOrLogin.svelte
+++ b/src/components/RegisterOrLogin.svelte
@@ -88,7 +88,11 @@
{/if}
<form class="space-y-5" on:submit|preventDefault={handleSubmit} method="POST">
- <input type="hidden" name="loginRedirect" value={$loginRedirect || $page.url.searchParams.get('redirect')} />
+ <input
+ type="hidden"
+ name="loginRedirect"
+ value={$loginRedirect || $page.url.searchParams.get('redirect')}
+ />
<input type="hidden" name="token" value={token} />
<div>