diff --git a/covas_mobile/android/app/src/main/AndroidManifest.xml b/covas_mobile/android/app/src/main/AndroidManifest.xml
index 71290e3..510d7ba 100644
--- a/covas_mobile/android/app/src/main/AndroidManifest.xml
+++ b/covas_mobile/android/app/src/main/AndroidManifest.xml
@@ -6,6 +6,9 @@
android:label="covas_mobile"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
+
NSLocationWhenInUseUsageDescription
Your location is needed for showing nearby events
+ GADApplicationIdentifier
+ ca-app-pub-4855855675386260~3438207239
+
diff --git a/covas_mobile/lib/classes/ad_helper.dart b/covas_mobile/lib/classes/ad_helper.dart
new file mode 100644
index 0000000..61bd66c
--- /dev/null
+++ b/covas_mobile/lib/classes/ad_helper.dart
@@ -0,0 +1,27 @@
+import 'package:google_mobile_ads/google_mobile_ads.dart';
+import 'package:flutter_dotenv/flutter_dotenv.dart';
+
+class AdHelper {
+ static Future createBannerAd(Function setStateCallback) async {
+ await dotenv.load(fileName: ".env");
+ final adUnitId = dotenv.env['AD_UNIT_ID'] ?? '';
+
+ BannerAd bannerAd = BannerAd(
+ adUnitId: adUnitId,
+ size: AdSize.banner,
+ request: AdRequest(),
+ listener: BannerAdListener(
+ onAdLoaded: (ad) {
+ setStateCallback(() {});
+ },
+ onAdFailedToLoad: (ad, error) {
+ print('Banner Ad failed to load: $error');
+ ad.dispose();
+ },
+ ),
+ );
+
+ bannerAd.load();
+ return bannerAd;
+ }
+}
diff --git a/covas_mobile/lib/main.dart b/covas_mobile/lib/main.dart
index 25fc343..1d4665a 100644
--- a/covas_mobile/lib/main.dart
+++ b/covas_mobile/lib/main.dart
@@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
-
import 'dart:convert';
+
+import 'classes/ad_helper.dart';
+import 'package:google_mobile_ads/google_mobile_ads.dart';
+
import 'dart:io';
//import 'MyHomePage.dart';
@@ -14,7 +17,9 @@ import 'classes/alert.dart';
import 'variable/globals.dart' as globals;
import 'package:permission_handler/permission_handler.dart';
-void main() {
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await MobileAds.instance.initialize();
runApp(MyApp());
}
@@ -34,6 +39,7 @@ class LoginDemo extends StatefulWidget {
}
class _LoginDemoState extends State with ShowAlertDialog {
+ BannerAd? _bannerAd;
TextEditingController inputPseudo = TextEditingController();
TextEditingController inputPassword = TextEditingController();
Future _login(BuildContext context) async {
@@ -128,9 +134,15 @@ class _LoginDemoState extends State with ShowAlertDialog {
@override
void initState() {
+ super.initState();
+ AdHelper.createBannerAd(() => setState(() {})).then((ad) {
+ setState(() {
+ _bannerAd = ad;
+ });
+ });
+
_checkLocationPermission();
start();
- super.initState();
}
Future _checkLocationPermission() async {
@@ -183,6 +195,13 @@ class _LoginDemoState extends State with ShowAlertDialog {
body: SingleChildScrollView(
child: Column(
children: [
+ _bannerAd == null
+ ? SizedBox.shrink()
+ : SizedBox(
+ height: _bannerAd!.size.height.toDouble(),
+ width: _bannerAd!.size.width.toDouble(),
+ child: AdWidget(ad: _bannerAd!),
+ ),
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
@@ -252,7 +271,7 @@ class _LoginDemoState extends State with ShowAlertDialog {
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (_) => AddProfile()));
- })
+ }),
],
),
),
diff --git a/covas_mobile/lib/pages/AddProfile.dart b/covas_mobile/lib/pages/AddProfile.dart
index 96d374b..f97fae4 100644
--- a/covas_mobile/lib/pages/AddProfile.dart
+++ b/covas_mobile/lib/pages/AddProfile.dart
@@ -11,7 +11,12 @@ import '../classes/alert.dart';
import '../variable/globals.dart' as globals;
-void main() {
+import '../classes/ad_helper.dart';
+import 'package:google_mobile_ads/google_mobile_ads.dart';
+
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await MobileAds.instance.initialize();
runApp(MyApp());
}
@@ -33,6 +38,8 @@ class AddProfile extends StatefulWidget {
}
class _AddProfileState extends State with ShowAlertDialog {
+ BannerAd? _bannerAd;
+
TextEditingController inputUserName = TextEditingController();
TextEditingController inputName = TextEditingController();
@@ -133,6 +140,11 @@ class _AddProfileState extends State with ShowAlertDialog {
@override
void initState() {
super.initState();
+ AdHelper.createBannerAd(() => setState(() {})).then((ad) {
+ setState(() {
+ _bannerAd = ad;
+ });
+ });
}
final _formKey = GlobalKey();
@@ -154,6 +166,12 @@ class _AddProfileState extends State with ShowAlertDialog {
child: SingleChildScrollView(
child: Column(
children: [
+ _bannerAd == null
+ ? SizedBox.shrink()
+ : SizedBox(
+ height: _bannerAd!.size.height.toDouble(),
+ width: _bannerAd!.size.width.toDouble(),
+ child: AdWidget(ad: _bannerAd!)),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart
index 41c86fd..73711df 100644
--- a/covas_mobile/lib/pages/DisplayPictureScreen.dart
+++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart
@@ -14,7 +14,12 @@ import 'dart:convert';
import '../variable/globals.dart' as globals;
import '../classes/MyDrawer.dart';
-void main() {
+import '../classes/ad_helper.dart';
+import 'package:google_mobile_ads/google_mobile_ads.dart';
+
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await MobileAds.instance.initialize();
runApp(MyApp());
}
@@ -56,9 +61,18 @@ class DisplayPictureScreen extends StatefulWidget {
// A widget that displays the picture taken by the user.
class DisplayPictureScreenState extends State
with ShowDescImageAdd, ShowAlertDialog, TickerProviderStateMixin {
+ BannerAd? _bannerAd;
+
late AnimationController controller;
@override
void initState() {
+ super.initState();
+ AdHelper.createBannerAd(() => setState(() {})).then((ad) {
+ setState(() {
+ _bannerAd = ad;
+ });
+ });
+
controller = AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
@@ -68,7 +82,6 @@ class DisplayPictureScreenState extends State
setState(() {});
});
controller.repeat(reverse: false);
- super.initState();
_getEventInfosFromImage();
}
@@ -160,12 +173,17 @@ class DisplayPictureScreenState extends State
// The image is stored as a file on the device. Use the `Image.file`
// constructor with the given path to display the image.
drawer: MyDrawer(),
-
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
+ _bannerAd == null
+ ? SizedBox.shrink()
+ : SizedBox(
+ height: _bannerAd!.size.height.toDouble(),
+ width: _bannerAd!.size.width.toDouble(),
+ child: AdWidget(ad: _bannerAd!)),
Text(
'Analyse de l\'image en cours',
style: Theme.of(context).textTheme.titleLarge,
diff --git a/covas_mobile/lib/pages/EditEvent.dart b/covas_mobile/lib/pages/EditEvent.dart
index 8beb2e5..69d7691 100644
--- a/covas_mobile/lib/pages/EditEvent.dart
+++ b/covas_mobile/lib/pages/EditEvent.dart
@@ -22,7 +22,12 @@ import '../classes/eventAdded.dart';
import '../variable/globals.dart' as globals;
-void main() {
+import '../classes/ad_helper.dart';
+import 'package:google_mobile_ads/google_mobile_ads.dart';
+
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await MobileAds.instance.initialize();
runApp(MyApp());
}
@@ -54,6 +59,7 @@ class EditEvent extends StatefulWidget {
class _EditEventState extends State
with ShowAlertDialog, ShowEventDialog {
+ BannerAd? _bannerAd;
TextEditingController inputName = TextEditingController();
TextEditingController inputDate = TextEditingController();
@@ -159,177 +165,161 @@ class _EditEventState extends State
}
Future _updateEvent(BuildContext context) async {
- var name = inputName.text;
- var place = inputGeo.text;
- var description = inputDesc.text;
- List tags = List.from(_stringTagController.getTags as List);
- List organizers =
- List.from(_stringOrgaController.getTags as List);
-
- var startDateFormat = formatDate(startDatepicker.text);
- //DateTime startDateCompare = DateTime.parse(startDateFormat);
- DateTime dateNow = DateTime.now();
- var endDateFormat = formatDate(endDatepicker.text);
- var startDate =
- "${startDateFormat}T${startTimepicker.text.replaceAll('-', ':')}";
- var endDate = "${endDateFormat}T${endTimepicker.text.replaceAll('-', ':')}";
- DateTime startDateCompare = DateTime.parse(startDate);
- if (startDateCompare.isAfter(dateNow)) {
- SharedPreferences prefs = await SharedPreferences.getInstance();
- var accessToken = prefs.getString("access_token") ?? "";
-
- if (accessToken.isNotEmpty) {
- try {
- await dotenv.load();
- final ApiTokenGoogle = dotenv.env['PLACE_API_KEY'] ?? '';
- // Searchbox API for geocoding the place (No session token)
- final searchboxUrl = Uri.parse(
- 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${place}&key=${ApiTokenGoogle}');
-
- // Perform the request
- final searchboxResponse = await http.get(searchboxUrl);
-
- if (searchboxResponse.statusCode == 200) {
- final data = json.decode(searchboxResponse.body);
- print("data : ${data}");
-
- if (data['results'].isNotEmpty) {
- place = data['results'][0]['formatted_address'];
- final coordinates = data['results'][0]['geometry']['location'];
- final longitude = coordinates["lng"]; // Longitude
- final latitude = coordinates["lat"]; // Latitude
- var urlGet = Uri.parse(
- "${globals.api}/events/search?item=${name}&date_event=${startDate}&min_lat=$latitude&max_lat=$latitude"
- "&min_lon=$longitude&max_lon=$longitude");
-
- var responseGet = await http.get(urlGet, headers: {
- HttpHeaders.cookieHeader: 'access_token=${accessToken}'
- });
- if (responseGet.statusCode == 200) {
- var events = jsonDecode(utf8.decode(responseGet.bodyBytes));
- if (events.length > 0) {
- if (events[0]["id"] != widget.events!.id) {
- showAlertDialog(
- context, "Info evenement", "Evenement deja existant");
- }
-
- return;
- }
- }
-
- if (widget.imgPath.isNotEmpty) {
- final params = {
- 'expiration': '15552000',
- 'key': dotenv.env["IMGBB_API_KEY"],
- };
- print("Post Img");
- final urlPost = Uri.parse('https://api.imgbb.com/1/upload')
- .replace(queryParameters: params);
- File image = File(widget.imgPath);
- Uint8List _bytes = await image.readAsBytes();
- String _base64String = base64.encode(_bytes);
-
- final req = http.MultipartRequest('POST', urlPost)
- ..fields['image'] = _base64String;
-
- final stream = await req.send();
- final res = await http.Response.fromStream(stream);
-
- final status = res.statusCode;
- print("code status imgbb ${status}");
- if (status != 200) {
- showAlertDialog(context, "Erreur image", "Image non posté");
- return;
- }
- var body = json.decode(utf8.decode(res.bodyBytes));
- imgUrl = body["data"]["url"];
- }
- var urlPut =
- Uri.parse("${globals.api}/events/${widget.events!.id}");
- var responsePut = await http.put(urlPut,
- headers: {
- HttpHeaders.cookieHeader: 'access_token=${accessToken}',
- HttpHeaders.acceptHeader:
- 'application/json, text/plain, */*',
- HttpHeaders.contentTypeHeader: 'application/json'
- },
- body: jsonEncode({
- 'name': name,
- 'place': place,
- 'start_date': startDate,
- 'end_date': endDate,
- 'organizers': organizers,
- 'latitude': latitude,
- 'longitude': longitude,
- 'description': description,
- "imgUrl": imgUrl,
- "tags": tags
- }));
- print(responsePut.statusCode);
- if ((responsePut.statusCode == 200) ||
- (responsePut.statusCode == 201)) {
- showEventDialog(context, "Evenement ${name} modifie");
- } else {
- var text = "";
- switch (responsePut.statusCode) {
- case 400:
- {
- text = "Requête mal construite";
- }
- break;
- case 406:
- {
- text = "Mot de passe incorrect";
- }
- break;
- case 404:
- {
- text = "Utilisateur inconnu";
- }
- break;
- case 403:
- {
- text = "Utilisateur desactive";
- }
- break;
- case 410:
- {
- text = "Token invalide";
- }
- break;
- case 500:
- {
- text = "Probleme interne du serveur";
- }
- break;
- default:
- {
- text = "Probleme d'authentification inconnu";
- }
- break;
- }
- showAlertDialog(context, "Erreur serveur", text);
- }
- } else {
- showAlertDialog(
- context, "Erreur serveur", "Aucune donnée geographique");
- }
- } else {
- showAlertDialog(context, "Erreur serveur", "Mapbox non accessible");
- }
- } catch (e) {
- showAlertDialog(context, "Erreur serveur", "${e}");
- }
- } else {
- showAlertDialog(context, "Erreur utilisateur", "Champ vide");
- }
- } else {
- showAlertDialog(context, "Erreur evenement", "Evenement non futur");
+ if (!_isEventInFuture()) {
+ _showErrorDialog(context, "Erreur evenement", "Evenement non futur");
+ return;
}
+
+ final accessToken = await _getAccessToken();
+ if (accessToken.isEmpty) {
+ _showErrorDialog(context, "Erreur utilisateur", "Champ vide");
+ return;
+ }
+
+ try {
+ await dotenv.load();
+ final geolocation = await _fetchGeolocation();
+ if (geolocation == null) {
+ _showErrorDialog(
+ context, "Erreur serveur", "Aucune donnée geographique");
+ return;
+ }
+
+ if (await _isDuplicateEvent(accessToken, geolocation)) {
+ _showErrorDialog(context, "Info evenement", "Evenement deja existant");
+ return;
+ }
+
+ if (widget.imgPath.isNotEmpty) {
+ imgUrl = await _uploadImage(widget.imgPath);
+ if (imgUrl.isEmpty) {
+ _showErrorDialog(context, "Erreur image", "Image non postée");
+ return;
+ }
+ }
+
+ await _updateEventData(accessToken, geolocation);
+ showEventDialog(context, "Evenement ${inputName.text} modifie");
+ } catch (e) {
+ _showErrorDialog(context, "Erreur serveur", "$e");
+ }
+ }
+
+ bool _isEventInFuture() {
+ DateTime startDateCompare = DateTime.parse(
+ "${formatDate(startDatepicker.text)}T${startTimepicker.text.replaceAll('-', ':')}");
+ return startDateCompare.isAfter(DateTime.now());
+ }
+
+ Future _getAccessToken() async {
+ final prefs = await SharedPreferences.getInstance();
+ return prefs.getString("access_token") ?? "";
+ }
+
+ Future