Browse Source

refactor map selection, and now location selection & cancellation works (but not saving yet)

search-bbox
Trent Larson 1 year ago
parent
commit
26d9b134c7
  1. 3
      README.md
  2. 9
      src/db/tables/settings.ts
  3. 208
      src/views/DiscoverView.vue

3
README.md

@ -99,6 +99,9 @@ See https://tea.xyz
### Reference Material
* Notifications can be type of `toast` (self-dismiss), `info`, `success`, `warning`, and `danger`.
They are done via [notiwind](https://www.npmjs.com/package/notiwind) and set up in App.vue.
```
// reference material from https://github.com/trentlarson/endorser-mobile/blob/8dc8e0353e0cc80ffa7ed89ded15c8b0da92726b/src/utility/idUtility.ts#L83

9
src/db/tables/settings.ts

@ -1,8 +1,8 @@
export type BoundingBox = {
eastLong: number;
maxLat: number;
maxLong: number;
minLat: number;
minLong: number;
westLong: number;
};
// a singleton
@ -14,7 +14,10 @@ export type Settings = {
firstName?: string;
lastName?: string;
lastViewedClaimId?: string;
searchBoxes?: Array<BoundingBox>;
searchBoxes?: Array<{
name: string;
bbox: BoundingBox;
}>;
showContactGivesInline?: boolean;
};

208
src/views/DiscoverView.vue

@ -62,6 +62,42 @@
</ul>
</div>
<div v-if="isLocalActive">
<div v-if="!isChoosingSearchBox">
<button
class="ml-2 px-4 py-2 rounded-md bg-blue-200 text-blue-500"
@click="isChoosingSearchBox = true"
>
Select a {{ searchBox ? "Different" : "" }} Location for Nearby Search
</button>
</div>
<div v-else>
<button v-if="!searchBox && !isMarkerSet" class="m-4 px-4 py-2">
Choose Location Below for Nearby Search
</button>
<button
v-if="!searchBox && isMarkerSet"
class="m-4 px-4 py-2 rounded-md bg-blue-200 text-blue-500"
@click="storeSearchBox"
>
Save Location for Nearby Search
</button>
<button
v-if="searchBox"
class="m-4 px-4 py-2 rounded-md bg-blue-200 text-blue-500"
@click="forgetSearchBox"
>
Delete Location for Nearby Search
</button>
<button
class="ml-2 px-4 py-2 rounded-md bg-blue-200 text-blue-500"
@click="cancelSearchBoxSelect"
>
Cancel
</button>
</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"
@ -104,20 +140,12 @@
</ul>
</InfiniteScroll>
<div
v-if="isLocalActive && searchBoxes.length === 0"
style="height: 600px; width: 800px"
>
<div v-if="isChoosingSearchBox" style="height: 600px; width: 800px">
<l-map
ref="map"
:center="[localCenterLat, localCenterLong]"
v-model:zoom="localZoom"
:center="[0, 0]"
@click="
(event) => {
localLatitude = event.latlng.lat;
localLongitude = event.latlng.lng;
}
"
@click="setMapPoint"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
@ -125,15 +153,16 @@
name="OpenStreetMap"
/>
<l-marker
v-if="localLatitude || localLongitude"
:lat-lng="[localLatitude, localLongitude]"
v-if="isMarkerSet"
:lat-lng="[localCenterLat, localCenterLong]"
@click="resetLatLong()"
/>
<l-rectangle
v-if="isMarkerSet"
:bounds="[
[localLatitude - 0.1, localLongitude - 0.1],
[localLatitude + 0.1, localLongitude + 0.1],
[localCenterLat - localLatDiff, localCenterLong - localLongDiff],
[localCenterLat + localLatDiff, localCenterLong + localLongDiff],
]"
:color="ff7800"
:weight="1"
/>
</l-map>
@ -155,14 +184,18 @@ import {
import { accountsDB, db } from "@/db";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto";
import { didInfo } from "@/libs/endorserServer";
import { didInfo, ProjectData } from "@/libs/endorserServer";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav";
import InfiniteScroll from "@/components/InfiniteScroll";
import EntityIcon from "@/components/EntityIcon";
const DEFAULT_LAT_LONG_DIFF = 0.01;
const WORLD_ZOOM = 2;
const DEFAULT_ZOOM = 2;
@Component({
components: {
LRectangle,
@ -184,14 +217,18 @@ export default class DiscoverView extends Vue {
alertMessage = "";
alertTitle = "";
projects: ProjectData[] = [];
isChoosingSearchBox = false;
isLocalActive = true;
isRemoteActive = false;
isMarkerSet = false;
localCenterLat = 0;
localCenterLong = 0;
localLatDiff = DEFAULT_LAT_LONG_DIFF;
localLongDiff = DEFAULT_LAT_LONG_DIFF;
localCount = 0;
localLatitude = 0;
localLongitude = 0;
localZoom = 2;
localZoom = DEFAULT_ZOOM;
remoteCount = 0;
searchBoxes = [];
searchBox: BoundingBox | null = null;
isLoading = false;
// make this function available to the Vue template
@ -202,7 +239,8 @@ export default class DiscoverView extends Vue {
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
this.searchBoxes = settings?.searchBoxes || [];
this.searchBox = settings?.searchBoxes?.[0];
this.resetLatLong();
this.allContacts = await db.contacts.toArray();
await accountsDB.open();
@ -399,6 +437,130 @@ export default class DiscoverView extends Vue {
this.$router.push(route);
}
setMapPoint(event) {
if (this.isMarkerSet) {
this.localLatDiff = Math.abs(event.latlng.lat - this.localCenterLat);
this.localLongDiff = Math.abs(event.latlng.lng - this.localCenterLong);
} else {
// marker is not set
this.localCenterLat = event.latlng.lat;
this.localCenterLong = event.latlng.lng;
let latDiff = DEFAULT_LAT_LONG_DIFF;
let longDiff = DEFAULT_LAT_LONG_DIFF;
// Guess at a size for the bounding box.
// 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;
}
this.localLatDiff = latDiff;
this.localLongDiff = longDiff;
this.isMarkerSet = true;
}
}
public resetLatLong() {
if (this.searchBox) {
this.localCenterLat = (this.searchBox.maxLat + this.searchBox.minLat) / 2;
this.localCenterLong =
(this.searchBox.eastLong + this.searchBox.westLong) / 2;
this.localLatDiff = (this.searchBox.maxLat - this.searchBox.minLat) / 2;
this.localLongDiff =
(this.searchBox.eastLong - this.searchBox.westLong) / 2;
this.localZoom = WORLD_ZOOM;
}
// otherwise, don't change their viewport
this.isMarkerSet = false;
}
public async storeSearchBox() {
if (this.localCenterLong || this.localCenterLat) {
try {
await db.open();
db.settings.update(MASTER_SETTINGS_KEY, {
searchBoxes: [
{
name: "Local",
bbox: {
eastLong: this.localCenterLong + this.localLongDiff,
maxLat: this.localCenterLat + this.localLatDiff,
minLat: this.localCenterLat - this.localLatDiff,
westLong: this.localCenterLong - this.localLongDiff,
},
},
],
});
this.searchBox = {
eastLong: this.localCenterLong + this.localLongDiff,
maxLat: this.localCenterLat + this.localLatDiff,
minLat: this.localCenterLat - this.localLatDiff,
westLong: this.localCenterLong - this.localLongDiff,
};
this.localZoom = WORLD_ZOOM;
} catch (err) {
this.$notify(
{
group: "alert",
type: "danger",
title: "Error Updating Search Settings",
text: "Try going to a different page and then coming back.",
},
-1,
);
console.error(
"Telling user to retry the location search setting because:",
err,
);
}
} else {
this.$notify(
{
group: "alert",
type: "warning",
title: "No Location Selected",
text: "Select a location on the map.",
},
-1,
);
}
}
public async forgetSearchBox() {
try {
await db.open();
db.settings.update(MASTER_SETTINGS_KEY, {
searchBoxes: [],
});
this.searchBox = null;
this.localCenterLat = 0;
this.localCenterLong = 0;
this.localLatDiff = DEFAULT_LAT_LONG_DIFF;
this.localLongDiff = DEFAULT_LAT_LONG_DIFF;
this.localZoom = DEFAULT_ZOOM;
} catch (err) {
this.$notify(
{
group: "alert",
type: "danger",
title: "Error Updating Search Settings",
text: "Try going to a different page and then coming back.",
},
-1,
);
console.error(
"Telling user to retry the location search setting because:",
err,
);
}
}
public cancelSearchBoxSelect() {
this.isChoosingSearchBox = false;
this.localZoom = WORLD_ZOOM;
}
public computedLocalTabClassNames() {
return {
"inline-block": true,

Loading…
Cancel
Save