Skip to content

Commit

Permalink
Improved cryptocities
Browse files Browse the repository at this point in the history
  • Loading branch information
onmax committed Oct 3, 2023
1 parent 96e5c9f commit 6870658
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/components/cards/cryptocity/CryptocityCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ defineEmits({ close: () => true })
<div class="grid items-center grid-cols-[auto_1fr_auto] grid-rows-2 grid-flow-dense gap-x-2">
<CryptocityIcon style="width: 31px; height: 27px" class="row-span-full" />
<h3 class="text-space leading-[1]" :class="cryptocity.locationsCount <= 1 ? 'row-span-full' : ''">{{ cryptocity.name }}</h3>
<span v-if="cryptocity.locationsCount > 1" class="text-sm leading-[1] text-space/60">{{ $tc('{count} locations', cryptocity.locationsCount) }}</span>
<span v-if="cryptocity.locationsCount > 1" class="text-sm leading-[1] text-space/70">{{ $tc('{count} locations', cryptocity.locationsCount) }}</span>
<button type="button" class="relative w-6 h-6 col-start-3 p-2 ml-auto transition rounded-full text-space bg-space/10 row-span-full -top-1" :aria-label="$t('Close')" :class="cryptocity.locationsCount > 1 ? 'self-start' : 'row-span-full'" @click="$emit('close')">
<CrossIcon />
</button>
</div>

<p v-for="(p, i) in cryptocity.description" :key="i" class="text-xs text-space/70" :class="i === 0 ? 'pt-3' : 'pt-2'">{{ p }}</p>
<Button :href="cryptocity.url" class="mt-2 !p-0 !h-auto text-xs" bg-color="transparent" size="sm" text-color="sky">
<p v-for="(p, i) in cryptocity.description" :key="i" class="text-sm text-space/80" :class="i === 0 ? 'pt-3' : 'pt-2'">{{ p }}</p>
<Button :href="cryptocity.url" class="mt-2 !p-0 !h-auto [&_span]:!text-sm" bg-color="transparent" size="sm" text-color="sky">
<template #label>
{{ cryptocity.url }}
</template>
Expand Down
2 changes: 1 addition & 1 deletion src/components/elements/Controls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ async function setBrowserPosition() {
:open="cryptocityCardOpen"
@update:open="$router.push({ query: { ...$route.query, cryptocity: $event ? cryptocityControl.name : undefined } })"
>
<PopoverTrigger class="border border-[#e9e9ed] animate-scale !w-8 !h-8 shadow bg-white rounded-full p-1.5" data-cryptocity-card :aria-label="$t('Information about this Cryptocity')"><CryptocityIcon /></PopoverTrigger>
<PopoverTrigger class="border border-[#e9e9ed] animate-scale !w-8 !h-8 shadow bg-white rounded-full p-1.5" data-cryptocity-card-trigger :aria-label="$t('Information about this Cryptocity')"><CryptocityIcon /></PopoverTrigger>
<PopoverPortal>
<PopoverContent
align="end" side="bottom" :side-offset="-32" class="max-desktop:-mb-[72px] max-desktop:w-screen will-change-[transform,opacity] animate-slideUpAndFade"
Expand Down
2 changes: 1 addition & 1 deletion src/components/icons/providers/ProviderCircleLogo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defineProps({
<template>
<div class="grid w-8 h-8 bg-white rounded-full children:w-5 children:h-5 place-content-center">
<BluecodeIcon v-if="provider === Provider.Bluecode" />
<CryptopaymentLinkIcon v-else-if="provider === Provider.CryptopaymentLink" />
<CryptopaymentLinkIcon v-else-if="provider === Provider.CryptopaymentLink" class="-ml-px" />
<DefaultAtmIcon v-else-if="provider === Provider.DefaultAtm" />
<EdeniaIcon v-else-if="provider === Provider.Edenia" class="[&_path]:!fill-[#22afad] [&_path]:!opacity-100" />
<GoCryptoIcon v-else-if="provider === Provider.GoCrypto" class="[&_path]:!fill-space" />
Expand Down
24 changes: 14 additions & 10 deletions src/components/markers/ClusterMarkers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { screens } from 'tailwindcss-nimiq-theme'
import { OnClickOutside } from '@vueuse/components'
import CryptocityMarker from './CryptocityMarker.vue'
import { useMap } from '@/stores/map'
import { useCryptocities } from '@/stores/cryptocities'
defineProps({
clusters: {
Expand All @@ -19,16 +18,19 @@ defineProps({
const { setPosition } = useMap()
const { zoom } = storeToRefs(useMap())
const { newCitiesInView } = storeToRefs(useCryptocities())
const isMobile = useBreakpoints(screens).smaller('md')
function setExpansionCluster(id: number, open: '0' | '1') {
(document.querySelector(`[data-cluster-id="${id}"]`) as HTMLElement).style.setProperty('--expanded', open)
}
function toggleClusterExpansion({ id }: Cluster, event?: Event) {
const clusterUl = document.querySelector(`[data-cluster-id="${id}"]`) as HTMLElement
const current = clusterUl.style.getPropertyValue('--expanded')
// If it is outside the cluster and it is 0, do nothing
if (event && current === '0' && !clusterUl.contains(event.target as Node))
return
clusterUl.style.setProperty('--expanded', current === '1' ? '0' : '1')
setExpansionCluster(id, current === '1' ? '0' : '1')
}
function onClusterClick({ expansionZoom, lat, lng }: Cluster) {
Expand All @@ -46,14 +48,17 @@ function onClusterClick({ expansionZoom, lat, lng }: Cluster) {
data-custom-marker
:class="c.cryptocities.length > 0 && 'z-10'"
>
<OnClickOutside @trigger="toggleClusterExpansion(c, $event)">
<OnClickOutside @trigger="isMobile && toggleClusterExpansion(c, $event)">
<ul
:data-cluster-id="c.id"
class="relative group [--expanded:0] hover:[--expanded:1]"
class="relative"
:style="`
--expanded: 0;
left: calc(-1 * ${c.diameter / 2}px); /* To center it after we set it to the left in the anchor point */
padding-right: calc(var(--expanded) * ${c.diameter * c.cryptocities.length + 8}px)
`"
@pointerover="!isMobile && c.cryptocities.length > 0 ? setExpansionCluster(c.id, '1') : undefined"
@pointerout="!isMobile && c.cryptocities.length > 0 ? setExpansionCluster(c.id, '0') : undefined"
>
<li class="relative z-10">
<div
Expand All @@ -66,13 +71,12 @@ function onClusterClick({ expansionZoom, lat, lng }: Cluster) {

<li
v-for="(city, i) in c.cryptocities" :key="city"
class="absolute top-0 z-0 transition"
:class="newCitiesInView.includes(city) && 'animate-cryptocity'"
class="absolute top-0 transition"
:style="`
--index: ${i + 1};
z-index: ${c.cryptocities.length - i};
width: ${c.diameter}px;
--offset-1: calc(var(--index) * 12px); /* If is not expanded */
--offset-2: calc((100% * var(--index)) + (var(--index) * 8px)); /* If is expanded */
--offset-1: calc(${i + 1} * 12px); /* If is not expanded */
--offset-2: calc((100% * ${i + 1}) + (${i + 1} * 8px)); /* If is expanded */
transform: translateX(calc(var(--offset-1) * (1 - var(--expanded)) + var(--offset-2) * var(--expanded))) rotate(calc((1 - var(--expanded)) * -90deg));
padding-left: calc(1 - var(--expanded) * 2px);
`"
Expand Down
2 changes: 1 addition & 1 deletion src/components/markers/CryptocityMarker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const route = useRoute()
function onCryptocityClick() {
const { lat, lng, name, showCardAtZoom } = cryptocity.value as CryptocityData
const cardTrigger = (document.querySelector('[data-cryptocity-card]') as HTMLElement)
const cardTrigger = (document.querySelector('[data-cryptocity-card-trigger]') as HTMLElement)
if (cardTrigger)
cardTrigger.click()
setPosition({ center: { lat, lng }, zoom: showCardAtZoom })
Expand Down
14 changes: 4 additions & 10 deletions src/stores/cryptocities.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineStore, storeToRefs } from 'pinia'
import type { Feature, MultiPolygon } from '@turf/helpers'
import { multiPolygon } from '@turf/helpers'
import { computed, ref, watch } from 'vue'
import { computed, ref } from 'vue'
import type { BoundingBox, Cryptocity, CryptocityData, CryptocityDatabase } from 'types'
import { addBBoxToArea, bBoxIsWithinArea, getItemsWithinBBox } from 'shared'
import { getCryptocities as getDbCryptocities } from 'database'
Expand Down Expand Up @@ -45,11 +45,6 @@ export const useCryptocities = defineStore('cryptocities', () => {
// Cryptocities no in attachedCryptocities
const cryptocitiesSingles = computed(() => allCryptocities.value.filter(cryptocity => !attachedCryptocities.value.includes(cryptocity.city)))

const newCitiesInView = ref<Cryptocity[]>([])
watch(cryptocitiesInView, (newInView, oldInView) => {
newCitiesInView.value = newInView.filter(city => !oldInView.includes(city)).map(({ city }) => city)
})

const CRYPTOCITY_MIN_ZOOM = 7
const CRYPTOCITY_MIN_OPACITY = 0.01
const CRYPTOCITY_MAX_ZOOM = 21
Expand All @@ -65,15 +60,15 @@ export const useCryptocities = defineStore('cryptocities', () => {
}

const addedShapes = ref<Cryptocity[]>([])
watchDebounced([boundingBox, zoom], () => {
watchDebounced([allCryptocities, boundingBox], () => {
if (!map.value)
return
allCryptocities.value.filter(({ city }) => !addedShapes.value.includes(city)).forEach(({ city, shape }) => {
map.value?.data.addGeoJson(shape)
addedShapes.value.push(city)
})
map.value?.data.setStyle({ fillColor: 'rgb(31, 35, 72)', fillOpacity: linearRegression(zoom.value), strokeWeight: 1.5, strokeColor: 'rgb(31, 35, 72)', strokeOpacity: 0.8 })
}, { debounce: 300 })
map.value?.data.setStyle({ fillColor: 'rgb(31, 35, 72)', fillOpacity: linearRegression(zoom.value), strokeWeight: 1.5, strokeColor: 'rgb(31, 35, 72)', strokeOpacity: 0.8, cursor: 'default' })
}, { debounce: 300, immediate: true })

return {
cryptocities,
Expand All @@ -82,6 +77,5 @@ export const useCryptocities = defineStore('cryptocities', () => {
cryptocitiesInView,
cryptocitiesSingles,
attachedCryptocities,
newCitiesInView,
}
})
3 changes: 3 additions & 0 deletions src/stores/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ export const useMap = defineStore('map', () => {
else if (p instanceof google.maps.LatLngBounds) {
map.value?.fitBounds(p)
}

// It takes a few seconds to recompute the clusters, so we clear the markers to avoid showing them
useMarkers().clearMarkers()
}

async function goToPlaceId(placeId?: string) {
Expand Down
1 change: 1 addition & 0 deletions src/stores/markers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,6 @@ export const useMarkers = defineStore('markers', () => {
singlesInView,
needsToUpdate,
loaded,
clearMarkers: () => setMarkers([], []),
}
})

0 comments on commit 6870658

Please sign in to comment.