2 Commits 5162e4ff20 ... 14bab8b01c

Auteur SHA1 Bericht Datum
  Marcin Jaborski 14bab8b01c Find place for challenge with geoflutterfire 3 jaren geleden
  Marcin Jaborski 9d62216219 Challenge widget 3 jaren geleden

+ 31 - 0
app/lib/challenges/challenge.dart

@@ -0,0 +1,31 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:flutter/material.dart';
+import 'package:latlong2/latlong.dart';
+
+import '../navigation/navigation_page.dart';
+
+Widget buildChallenge(DocumentSnapshot<Map<String, dynamic>> data, BuildContext context) {
+  final LatLng coordinates =
+      LatLng(data.get('location')['geopoint'].latitude, data.get('location')['geopoint'].longitude);
+  return Center(
+    child: Column(
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        const Text('Your challenge for this week:'),
+        Text(data.get('name')),
+        TextButton(
+            onPressed: () {
+              Navigator.push(
+                context,
+                MaterialPageRoute(
+                  builder: (context) => NavigationPage(
+                    destination: coordinates,
+                  ),
+                ),
+              );
+            },
+            child: const Text('Navigate me'))
+      ],
+    ),
+  );
+}

+ 35 - 0
app/lib/challenges/challenge_page.dart

@@ -0,0 +1,35 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:flutter/material.dart';
+import 'package:physigo/challenges/challenges_utils.dart';
+import 'package:physigo/challenges/challenge.dart';
+
+class ChallengePage extends StatelessWidget {
+  const ChallengePage({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
+        future: ChallengesUtils.getChallenge(),
+        builder: (context, snapshot) {
+          switch (snapshot.connectionState) {
+            case ConnectionState.waiting:
+              return const Center(
+                child: Text('Getting challenges...'),
+              );
+            case ConnectionState.done:
+              if (snapshot.hasError) {
+                return const Text('Error occurred');
+              }
+              if (snapshot.hasData) {
+                return buildChallenge(snapshot.data!, context);
+              }
+              return const Text('No data');
+            default:
+              return const Text('Dunno');
+          }
+        },
+      ),
+    );
+  }
+}

+ 67 - 0
app/lib/challenges/challenges_utils.dart

@@ -0,0 +1,67 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:geoflutterfire/geoflutterfire.dart';
+import 'dart:math';
+
+class ChallengesUtils {
+  static final geo = Geoflutterfire();
+  static final _firestore = FirebaseFirestore.instance;
+
+  static Future<DocumentSnapshot<Map<String, dynamic>>> getChallenge() async {
+    Future<DocumentSnapshot<Map<String, dynamic>>> challenge;
+    if (await shouldGenerateChallenge()) {
+      challenge = generateChallenge();
+    } else {
+      final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx');
+      challenge = user.get().then((value) => value.get('weekly_place').get());
+    }
+    return challenge;
+  }
+
+  static Future<bool> shouldGenerateChallenge() async {
+    final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx');
+    DateTime now = DateTime.now();
+    DateTime today = DateTime(now.year, now.month, now.day);
+    DateTime lastMonday = today.subtract(Duration(days: today.weekday - 1));
+    int secondsSinceEpoch = lastMonday.millisecondsSinceEpoch ~/ 1000;
+    bool shouldGenerate = await user.get().then((value) {
+      final dif = secondsSinceEpoch - value.get('last_challenge_date').seconds;
+      return dif / 3600 / 24 > 7;
+    });
+    return Future.value(shouldGenerate);
+  }
+
+  static Future<DocumentSnapshot<Map<String, dynamic>>> generateChallenge() async {
+    final user = await _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').get();
+    Query<Map<String, dynamic>> places = _firestore.collection('Places');
+    double innerRadius = 3;
+    double outerRadius = 5;
+    String randomPlaceID = '';
+
+    Stream<List<DocumentSnapshot>> possiblePlaces = geo.collection(collectionRef: places).within(
+        center: geo.point(latitude: user.get('address').latitude, longitude: user.get('address').longitude),
+        radius: outerRadius,
+        field: 'location',
+        strictMode: true);
+
+    Stream<List<DocumentSnapshot>> placesTooClose = geo.collection(collectionRef: places).within(
+        center: geo.point(latitude: user.get('address').latitude, longitude: user.get('address').longitude),
+        radius: innerRadius,
+        field: 'location',
+        strictMode: true);
+
+    List<DocumentSnapshot<Object?>> possiblePlacesList = await possiblePlaces.first;
+    List<DocumentSnapshot<Object?>> placesTooCloseList = await placesTooClose.first;
+    final ids = <String>{};
+    for (DocumentSnapshot<Object?> element in placesTooCloseList) {
+      ids.add(element.id);
+    }
+    possiblePlacesList.retainWhere((element) => !ids.contains(element.id));
+    int numOfPlaces = possiblePlacesList.length;
+    randomPlaceID = possiblePlacesList[Random().nextInt(numOfPlaces)].id;
+    _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').update({
+      'weekly_place': _firestore.collection('Places').doc(randomPlaceID),
+      'last_challenge_date': Timestamp.now(),
+    });
+    return _firestore.collection('Places').doc(randomPlaceID).get();
+  }
+}

+ 1 - 1
app/lib/main.dart

@@ -2,7 +2,7 @@ import 'package:firebase_core/firebase_core.dart';
 import 'package:flutter/material.dart';
 import 'package:latlong2/latlong.dart';
 import 'navigation/navigation_page.dart';
-import 'navigation/challenge_page.dart';
+import 'challenges/challenge_page.dart';
 
 import 'firebase_options.dart';
 

+ 0 - 23
app/lib/navigation/challenge_page.dart

@@ -1,23 +0,0 @@
-import 'package:cloud_firestore/cloud_firestore.dart';
-import 'package:flutter/material.dart';
-import 'package:physigo/navigation/utils/challenges_utils.dart';
-
-class ChallengePage extends StatelessWidget {
-
-  const ChallengePage({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-      body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
-        future: ChallengesUtils.getChallenge(),
-        builder: (context, snapshot) {
-          if(snapshot.hasData) {
-            print(snapshot.data?.get('name'));
-          }
-          return const Text('Challenges are here');
-        },
-      ),
-    );
-  }
-}

+ 0 - 67
app/lib/navigation/utils/challenges_utils.dart

@@ -1,67 +0,0 @@
-import 'package:cloud_firestore/cloud_firestore.dart';
-import 'dart:math';
-
-class ChallengesUtils {
-  static Future<DocumentSnapshot<Map<String, dynamic>>> getChallenge() async {
-    Future<DocumentSnapshot<Map<String, dynamic>>> challenge;
-    if(await shouldGenerateChallenge()){
-      challenge = generateChallenge();
-    } else {
-      final user = FirebaseFirestore.instance
-          .collection('Users')
-          .doc('tlmysIvwTBaoZKWqBofx');
-      challenge = user.get().then((value) => value.get('weekly_place').get());
-    }
-    return challenge;
-  }
-
-  static Future<bool> shouldGenerateChallenge() async {
-    final user = FirebaseFirestore.instance
-        .collection('Users')
-        .doc('tlmysIvwTBaoZKWqBofx');
-    DateTime now = DateTime.now();
-    int secondsSinceEpoch = now.millisecondsSinceEpoch ~/ 1000;
-    bool shouldGenerate = await user.get().then((value) {
-      final dif = secondsSinceEpoch - value.get('last_challenge_date').seconds;
-      return dif / 3600 / 24 > 7;
-    });
-    return Future.value(shouldGenerate);
-  }
-
-  static Future<DocumentSnapshot<Map<String, dynamic>>> generateChallenge() {
-    final user = FirebaseFirestore.instance
-        .collection('Users')
-        .doc('tlmysIvwTBaoZKWqBofx');
-    return user.get().then((value) {
-      double lat = 0.0144927536231884;
-      double lon = 0.0181818181818182;
-      double userLat = value.get('address').latitude;
-      double userLon = value.get('address').longitude;
-
-      double lowerLat = userLat - (lat * 5);
-      double lowerLon = userLon - (lon * 5);
-      double upperLat = userLat + (lat * 5);
-      double upperLon = userLon + (lon * 5);
-
-      GeoPoint lesserGeoPoint = GeoPoint(lowerLat, lowerLon);
-      GeoPoint greaterGeoPoint = GeoPoint(upperLat, upperLon);
-
-      return FirebaseFirestore.instance
-          .collection('Places')
-          .where('location', isGreaterThan: lesserGeoPoint)
-          .where('location', isLessThan: greaterGeoPoint)
-          .get()
-          .then((snapshot) {
-        int numOfPlaces = snapshot.docs.length;
-        String id = snapshot.docs[Random().nextInt(numOfPlaces)].id;
-        print('updating');
-        user.update({
-          'weekly_place':
-              FirebaseFirestore.instance.collection('Places').doc(id),
-          'last_challenge_date': Timestamp.now(),
-        });
-        return FirebaseFirestore.instance.collection('Places').doc(id).get();
-      });
-    });
-  }
-}

+ 14 - 0
app/pubspec.lock

@@ -142,6 +142,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  geoflutterfire:
+    dependency: "direct main"
+    description:
+      name: geoflutterfire
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.3"
   geolocator:
     dependency: transitive
     description:
@@ -296,6 +303,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.1+1"
+  rxdart:
+    dependency: transitive
+    description:
+      name: rxdart
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.27.3"
   sky_engine:
     dependency: transitive
     description: flutter

+ 1 - 0
app/pubspec.yaml

@@ -39,6 +39,7 @@ dependencies:
   flutter_map: ^0.14.0
   flutter_map_location_marker: ^3.1.0
   cloud_firestore: ^3.1.14
+  geoflutterfire: ^3.0.3
 
 dev_dependencies:
   flutter_test: