diff options
| author | Adam Soltys <[email protected]> | 2023-10-16 15:34:26 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-10-16 15:34:26 -0700 |
| commit | 829c2efb9c4415c64466988f1e189184ffb88478 (patch) | |
| tree | 23f9e5fd83be3d4ee3943d254e4d3d2ce194819a /src/components | |
| parent | 16475fffdb0d20a2933cfaf6922afc7c137bb7fe (diff) | |
| parent | 0212fe0032eb0c5d6bfb74ebaab42543b73d6d6b (diff) | |
| download | coinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.tar.gz coinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.zip | |
Merge branch 'master' into swapee
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/AppHeader.svelte | 4 | ||||
| -rw-r--r-- | src/components/Balance.svelte | 4 | ||||
| -rw-r--r-- | src/components/Code.svelte | 4 | ||||
| -rw-r--r-- | src/components/Footer.svelte | 2 | ||||
| -rw-r--r-- | src/components/LocationsMap.svelte | 268 | ||||
| -rw-r--r-- | src/components/RegisterOrLogin.svelte | 6 |
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> |
