From 7d90aeacb1effb44e6ecb8e468ec1b66b2479d9e Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Wed, 8 Feb 2023 13:35:42 -0800 Subject: [PATCH] map: restore functionality --- lib/Controller/ApiBase.php | 13 +- lib/Controller/LocationController.php | 20 +-- lib/Db/TimelineQueryFilters.php | 10 +- src/App.vue | 15 ++- src/components/SplitTimeline.vue | 68 ++++++++++ src/components/Timeline.vue | 56 +++----- .../top-matter/LocationTopMatter.vue | 124 +++++++++--------- src/components/top-matter/TopMatter.vue | 3 - src/global.scss | 15 +++ src/router.ts | 5 +- src/types.ts | 12 +- 11 files changed, 209 insertions(+), 132 deletions(-) create mode 100644 src/components/SplitTimeline.vue diff --git a/lib/Controller/ApiBase.php b/lib/Controller/ApiBase.php index 79bc3497..7ea87198 100644 --- a/lib/Controller/ApiBase.php +++ b/lib/Controller/ApiBase.php @@ -458,12 +458,13 @@ class ApiBase extends Controller } // Filter geological bounds - $minLat = $this->request->getParam('minLat'); - $maxLat = $this->request->getParam('maxLat'); - $minLng = $this->request->getParam('minLng'); - $maxLng = $this->request->getParam('maxLng'); - if ($minLat && $maxLat && $minLng && $maxLng) { - $transforms[] = [$this->timelineQuery, 'transformBoundFilter', $minLat, $maxLat, $minLng, $maxLng]; + $bounds = $this->request->getParam('mapbounds'); + if ($bounds) { + $bounds = explode(',', $bounds); + $bounds = array_map('floatval', $bounds); + if (4 === \count($bounds)) { + $transforms[] = [$this->timelineQuery, 'transformBoundFilter', $bounds]; + } } return $transforms; diff --git a/lib/Controller/LocationController.php b/lib/Controller/LocationController.php index 9981a5a8..3f017a62 100644 --- a/lib/Controller/LocationController.php +++ b/lib/Controller/LocationController.php @@ -46,22 +46,24 @@ class LocationController extends ApiBase // Get the folder to show $root = null; - try { $root = $this->getRequestRoot(); } catch (\Exception $e) { return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); } - // Just check bound parameters instead of using them; they are used in transformation - $minLat = $this->request->getParam('minLat'); - $maxLat = $this->request->getParam('maxLat'); - $minLng = $this->request->getParam('minLng'); - $maxLng = $this->request->getParam('maxLng'); + // Make sure we have bounds + // $bounds = $this->request->getParam('bounds'); + // if (!$bounds) { + // return new JSONResponse(['message' => 'Invalid perameters'], Http::STATUS_PRECONDITION_FAILED); + // } - if (!is_numeric($minLat) || !is_numeric($maxLat) || !is_numeric($minLng) || !is_numeric($maxLng)) { - return new JSONResponse(['message' => 'Invalid perameters'], Http::STATUS_PRECONDITION_FAILED); - } + // // Make sure we have 4 bounds + // $bounds = explode(',', $bounds); + // $bounds = array_map('floatval', $bounds); + // if (4 !== \count($bounds)) { + // return new JSONResponse(['message' => 'Invalid perameters'], Http::STATUS_PRECONDITION_FAILED); + // } // Zoom level is used to determine the grid length $zoomLevel = $this->request->getParam('zoom'); diff --git a/lib/Db/TimelineQueryFilters.php b/lib/Db/TimelineQueryFilters.php index 7e4bebd9..83ad7c6f 100644 --- a/lib/Db/TimelineQueryFilters.php +++ b/lib/Db/TimelineQueryFilters.php @@ -40,14 +40,14 @@ trait TimelineQueryFilters $query->setMaxResults($limit); } - public function transformBoundFilter(IQueryBuilder &$query, string $userId, string $minLat, string $maxLat, string $minLng, string $maxLng) + public function transformBoundFilter(IQueryBuilder &$query, string $userId, array $bounds) { $query->andWhere( $query->expr()->andX( - $query->expr()->gte('m.lat', $query->createNamedParameter($minLat, IQueryBuilder::PARAM_STR)), - $query->expr()->lte('m.lat', $query->createNamedParameter($maxLat, IQueryBuilder::PARAM_STR)), - $query->expr()->gte('m.lon', $query->createNamedParameter($minLng, IQueryBuilder::PARAM_STR)), - $query->expr()->lte('m.lon', $query->createNamedParameter($maxLng, IQueryBuilder::PARAM_STR)) + $query->expr()->gte('m.lat', $query->createNamedParameter($bounds[0], IQueryBuilder::PARAM_STR)), + $query->expr()->lte('m.lat', $query->createNamedParameter($bounds[1], IQueryBuilder::PARAM_STR)), + $query->expr()->gte('m.lon', $query->createNamedParameter($bounds[2], IQueryBuilder::PARAM_STR)), + $query->expr()->lte('m.lon', $query->createNamedParameter($bounds[3], IQueryBuilder::PARAM_STR)) ) ); } diff --git a/src/App.vue b/src/App.vue index c1092d35..1cf69ce9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -30,7 +30,12 @@ -
+
@@ -144,6 +149,10 @@ export default defineComponent({ showNavigation(): boolean { return !this.$route.name?.endsWith("-share"); }, + + removeNavGap(): boolean { + return this.$route.name === "locations"; + }, }, watch: { @@ -330,6 +339,10 @@ export default defineComponent({ padding: 0 0 0 44px; height: 100%; width: 100%; + + &.remove-gap { + padding: 0; + } } @media (max-width: 768px) { diff --git a/src/components/SplitTimeline.vue b/src/components/SplitTimeline.vue new file mode 100644 index 00000000..c18856ff --- /dev/null +++ b/src/components/SplitTimeline.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index 1ee38ad6..076bab20 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -5,7 +5,7 @@ :class="{ 'icon-loading': loading > 0 }" > - + & any, /** Scroller manager component */ scrollerManager: null as InstanceType & any, - - /** The boundary of the map */ - mapBoundary: { - minLat: -90, - maxLat: 90, - minLng: -180, - maxLng: 180, - } as MapBoundary, }), mounted() { @@ -341,13 +325,16 @@ export default defineComponent({ methods: { async routeChange(to: any, from?: any) { - if ( - from?.path !== to.path || - JSON.stringify(from.query) !== JSON.stringify(to.query) - ) { + // Always do a hard refresh if the path changes + if (from?.path !== to.path) { await this.refresh(); } + // Do a soft refresh if the query changes + else if (JSON.stringify(from.query) !== JSON.stringify(to.query)) { + await this.softRefresh(); + } + // The viewer might change the route immediately again await this.$nextTick(); @@ -408,7 +395,9 @@ export default defineComponent({ }, isMobileLayout() { - return globalThis.windowInnerWidth <= 600; + return ( + globalThis.windowInnerWidth <= 600 || this.$route.name === "locations" + ); }, allowBreakout() { @@ -700,20 +689,17 @@ export default defineComponent({ query.set("tag", this.$route.params.name); } + // Map Bounds + if (this.$route.name === "locations" && this.$route.query.b) { + query.set("mapbounds", this.$route.query.b); + } + // Month view if (this.isMonthView) { query.set("monthView", "1"); query.set("reverse", "1"); } - // Geological Bounds - if (this.$route.name === "locations") { - query.set("minLat", "" + this.mapBoundary.minLat); - query.set("maxLat", "" + this.mapBoundary.maxLat); - query.set("minLng", "" + this.mapBoundary.minLng); - query.set("maxLng", "" + this.mapBoundary.maxLng); - } - return query; }, @@ -1314,11 +1300,6 @@ export default defineComponent({ this.processDay(day.dayid, newDetail); } }, - - async updateBoundary(mapBoundary: MapBoundary) { - this.mapBoundary = mapBoundary; - await this.softRefresh(); - }, }, }); @@ -1347,7 +1328,7 @@ export default defineComponent({ will-change: scroll-position; contain: strict; height: 300px; - width: calc(100% + 20px); + width: 100%; transition: opacity 0.2s ease-in-out; :deep .vue-recycle-scroller__slot { @@ -1365,6 +1346,7 @@ export default defineComponent({ &.empty { opacity: 0; transition: none; + width: 0; } } diff --git a/src/components/top-matter/LocationTopMatter.vue b/src/components/top-matter/LocationTopMatter.vue index f4cb1dd1..b79f944a 100644 --- a/src/components/top-matter/LocationTopMatter.vue +++ b/src/components/top-matter/LocationTopMatter.vue @@ -1,11 +1,12 @@