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

208
src/views/DiscoverView.vue

@ -62,6 +62,42 @@
</ul> </ul>
</div> </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 --> <!-- Loading Animation -->
<div <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" 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> </ul>
</InfiniteScroll> </InfiniteScroll>
<div <div v-if="isChoosingSearchBox" style="height: 600px; width: 800px">
v-if="isLocalActive && searchBoxes.length === 0"
style="height: 600px; width: 800px"
>
<l-map <l-map
ref="map" ref="map"
:center="[localCenterLat, localCenterLong]"
v-model:zoom="localZoom" v-model:zoom="localZoom"
:center="[0, 0]" @click="setMapPoint"
@click="
(event) => {
localLatitude = event.latlng.lat;
localLongitude = event.latlng.lng;
}
"
> >
<l-tile-layer <l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
@ -125,15 +153,16 @@
name="OpenStreetMap" name="OpenStreetMap"
/> />
<l-marker <l-marker
v-if="localLatitude || localLongitude" v-if="isMarkerSet"
:lat-lng="[localLatitude, localLongitude]" :lat-lng="[localCenterLat, localCenterLong]"
@click="resetLatLong()"
/> />
<l-rectangle <l-rectangle
v-if="isMarkerSet"
:bounds="[ :bounds="[
[localLatitude - 0.1, localLongitude - 0.1], [localCenterLat - localLatDiff, localCenterLong - localLongDiff],
[localLatitude + 0.1, localLongitude + 0.1], [localCenterLat + localLatDiff, localCenterLong + localLongDiff],
]" ]"
:color="ff7800"
:weight="1" :weight="1"
/> />
</l-map> </l-map>
@ -155,14 +184,18 @@ import {
import { accountsDB, db } from "@/db"; import { accountsDB, db } from "@/db";
import { Contact } from "@/db/tables/contacts"; 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 { accessToken } from "@/libs/crypto";
import { didInfo } from "@/libs/endorserServer"; import { didInfo, ProjectData } from "@/libs/endorserServer";
import AlertMessage from "@/components/AlertMessage"; import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import InfiniteScroll from "@/components/InfiniteScroll"; import InfiniteScroll from "@/components/InfiniteScroll";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
const DEFAULT_LAT_LONG_DIFF = 0.01;
const WORLD_ZOOM = 2;
const DEFAULT_ZOOM = 2;
@Component({ @Component({
components: { components: {
LRectangle, LRectangle,
@ -184,14 +217,18 @@ export default class DiscoverView extends Vue {
alertMessage = ""; alertMessage = "";
alertTitle = ""; alertTitle = "";
projects: ProjectData[] = []; projects: ProjectData[] = [];
isChoosingSearchBox = false;
isLocalActive = true; isLocalActive = true;
isRemoteActive = false; isRemoteActive = false;
isMarkerSet = false;
localCenterLat = 0;
localCenterLong = 0;
localLatDiff = DEFAULT_LAT_LONG_DIFF;
localLongDiff = DEFAULT_LAT_LONG_DIFF;
localCount = 0; localCount = 0;
localLatitude = 0; localZoom = DEFAULT_ZOOM;
localLongitude = 0;
localZoom = 2;
remoteCount = 0; remoteCount = 0;
searchBoxes = []; searchBox: BoundingBox | null = null;
isLoading = false; isLoading = false;
// make this function available to the Vue template // 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); const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = settings?.activeDid || ""; this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || ""; this.apiServer = settings?.apiServer || "";
this.searchBoxes = settings?.searchBoxes || []; this.searchBox = settings?.searchBoxes?.[0];
this.resetLatLong();
this.allContacts = await db.contacts.toArray(); this.allContacts = await db.contacts.toArray();
await accountsDB.open(); await accountsDB.open();
@ -399,6 +437,130 @@ export default class DiscoverView extends Vue {
this.$router.push(route); 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() { public computedLocalTabClassNames() {
return { return {
"inline-block": true, "inline-block": true,

Loading…
Cancel
Save