Browse Source

add requests for map tiles with counts of plans (commented out)

split_build_process
Trent Larson 3 weeks ago
parent
commit
a8b404133e
  1. 7
      CHANGELOG.md
  2. 4
      package.json
  3. 157
      src/views/DiscoverView.vue
  4. 8
      src/views/SearchAreaView.vue

7
CHANGELOG.md

@ -6,7 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.3.42] - 2024.12.27
## [0.3...]
### Added
- Projects on a map
## [0.3.42] - 2024.12.27 - 9751934bc24a1040415a8cfeacbae59ed91f92a5
### Added
- Link from certificate page to the claim
### Changed

4
package.json

@ -37,6 +37,7 @@
"@veramo/did-provider-peer": "^6.0.0",
"@veramo/did-resolver": "^5.6.0",
"@veramo/key-manager": "^5.6.0",
"@vue-leaflet/vue-leaflet": "^0.10.1",
"@vueuse/core": "^10.9.0",
"@zxing/text-encoding": "^0.9.0",
"asn1-ber": "^1.2.2",
@ -52,6 +53,7 @@
"jdenticon": "^3.2.0",
"js-generate-password": "^0.1.9",
"js-yaml": "^4.1.0",
"leaflet": "^1.9.4",
"localstorage-slim": "^2.7.0",
"lru-cache": "^10.2.0",
"luxon": "^3.4.4",
@ -91,14 +93,12 @@
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vue-leaflet/vue-leaflet": "^0.10.1",
"@vue/eslint-config-typescript": "^11.0.3",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.23.0",
"leaflet": "^1.9.4",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"tailwindcss": "^3.4.1",

157
src/views/DiscoverView.vue

@ -16,6 +16,7 @@
id="QuickSearch"
class="mt-8 mb-4 flex"
v-on:keyup.enter="searchSelected()"
:style="{ visibility: isSearchVisible ? 'visible' : 'hidden' }"
>
<input
type="text"
@ -40,38 +41,63 @@
@click="
projects = [];
isLocalActive = true;
isMappedActive = false;
isRemoteActive = false;
isSearchVisible = true;
searchLocal();
"
v-bind:class="computedLocalTabStyleClassNames()"
>
Nearby
<!-- restore when the links don't jump around for different numbers
<span
class="font-semibold text-sm bg-slate-200 px-1.5 py-0.5 rounded-md"
v-if="isLocalActive"
>
{{ localCount > -1 ? localCount : "?" }}
</span>
-->
</a>
</li>
<!--
<li>
<a
href="#"
@click="
projects = [];
isLocalActive = false;
isMappedActive = true;
isRemoteActive = false;
isSearchVisible = false;
"
v-bind:class="computedMappedTabStyleClassNames()"
>
Mapped
</a>
</li>
-->
<li>
<a
href="#"
@click="
projects = [];
isRemoteActive = true;
isLocalActive = false;
isMappedActive = false;
isRemoteActive = true;
isSearchVisible = true;
searchAll();
"
v-bind:class="computedRemoteTabStyleClassNames()"
>
Anywhere
<!-- restore when the links don't jump around for different numbers
<span
class="font-semibold text-sm bg-slate-200 px-1.5 py-0.5 rounded-md"
v-if="isRemoteActive"
>
{{ remoteCount > -1 ? remoteCount : "?" }}
</span>
-->
</a>
</li>
</ul>
@ -89,6 +115,25 @@
</div>
</div>
<div v-if="isMappedActive">
<div class="mt-4 h-96 w-5/6 mx-auto">
<l-map
ref="map"
:center="[localCenterLat, localCenterLong]"
:zoom="2"
@moveend="onMoveEnd"
@zoomend="onZoomEnd"
@zoomstart="onZoomStart"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
layer-type="base"
name="OpenStreetMap"
/>
</l-map>
</div>
</div>
<!-- Loading Animation -->
<div
class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
@ -102,7 +147,7 @@
<span v-if="searchBox"> None found in the selected area. </span>
<!-- Otherwise there's no search area selected so we'll just leave the search box for them to click. -->
</span>
<span v-else>No projects were found with that search.</span>
<span v-else-if="isRemoteActive">No projects were found with that search.</span>
</p>
</div>
@ -144,7 +189,15 @@
</template>
<script lang="ts">
import "leaflet/dist/leaflet.css";
import { Map } from "leaflet";
import * as L from "leaflet";
import { Component, Vue } from "vue-facing-decorator";
import {
LMap,
LTileLayer,
LMarker,
} from "@vue-leaflet/vue-leaflet";
import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
@ -158,10 +211,13 @@ import { Contact } from "@/db/tables/contacts";
import { BoundingBox } from "@/db/tables/settings";
import { didInfo, getHeaders, PlanData } from "@/libs/endorserServer";
import { OnboardPage, retrieveAccountDids } from "@/libs/util";
import { LocationEvent } from "leaflet";
@Component({
components: {
InfiniteScroll,
LMap,
LTileLayer,
OnboardingDialog,
ProjectIcon,
QuickNav,
@ -179,10 +235,16 @@ export default class DiscoverView extends Vue {
projects: PlanData[] = [];
isLoading = false;
isLocalActive = true;
isMappedActive = false;
isRemoteActive = false;
isSearchVisible = true;
localCenterLat = 0;
localCenterLong = 0;
localCount = -1;
markers: { [key: string]: L.Marker } = {};
remoteCount = -1;
searchBox: { name: string; bbox: BoundingBox } | null = null;
zoomedSoDoNotMove = false;
// make this function available to the Vue template
didInfo = didInfo;
@ -207,8 +269,13 @@ export default class DiscoverView extends Vue {
if (this.searchBox) {
await this.searchLocal();
const bbox = this.searchBox.bbox;
this.localCenterLat = (bbox.maxLat + bbox.minLat) / 2;
this.localCenterLong = (bbox.eastLong + bbox.westLong) / 2;
} else {
this.isLocalActive = false;
this.isMappedActive = false;
this.isRemoteActive = true;
await this.searchAll();
}
@ -222,6 +289,9 @@ export default class DiscoverView extends Vue {
public async searchSelected() {
if (this.isLocalActive) {
await this.searchLocal();
} else if (this.isMappedActive) {
this.isRemoteActive = true;
await this.searchAll();
} else {
await this.searchAll();
}
@ -406,12 +476,62 @@ export default class DiscoverView extends Vue {
const latestProject = this.projects[this.projects.length - 1];
if (this.isLocalActive) {
this.searchLocal(latestProject["rowid"]);
} else if (this.isMappedActive) {
// don't do anything since mapped items only show a limited number
} else if (this.isRemoteActive) {
this.searchAll(latestProject["rowid"]);
}
}
}
async onMoveEnd(event: LocationEvent) {
if (this.zoomedSoDoNotMove) {
this.zoomedSoDoNotMove = false;
} else {
// not part of a zoom so request tiles
await this.requestTiles(event);
}
}
async onZoomEnd(event: LocationEvent) {
await this.requestTiles(event);
}
onZoomStart(event: LocationEvent) {
this.zoomedSoDoNotMove = true;
}
async requestTiles(event: LocationEvent) {
const bounds = event.target.getBounds();
const queryParams = [
"minLocLat=" + bounds?.getSouthWest().lat,
"maxLocLat=" + bounds?.getNorthEast().lat,
"westLocLon=" + bounds?.getSouthWest().lng,
"eastLocLon=" + bounds?.getNorthEast().lng,
].join("&");
const response = await fetch(this.apiServer + "/api/v2/report/planCountsByBBox?" + queryParams);
if (response.status === 200) {
const results = await response.json();
if (results.data?.tiles?.length > 0) {
Object.values(this.markers).forEach(marker => marker.remove());
this.markers = {};
for (const tile of results.data.tiles) {
const pinLat = (tile.minFoundLat + tile.maxFoundLat) / 2;
const pinLon = (tile.minFoundLon + tile.maxFoundLon) / 2;
const numberIcon = L.divIcon({
className: "numbered-marker",
html: `<strong>${tile.recordCount}</strong>`,
iconSize: [24, 24],
iconAnchor: [12, 12], // coordinates of the tip of the icon relative to the top-left corner of the icon
});
const marker = L.marker([pinLat, pinLon], { icon: numberIcon });
marker.addTo(event.target);
this.markers["" + tile.indexLat + "x" + tile.indexLon] = marker;
}
}
}
}
/**
* Handle clicking on a project entry found in the list
* @param id of the project
@ -441,6 +561,24 @@ export default class DiscoverView extends Vue {
};
}
public computedMappedTabStyleClassNames() {
return {
"inline-block": true,
"py-3": true,
"rounded-t-lg": true,
"border-b-2": true,
active: this.isMappedActive,
"text-black": this.isMappedActive,
"border-black": this.isMappedActive,
"font-semibold": this.isMappedActive,
"text-blue-600": !this.isMappedActive,
"border-transparent": !this.isMappedActive,
"hover:border-slate-400": !this.isMappedActive,
};
}
public computedRemoteTabStyleClassNames() {
return {
"inline-block": true,
@ -460,3 +598,18 @@ export default class DiscoverView extends Vue {
}
}
</script>
<style>
.numbered-marker {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
color: white;
background: blue;
width: 24px;
height: 24px;
border-radius: 50%;
border: 2px solid white;
}
</style>

8
src/views/SearchAreaView.vue

@ -68,7 +68,7 @@
</div>
</div>
<div class="mb-4 aspect-video">
<div class="aspect-video">
<l-map
ref="map"
:center="[localCenterLat, localCenterLong]"
@ -129,7 +129,7 @@ const DEFAULT_ZOOM = 2;
LTileLayer,
},
})
export default class DiscoverView extends Vue {
export default class SearchAreaView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
isChoosingSearchBox = false;
@ -166,8 +166,8 @@ export default class DiscoverView extends Vue {
// This doesn't seem like the right approach but it's the only way I can find to get the screen bounds.
const bounds = event.target.boxZoom?._map?.getBounds();
if (bounds) {
latDiff = Math.abs(bounds._northEast.lat - bounds._southWest.lat) / 8;
longDiff = Math.abs(bounds._northEast.lng - bounds._southWest.lng) / 8;
latDiff = Math.abs(bounds.getNorthEast().lat - bounds.getSouthWest().lat) / 8;
longDiff = Math.abs(bounds.getNorthEast().lng - bounds.getSouthWest().lng) / 8;
}
this.localLatDiff = latDiff;
this.localLongDiff = longDiff;

Loading…
Cancel
Save