upgrade mapbox
This commit is contained in:
209
covas_mobile_new/lib/classes/MyDrawer.dart
Normal file
209
covas_mobile_new/lib/classes/MyDrawer.dart
Normal file
@@ -0,0 +1,209 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:io';
|
||||
import '../pages/EditProfile.dart';
|
||||
import '../pages/EditSettings.dart';
|
||||
import '../pages/ListItemMenu.dart';
|
||||
import 'alert.dart';
|
||||
|
||||
import '../variable/globals.dart' as globals;
|
||||
|
||||
import '../pages/LoginDemo.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
|
||||
import 'package:encrypt_shared_preferences/provider.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
import '../locale_provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class MyDrawer extends StatelessWidget with ShowAlertDialog {
|
||||
Future<void> logout(BuildContext context) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var accessToken = prefs.getString("access_token") ?? "";
|
||||
|
||||
if (accessToken.isNotEmpty) {
|
||||
var url = Uri.parse("${globals.api}/token");
|
||||
|
||||
try {
|
||||
var response = await http.delete(url, headers: {
|
||||
"Content-Type": "application/json",
|
||||
HttpHeaders.cookieHeader: "access_token=${accessToken}"
|
||||
});
|
||||
|
||||
print("Status code logout ${response.statusCode}");
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
await prefs.remove("access_token");
|
||||
await dotenv.load(fileName: ".env"); // Load .env file
|
||||
|
||||
final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? '';
|
||||
if (keyEncrypt.isNotEmpty) {
|
||||
await EncryptedSharedPreferences.initialize(keyEncrypt);
|
||||
var sharedPref = EncryptedSharedPreferences.getInstance();
|
||||
String username = sharedPref.getString("username") ?? "";
|
||||
String password = sharedPref.getString("password") ?? "";
|
||||
if ((username.isEmpty) || (password.isEmpty)) {
|
||||
sharedPref.remove("username");
|
||||
sharedPref.remove("password");
|
||||
}
|
||||
}
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => LoginDemo()),
|
||||
(route) => false, // Remove all previous routes
|
||||
);
|
||||
} else {
|
||||
String errorMessage;
|
||||
switch (response.statusCode) {
|
||||
case 400:
|
||||
errorMessage = "Bad Request: Please check your input.";
|
||||
break;
|
||||
case 401:
|
||||
errorMessage = "Unauthorized: Invalid credentials.";
|
||||
break;
|
||||
case 403:
|
||||
errorMessage = "Forbidden: You don't have permission.";
|
||||
break;
|
||||
case 404:
|
||||
errorMessage = "Not Found: The resource was not found.";
|
||||
break;
|
||||
case 500:
|
||||
errorMessage =
|
||||
"Server Error: Something went wrong on the server.";
|
||||
break;
|
||||
default:
|
||||
errorMessage = "Unexpected Error: ${response.statusCode}";
|
||||
break;
|
||||
}
|
||||
print(errorMessage);
|
||||
showAlertDialog(context, "Error", errorMessage);
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error: $e");
|
||||
showAlertDialog(
|
||||
context, "Error", "An error occurred. Please try again.");
|
||||
}
|
||||
} else {
|
||||
showAlertDialog(context, "Error", "Invalid token.");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
final localeProvider = Provider.of<LocaleProvider>(context);
|
||||
return Drawer(
|
||||
child: ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
// Drawer Header
|
||||
DrawerHeader(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue,
|
||||
),
|
||||
child: Text(
|
||||
'Menu',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Drawer Items
|
||||
ListTile(
|
||||
leading: Icon(Icons.home),
|
||||
title: Text(loc?.home ?? "Home"),
|
||||
onTap: () {
|
||||
Navigator.pushReplacement(
|
||||
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
|
||||
|
||||
/// Close the drawer
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.settings),
|
||||
title: Text(loc?.settings ?? 'Settings'),
|
||||
onTap: () {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => EditSettings())); // Close the drawer
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.account_circle),
|
||||
title: Text(loc?.update_profile ?? 'Update profile'),
|
||||
onTap: () {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => EditProfile())); // Close the drawer
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.language),
|
||||
title: Text(loc?.language ?? 'Language'),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => AlertDialog(
|
||||
title: Text(loc?.select_language ?? 'Select Language'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: Icon(Icons.flag),
|
||||
title: Text(loc?.french ?? 'Français'),
|
||||
onTap: () {
|
||||
Provider.of<LocaleProvider>(context, listen: false)
|
||||
.setLocale(const Locale('fr'));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.flag_outlined),
|
||||
title: Text(loc?.english ?? 'English'),
|
||||
onTap: () {
|
||||
Provider.of<LocaleProvider>(context, listen: false)
|
||||
.setLocale(const Locale('en'));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.flag_outlined),
|
||||
title: Text(loc?.german ?? 'German'),
|
||||
onTap: () {
|
||||
Provider.of<LocaleProvider>(context, listen: false)
|
||||
.setLocale(const Locale('de'));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.info),
|
||||
title: Text(loc?.about ?? 'About'),
|
||||
onTap: () {
|
||||
showAlertDialog(context, loc?.about ?? 'About',
|
||||
"Version 0.0.1"); // Close the drawer
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.logout),
|
||||
title: Text(loc?.log_out ?? 'Log out'),
|
||||
onTap: () async {
|
||||
logout(context);
|
||||
// Close the drawer
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
27
covas_mobile_new/lib/classes/ad_helper.dart
Normal file
27
covas_mobile_new/lib/classes/ad_helper.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
class AdHelper {
|
||||
static Future<BannerAd> 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;
|
||||
}
|
||||
}
|
67
covas_mobile_new/lib/classes/addEventImage.dart
Normal file
67
covas_mobile_new/lib/classes/addEventImage.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'events.dart';
|
||||
import '../variable/globals.dart' as globals;
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
mixin ShowDescImageAdd<T extends StatefulWidget> on State<T> {
|
||||
Future<void> addEvents(var events) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var accessToken = prefs.getString("access_token") ?? "";
|
||||
List<String> send = ["toto"];
|
||||
|
||||
if (accessToken.isNotEmpty) {
|
||||
var urlPut = Uri.parse("${globals.api}/events");
|
||||
print("start date : ${events["start_date"]}");
|
||||
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': events["name"],
|
||||
'place': events["place"],
|
||||
'start_date': events['date'],
|
||||
'end_date': events['date'],
|
||||
'organizers': send,
|
||||
'latitude': '0.0',
|
||||
'longitude': '0.0',
|
||||
}));
|
||||
|
||||
print("http put code status : ${responsePut.statusCode}");
|
||||
print("http put body : ${responsePut.body}");
|
||||
}
|
||||
}
|
||||
|
||||
void showDescImageAddDialog(BuildContext context, var events) {
|
||||
// Create AlertDialog
|
||||
String name = events['name'];
|
||||
AlertDialog dialog = AlertDialog(
|
||||
title: Text("Ajouter un evenement"),
|
||||
content: Text("${name} n'a pas été trouvé. Voulez-vous l'ajouter ? "),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text("Annuler"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop("Yes, Of course!"); // Return value
|
||||
}),
|
||||
TextButton(
|
||||
child: Text("Oui"),
|
||||
onPressed: () {
|
||||
addEvents(events); // Return value
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
// Call showDialog function to show dialog.
|
||||
Future futureValue = showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return dialog;
|
||||
});
|
||||
}
|
||||
}
|
29
covas_mobile_new/lib/classes/alert.dart
Normal file
29
covas_mobile_new/lib/classes/alert.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
mixin ShowAlertDialog {
|
||||
void showAlertDialog(BuildContext context, String title, String text) {
|
||||
// Create AlertDialog
|
||||
AlertDialog dialog = AlertDialog(
|
||||
title: Text(title),
|
||||
content: Text(text),
|
||||
actions: [
|
||||
ElevatedButton(
|
||||
child: Text("OK"),
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 15, fontWeight: FontWeight.normal)),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop("Yes, Of course!"); // Return value
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
// Call showDialog function to show dialog.
|
||||
Future futureValue = showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return dialog;
|
||||
});
|
||||
}
|
||||
}
|
141
covas_mobile_new/lib/classes/auth_service.dart
Normal file
141
covas_mobile_new/lib/classes/auth_service.dart
Normal file
@@ -0,0 +1,141 @@
|
||||
import 'dart:convert';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../variable/globals.dart' as globals;
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:encrypt_shared_preferences/provider.dart';
|
||||
import '../pages/LoginDemo.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
|
||||
|
||||
class AuthService {
|
||||
// Login with username and password
|
||||
Future<bool> login(String username, String password,
|
||||
{bool rememberMe = false}) async {
|
||||
final url = Uri.parse("${globals.api}/token");
|
||||
|
||||
try {
|
||||
final response = await http.post(
|
||||
url,
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: {"username": username, "password": password},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
if (rememberMe) {
|
||||
await dotenv.load(fileName: ".env"); // Load .env file
|
||||
|
||||
final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? '';
|
||||
if (keyEncrypt.isNotEmpty) {
|
||||
await EncryptedSharedPreferences.initialize(keyEncrypt);
|
||||
var sharedPref = EncryptedSharedPreferences.getInstance();
|
||||
sharedPref.setString("username", username);
|
||||
sharedPref.setString("password", password);
|
||||
}
|
||||
}
|
||||
final cookies = response.headers["set-cookie"]?.split(";") ?? [];
|
||||
|
||||
for (final cookie in cookies) {
|
||||
final cookieParts = cookie.split(",");
|
||||
for (final part in cookieParts) {
|
||||
final keyValue = part.split("=");
|
||||
if (keyValue.length == 2 && keyValue[0] == "access_token") {
|
||||
prefs.setString("access_token", keyValue[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
print("Login error: $e");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Logout
|
||||
Future<void> logout() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove("access_token");
|
||||
}
|
||||
|
||||
Future<bool> isLoggedIn() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final accessToken = prefs.getString("access_token");
|
||||
|
||||
if (accessToken == null || accessToken.isEmpty) {
|
||||
print("No access token found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
print("Checking token validity...");
|
||||
var url = Uri.parse("${globals.api}/token");
|
||||
|
||||
try {
|
||||
final response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
HttpHeaders.cookieHeader: "access_token=$accessToken",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print("Token is valid.");
|
||||
return true;
|
||||
} else {
|
||||
print("Token is invalid. Status code: ${response.statusCode}");
|
||||
await dotenv.load(fileName: ".env"); // Load .env file
|
||||
|
||||
final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? '';
|
||||
if (keyEncrypt.isNotEmpty) {
|
||||
await EncryptedSharedPreferences.initialize(keyEncrypt);
|
||||
var sharedPref = EncryptedSharedPreferences.getInstance();
|
||||
String username = sharedPref.getString("username") ?? "";
|
||||
String password = sharedPref.getString("password") ?? "";
|
||||
if ((username.isEmpty) || (password.isEmpty)) {
|
||||
sharedPref.remove("username");
|
||||
sharedPref.remove("password");
|
||||
await prefs.remove("access_token"); // Clear invalid token
|
||||
return false;
|
||||
} else {
|
||||
return login(username, password);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error while checking token: $e");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkTokenStatus(context) async {
|
||||
bool loggedIn = await isLoggedIn();
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
||||
if (!loggedIn) {
|
||||
await prefs.remove("access_token"); // Correctly remove the token
|
||||
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => LoginDemo()),
|
||||
(route) => false, // Remove all previous routes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Get stored access token
|
||||
Future<String?> getAccessToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("access_token");
|
||||
}
|
||||
|
||||
// Login with Google
|
||||
}
|
34
covas_mobile_new/lib/classes/eventAdded.dart
Normal file
34
covas_mobile_new/lib/classes/eventAdded.dart
Normal file
@@ -0,0 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../pages/ListItemMenu.dart';
|
||||
|
||||
mixin ShowEventDialog<T extends StatefulWidget> on State<T> {
|
||||
void showEventDialog(BuildContext context, String text) {
|
||||
// Create AlertDialog
|
||||
AlertDialog dialog = AlertDialog(
|
||||
title: Text("Evenement ajoute"),
|
||||
content: Text(text),
|
||||
actions: [
|
||||
ElevatedButton(
|
||||
child: Text("OK"),
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 15, fontWeight: FontWeight.normal)),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => ListItemMenu())); // Return value
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
// Call showDialog function to show dialog.
|
||||
Future futureValue = showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return dialog;
|
||||
});
|
||||
}
|
||||
}
|
54
covas_mobile_new/lib/classes/events.dart
Normal file
54
covas_mobile_new/lib/classes/events.dart
Normal file
@@ -0,0 +1,54 @@
|
||||
class Events {
|
||||
String? id;
|
||||
String? name;
|
||||
String? place;
|
||||
String? startDate;
|
||||
String? endDate;
|
||||
String? description;
|
||||
String? link;
|
||||
String? ticket;
|
||||
double? latitude;
|
||||
double? longitude;
|
||||
List<String>? tags;
|
||||
List<String>? organizers;
|
||||
String? imgUrl;
|
||||
int? interestedCount;
|
||||
bool? interested;
|
||||
Events(
|
||||
{this.place,
|
||||
this.id,
|
||||
this.name,
|
||||
this.startDate,
|
||||
this.description,
|
||||
this.endDate,
|
||||
this.tags,
|
||||
this.latitude,
|
||||
this.longitude,
|
||||
this.organizers,
|
||||
this.link,
|
||||
this.ticket,
|
||||
this.imgUrl,
|
||||
this.interestedCount,
|
||||
this.interested});
|
||||
|
||||
Events.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'] as String?;
|
||||
name = json['name'] as String?;
|
||||
place = json['place'] as String?;
|
||||
startDate = json['start_date'] as String?;
|
||||
endDate = json['end_date'] as String?;
|
||||
description = json['description'] as String?;
|
||||
latitude = (json['latitude'] as num?)?.toDouble(); // Safely cast to double
|
||||
longitude =
|
||||
(json['longitude'] as num?)?.toDouble(); // Safely cast to double
|
||||
tags = (json['tags'] as List<dynamic>?)
|
||||
?.cast<String>(); // Convert List<dynamic> to List<String>
|
||||
organizers = (json['organizers'] as List<dynamic>?)
|
||||
?.cast<String>(); // Convert List<dynamic> to List<String>
|
||||
imgUrl = json['imgUrl'] as String?;
|
||||
link = json['link'] as String?;
|
||||
ticket = json['ticket'] as String?;
|
||||
interested = json['interested'] as bool?;
|
||||
interestedCount = json['interested_count'] as int?;
|
||||
}
|
||||
}
|
67
covas_mobile_new/lib/classes/getEventImage.dart
Normal file
67
covas_mobile_new/lib/classes/getEventImage.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'events.dart';
|
||||
import '../variable/globals.dart' as globals;
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
mixin ShowDescImageGet<T extends StatefulWidget> on State<T> {
|
||||
Future<void> getEvents(var events) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var accessToken = prefs.getString("access_token") ?? "";
|
||||
List<String> send = ["toto"];
|
||||
|
||||
if (accessToken.isNotEmpty) {
|
||||
var urlPut = Uri.parse("${globals.api}/events");
|
||||
print("start date : ${events["start_date"]}");
|
||||
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': events["name"],
|
||||
'place': events["place"],
|
||||
'start_date': events['date'],
|
||||
'end_date': events['date'],
|
||||
'organizers': send,
|
||||
'latitude': '0.0',
|
||||
'longitude': '0.0',
|
||||
}));
|
||||
|
||||
print("http put code status : ${responsePut.statusCode}");
|
||||
print("http put body : ${responsePut.body}");
|
||||
}
|
||||
}
|
||||
|
||||
void showDescImageGetDialog(BuildContext context, var events) {
|
||||
// Create AlertDialog
|
||||
String name = events['name'];
|
||||
AlertDialog dialog = AlertDialog(
|
||||
title: Text("Voir la description de l'evenement"),
|
||||
content: Text("${name} a été trouvé. Voulez-vous voir sa description ? "),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text("Annuler"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop("Yes, Of course!"); // Return value
|
||||
}),
|
||||
TextButton(
|
||||
child: Text("Oui"),
|
||||
onPressed: () {
|
||||
getEvents(events); // Return value
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
// Call showDialog function to show dialog.
|
||||
Future futureValue = showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return dialog;
|
||||
});
|
||||
}
|
||||
}
|
91
covas_mobile_new/lib/classes/notification_service.dart
Normal file
91
covas_mobile_new/lib/classes/notification_service.dart
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
import 'package:timezone/data/latest_all.dart' as tz;
|
||||
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class NotificationService {
|
||||
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
/// Initialisation (à appeler dans main())
|
||||
static Future<void> initialize() async {
|
||||
tz.initializeTimeZones();
|
||||
|
||||
const AndroidInitializationSettings androidInitSettings =
|
||||
AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
|
||||
const InitializationSettings initSettings = InitializationSettings(
|
||||
android: androidInitSettings,
|
||||
iOS: DarwinInitializationSettings(),
|
||||
);
|
||||
|
||||
await _notificationsPlugin.initialize(initSettings);
|
||||
|
||||
// Demande les permissions au lancement
|
||||
await requestPermissions();
|
||||
}
|
||||
|
||||
/// Demander les permissions (Android 13+ et iOS)
|
||||
static Future<void> requestPermissions() async {
|
||||
// Android 13+
|
||||
final androidImplementation =
|
||||
_notificationsPlugin.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>();
|
||||
await androidImplementation?.requestNotificationsPermission();
|
||||
|
||||
// iOS
|
||||
final iosImplementation =
|
||||
_notificationsPlugin.resolvePlatformSpecificImplementation<
|
||||
IOSFlutterLocalNotificationsPlugin>();
|
||||
await iosImplementation?.requestPermissions(
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// Planifie une notification 1h avant l’évènement
|
||||
static Future<void> scheduleEventNotification({
|
||||
required String eventId,
|
||||
required String title,
|
||||
required String body,
|
||||
required DateTime eventDate,
|
||||
}) async {
|
||||
final scheduledDate = eventDate.subtract(const Duration(hours: 1));
|
||||
|
||||
if (scheduledDate.isBefore(DateTime.now())) {
|
||||
// Trop tard pour notifier
|
||||
return;
|
||||
}
|
||||
|
||||
await _notificationsPlugin.zonedSchedule(
|
||||
eventId.hashCode, // identifiant unique pour l’évènement
|
||||
title,
|
||||
body,
|
||||
tz.TZDateTime.from(scheduledDate, tz.local),
|
||||
const NotificationDetails(
|
||||
android: AndroidNotificationDetails(
|
||||
'events_channel',
|
||||
'Events',
|
||||
channelDescription: 'Favorite event notifications ',
|
||||
importance: Importance.high,
|
||||
priority: Priority.high,
|
||||
),
|
||||
iOS: DarwinNotificationDetails(),
|
||||
),
|
||||
androidScheduleMode: AndroidScheduleMode
|
||||
.inexactAllowWhileIdle, // évite l'erreur Exact Alarm
|
||||
uiLocalNotificationDateInterpretation:
|
||||
UILocalNotificationDateInterpretation.absoluteTime,
|
||||
matchDateTimeComponents: DateTimeComponents.dateAndTime,
|
||||
);
|
||||
}
|
||||
|
||||
/// Annule une notification planifiée
|
||||
static Future<void> cancel(String eventId) async {
|
||||
await _notificationsPlugin.cancel(eventId.hashCode);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user