diff --git a/frontend/app/src/app/modules/data/list/food-data-list.component.ts b/frontend/app/src/app/modules/data/list/food-data-list.component.ts
index 5fb5ddd5..6379d815 100644
--- a/frontend/app/src/app/modules/data/list/food-data-list.component.ts
+++ b/frontend/app/src/app/modules/data/list/food-data-list.component.ts
@@ -12,27 +12,13 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
-import {AfterViewInit, Component, ViewChild} from '@angular/core';
+import {ChangeDetectionStrategy, Component} from '@angular/core';
import {MapPosition, PositionService} from '../../map/position.service';
-import {SCSearchFilter, SCSearchSort} from '@openstapps/core';
-import {SearchPageComponent} from './search-page.component';
import {Geolocation} from '@capacitor/geolocation';
-
-/**
- * Converts a position into a sort query
- */
-function asSortQuery(position: MapPosition): SCSearchSort[] {
- return [
- {
- type: 'distance',
- order: 'asc',
- arguments: {
- field: 'geo',
- position: [position.longitude, position.latitude],
- },
- },
- ];
-}
+import {BehaviorSubject, from} from 'rxjs';
+import {pauseWhen} from '../../../util/pause-when';
+import {map, retry, startWith, take} from 'rxjs/operators';
+import {SCSearchFilter, SCSearchSort} from '@openstapps/core';
/**
* Presents a list of places for eating/drinking
@@ -41,9 +27,10 @@ function asSortQuery(position: MapPosition): SCSearchSort[] {
selector: 'stapps-food-data-list',
templateUrl: 'food-data-list.html',
styleUrls: ['food-data-list.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class FoodDataListComponent implements AfterViewInit {
- @ViewChild(SearchPageComponent) searchPage: SearchPageComponent;
+export class FoodDataListComponent {
+ isNotInView$ = new BehaviorSubject(true);
forcedFilter: SCSearchFilter = {
arguments: {
@@ -82,20 +69,43 @@ export class FoodDataListComponent implements AfterViewInit {
type: 'boolean',
};
- sortQuery = this.positionService.getCurrentLocation({enableHighAccuracy: false}).then(asSortQuery);
+ sortQuery = this.positionService
+ .watchCurrentLocation({
+ enableHighAccuracy: false,
+ maximumAge: 1000,
+ })
+ .pipe(
+ pauseWhen(this.isNotInView$),
+ retry({
+ delay: () => from(Geolocation.checkPermissions()),
+ }),
+ map(({longitude, latitude}) => [
+ {
+ type: 'distance',
+ order: 'asc',
+ arguments: {
+ field: 'geo',
+ position: [longitude, latitude],
+ },
+ },
+ ]),
+ take(1),
+ startWith([
+ {
+ arguments: {field: 'name'},
+ order: 'asc',
+ type: 'ducet',
+ },
+ ]),
+ );
constructor(private readonly positionService: PositionService) {}
- async ngAfterViewInit() {
- const canAccessLocation = await Geolocation.checkPermissions()
- .then(it => it.coarseLocation === 'granted' || it.location === 'granted')
- .catch(() => false);
- this.searchPage.showDefaultData = true;
- this.searchPage.loading = true;
- if (!canAccessLocation) {
- await this.searchPage.fetchAndUpdateItems();
- }
- this.searchPage.sortQuery = await this.sortQuery;
- await this.searchPage.fetchAndUpdateItems();
+ async ionViewWillEnter() {
+ this.isNotInView$.next(false);
+ }
+
+ ionViewWillLeave() {
+ this.isNotInView$.next(true);
}
}
diff --git a/frontend/app/src/app/modules/data/list/food-data-list.html b/frontend/app/src/app/modules/data/list/food-data-list.html
index 4dd08fb9..9b47abfa 100644
--- a/frontend/app/src/app/modules/data/list/food-data-list.html
+++ b/frontend/app/src/app/modules/data/list/food-data-list.html
@@ -1,7 +1,8 @@
diff --git a/frontend/app/src/app/modules/data/list/food-data-list.scss b/frontend/app/src/app/modules/data/list/food-data-list.scss
new file mode 100644
index 00000000..92d692cd
--- /dev/null
+++ b/frontend/app/src/app/modules/data/list/food-data-list.scss
@@ -0,0 +1,3 @@
+:host {
+ display: contents;
+}
diff --git a/frontend/app/src/app/modules/data/list/search-page.component.ts b/frontend/app/src/app/modules/data/list/search-page.component.ts
index 7ffddaf8..375cd49e 100644
--- a/frontend/app/src/app/modules/data/list/search-page.component.ts
+++ b/frontend/app/src/app/modules/data/list/search-page.component.ts
@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
-import {Component, DestroyRef, inject, Input, OnInit} from '@angular/core';
+import {Component, DestroyRef, inject, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Keyboard} from '@capacitor/keyboard';
import {AlertController} from '@ionic/angular';
@@ -45,7 +45,7 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
styleUrls: ['search-page.scss'],
providers: [ContextMenuService],
})
-export class SearchPageComponent implements OnInit {
+export class SearchPageComponent implements OnInit, OnChanges {
@Input() title = 'search.title';
@Input() placeholder = 'search.search_bar.placeholder';
@@ -139,7 +139,7 @@ export class SearchPageComponent implements OnInit {
/**
* Api query sorting
*/
- sortQuery: SCSearchSort[] | undefined;
+ @Input() sortQuery: SCSearchSort[] | undefined;
destroy$ = inject(DestroyRef);
@@ -157,6 +157,12 @@ export class SearchPageComponent implements OnInit {
private readonly configProvider: ConfigProvider,
) {}
+ async ngOnChanges(changes: SimpleChanges) {
+ if ('sortQuery' in changes) {
+ await this.fetchAndUpdateItems();
+ }
+ }
+
/**
* Fetches items with set query configuration
* @param append If true fetched data gets appended to existing, override otherwise (default false)