refactor: Global evolution 15/05/2023
parent
662838c8ec
commit
f0d575e2f3
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
|
|
@ -1,6 +1,9 @@
|
||||||
PODS:
|
PODS:
|
||||||
- camera_avfoundation (0.0.1):
|
- camera_avfoundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- connectivity_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- ReachabilitySwift
|
||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
|
|
@ -23,6 +26,7 @@ PODS:
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- permission_handler_apple (9.0.4):
|
- permission_handler_apple (9.0.4):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- ReachabilitySwift (5.0.0)
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
|
@ -37,6 +41,7 @@ PODS:
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
|
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
|
||||||
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
|
|
@ -54,11 +59,14 @@ SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
- FMDB
|
||||||
- ObjectBox
|
- ObjectBox
|
||||||
|
- ReachabilitySwift
|
||||||
- Toast
|
- Toast
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
camera_avfoundation:
|
camera_avfoundation:
|
||||||
:path: ".symlinks/plugins/camera_avfoundation/ios"
|
:path: ".symlinks/plugins/camera_avfoundation/ios"
|
||||||
|
connectivity_plus:
|
||||||
|
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
|
|
@ -86,6 +94,7 @@ EXTERNAL SOURCES:
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
|
camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
|
||||||
|
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
|
||||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
|
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
|
||||||
|
|
@ -96,6 +105,7 @@ SPEC CHECKSUMS:
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||||
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
||||||
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
|
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
|
||||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class VisitPhoto {
|
||||||
int photo_principale;
|
int photo_principale;
|
||||||
String tags;
|
String tags;
|
||||||
int id_concurrence_lien;
|
int id_concurrence_lien;
|
||||||
|
bool depuis_galerie;
|
||||||
|
|
||||||
VisitPhoto(
|
VisitPhoto(
|
||||||
{this.id = 0,
|
{this.id = 0,
|
||||||
|
|
@ -31,7 +32,8 @@ class VisitPhoto {
|
||||||
this.photo_principale = 0,
|
this.photo_principale = 0,
|
||||||
this.tags = '',
|
this.tags = '',
|
||||||
DateTime? date_photo,
|
DateTime? date_photo,
|
||||||
this.id_concurrence_lien = 0})
|
this.id_concurrence_lien = 0,
|
||||||
|
this.depuis_galerie = false})
|
||||||
: date_photo = date_photo ?? DateTime.now();
|
: date_photo = date_photo ?? DateTime.now();
|
||||||
|
|
||||||
static String? _photosDir = SharedPrefs().photosDir;
|
static String? _photosDir = SharedPrefs().photosDir;
|
||||||
|
|
@ -40,7 +42,10 @@ class VisitPhoto {
|
||||||
if (_photosDir == null) {
|
if (_photosDir == null) {
|
||||||
throw Exception('Photos directory not initialized');
|
throw Exception('Photos directory not initialized');
|
||||||
}
|
}
|
||||||
return '$_photosDir/$image_name';
|
if (depuis_galerie == false) {
|
||||||
|
return '$_photosDir/$image_name';
|
||||||
|
} else
|
||||||
|
return image_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get dateFormat => DateFormat('dd.MM.yyyy hh:mm:ss').format(date_photo);
|
String get dateFormat => DateFormat('dd.MM.yyyy hh:mm:ss').format(date_photo);
|
||||||
|
|
@ -57,6 +62,7 @@ class VisitPhoto {
|
||||||
int? photo_principale,
|
int? photo_principale,
|
||||||
String? tags,
|
String? tags,
|
||||||
int? id_concurrence_lien,
|
int? id_concurrence_lien,
|
||||||
|
bool? depuis_galerie,
|
||||||
}) {
|
}) {
|
||||||
return VisitPhoto(
|
return VisitPhoto(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
|
|
@ -69,6 +75,7 @@ class VisitPhoto {
|
||||||
photo_principale: photo_principale ?? this.photo_principale,
|
photo_principale: photo_principale ?? this.photo_principale,
|
||||||
tags: tags ?? this.tags,
|
tags: tags ?? this.tags,
|
||||||
id_concurrence_lien: id_concurrence_lien ?? this.id_concurrence_lien,
|
id_concurrence_lien: id_concurrence_lien ?? this.id_concurrence_lien,
|
||||||
|
depuis_galerie: depuis_galerie ?? this.depuis_galerie,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ Future<void> main() async {
|
||||||
|
|
||||||
objectbox = await ObjectBox.create();
|
objectbox = await ObjectBox.create();
|
||||||
|
|
||||||
int objectboxAddress = identityHashCode(objectbox);
|
|
||||||
print(objectboxAddress);
|
|
||||||
|
|
||||||
/// Log
|
/// Log
|
||||||
objectbox.addLog('LOG', 'MOBDR', 'Ouverture application ', 0);
|
objectbox.addLog('LOG', 'MOBDR', 'Ouverture application ', 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,7 @@ class ApiProvider {
|
||||||
String base64Photo = base64.encode(ReponseImg.data);
|
String base64Photo = base64.encode(ReponseImg.data);
|
||||||
|
|
||||||
/// create box user
|
/// create box user
|
||||||
|
objectbox.userBox.removeAll();
|
||||||
objectbox.addUSer(
|
objectbox.addUSer(
|
||||||
response.data['id_utilisateur'],
|
response.data['id_utilisateur'],
|
||||||
response.data['login'],
|
response.data['login'],
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "13:6298506278273268036",
|
"id": "13:6298506278273268036",
|
||||||
"lastPropertyId": "11:7594245284938827569",
|
"lastPropertyId": "13:3286310216758176958",
|
||||||
"name": "VisitPhoto",
|
"name": "VisitPhoto",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
|
|
@ -277,6 +277,11 @@
|
||||||
"id": "11:7594245284938827569",
|
"id": "11:7594245284938827569",
|
||||||
"name": "id_concurrence_lien",
|
"name": "id_concurrence_lien",
|
||||||
"type": 6
|
"type": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13:3286310216758176958",
|
||||||
|
"name": "depuis_galerie",
|
||||||
|
"type": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
|
|
@ -463,7 +468,8 @@
|
||||||
102253757473665009,
|
102253757473665009,
|
||||||
1526411175344533047,
|
1526411175344533047,
|
||||||
1603887098520719919,
|
1603887098520719919,
|
||||||
427077651567855068
|
427077651567855068,
|
||||||
|
7039119413270734559
|
||||||
],
|
],
|
||||||
"retiredRelationUids": [],
|
"retiredRelationUids": [],
|
||||||
"version": 1
|
"version": 1
|
||||||
|
|
|
||||||
|
|
@ -54,27 +54,6 @@ class ObjectBox {
|
||||||
PhotoTypologyBox = Box<PhotoTypology>(store);
|
PhotoTypologyBox = Box<PhotoTypology>(store);
|
||||||
visitPhotoBox = Box<VisitPhoto>(store);
|
visitPhotoBox = Box<VisitPhoto>(store);
|
||||||
logBox = Box<Log>(store);
|
logBox = Box<Log>(store);
|
||||||
|
|
||||||
// Add some demo data if the box is empty.
|
|
||||||
if (noteBox.isEmpty()) {
|
|
||||||
_putDemoData();
|
|
||||||
}
|
|
||||||
|
|
||||||
userBox.removeAll();
|
|
||||||
|
|
||||||
/*
|
|
||||||
etabBox.removeAll();
|
|
||||||
etabCompetitorBox.removeAll();
|
|
||||||
visitBox.removeAll();
|
|
||||||
visitTagBox.removeAll();
|
|
||||||
visitPhotoBox.removeAll();
|
|
||||||
PhotoTypologyBox.removeAll();
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Add some demo data if the box is empty.
|
|
||||||
if (userBox.isEmpty()) {
|
|
||||||
_putUserAdminData();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an instance of ObjectBox to use throughout the app.
|
/// Create an instance of ObjectBox to use throughout the app.
|
||||||
|
|
@ -84,19 +63,9 @@ class ObjectBox {
|
||||||
return ObjectBox._create(store);
|
return ObjectBox._create(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _putDemoData() {
|
/**
|
||||||
final demoNotes = [
|
* TODO: A SUPPRIMER + Box note
|
||||||
Note('Quickly add a note by writing text and pressing Enter'),
|
*/
|
||||||
Note('Delete notes by tapping on one'),
|
|
||||||
Note('Write a demo app for ObjectBox')
|
|
||||||
];
|
|
||||||
store.runInTransactionAsync(TxMode.write, _putNotesInTx, demoNotes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _putUserAdminData() {
|
|
||||||
//addUSer(0, 'root', 'admim', 'admin', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<List<Note>> getNotes() {
|
Stream<List<Note>> getNotes() {
|
||||||
// Query for all notes, sorted by their date.
|
// Query for all notes, sorted by their date.
|
||||||
// https://docs.objectbox.io/queries
|
// https://docs.objectbox.io/queries
|
||||||
|
|
@ -134,20 +103,14 @@ class ObjectBox {
|
||||||
/// USER ---------------------------------------------------------------------
|
/// USER ---------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
|
||||||
Future<void> addUSer(int _id_utilisateur, String _login, String _nom,
|
void addUSer(int _id_utilisateur, String _login, String _nom, String _prenom,
|
||||||
String _prenom, String _photo) =>
|
String _photo) {
|
||||||
store.runInTransactionAsync(
|
userBox.put(User(
|
||||||
TxMode.write,
|
id_utilisateur: _id_utilisateur,
|
||||||
_addUserInTx,
|
login: _login,
|
||||||
User(
|
nom: _nom,
|
||||||
id_utilisateur: _id_utilisateur,
|
prenom: _prenom,
|
||||||
login: _login,
|
photo: _photo));
|
||||||
nom: _nom,
|
|
||||||
prenom: _prenom,
|
|
||||||
photo: _photo));
|
|
||||||
|
|
||||||
static void _addUserInTx(Store store, _User) {
|
|
||||||
store.box<User>().put(_User);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getUserAvatar(int id_utilisateur) {
|
String getUserAvatar(int id_utilisateur) {
|
||||||
|
|
@ -241,9 +204,23 @@ class ObjectBox {
|
||||||
.query(EtabCompetitor_.id_etab.equals(_id_etab))
|
.query(EtabCompetitor_.id_etab.equals(_id_etab))
|
||||||
.order(EtabCompetitor_.nom)
|
.order(EtabCompetitor_.nom)
|
||||||
.build();
|
.build();
|
||||||
final photoCompetitors = query.find();
|
final etabCompetitors = query.find();
|
||||||
|
|
||||||
return photoCompetitors.toList();
|
return etabCompetitors.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves a etab competitor object from the ObjectBox database with the specified ID.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// _id_concurrence_lien : The _id_concurrence_lien of the competitor to retrieve.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// A Etab Competitor object, or null if no object is found.
|
||||||
|
EtabCompetitor? getEtabCompetitorByLink(int _id_concurrence_lien) {
|
||||||
|
final query = etabCompetitorBox
|
||||||
|
.query(EtabCompetitor_.id_concurrence_lien.equals(_id_concurrence_lien))
|
||||||
|
.build();
|
||||||
|
return query.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getEtabCompetitorsCount() {
|
int getEtabCompetitorsCount() {
|
||||||
|
|
@ -598,42 +575,42 @@ class ObjectBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> putPhotoTypologie(int photoId, int typologieId) async {
|
void putPhotoTypologie(int photoId, int typologieId) {
|
||||||
final photo = visitPhotoBox.get(photoId);
|
final photo = visitPhotoBox.get(photoId);
|
||||||
|
|
||||||
if (photo != null) {
|
if (photo != null) {
|
||||||
final updatedPhoto = photo.copyWith(id_photo_typologie: typologieId);
|
final updatedPhoto = photo.copyWith(id_photo_typologie: typologieId);
|
||||||
await visitPhotoBox.putAsync(updatedPhoto);
|
visitPhotoBox.put(updatedPhoto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> putPhotoTags(int photoId, List<String> tags) async {
|
void putPhotoTags(int photoId, List<String> tags) {
|
||||||
final photo = visitPhotoBox.get(photoId);
|
final photo = visitPhotoBox.get(photoId);
|
||||||
|
|
||||||
if (photo != null) {
|
if (photo != null) {
|
||||||
final updatedPhoto = photo.copyWith(tags: tags.join(","));
|
final updatedPhoto = photo.copyWith(tags: tags.join(","));
|
||||||
await visitPhotoBox.putAsync(updatedPhoto);
|
visitPhotoBox.put(updatedPhoto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> putPhotoVisibilities(
|
void putPhotoVisibilities(int photoId, List<String> visibilities) {
|
||||||
int photoId, List<String> visibilities) async {
|
|
||||||
final photo = visitPhotoBox.get(photoId);
|
final photo = visitPhotoBox.get(photoId);
|
||||||
|
|
||||||
if (photo != null) {
|
if (photo != null) {
|
||||||
final updatedPhoto = photo.copyWith(
|
final updatedPhoto = photo.copyWith(
|
||||||
photo_principale: visibilities.contains('principal') ? 1 : 0,
|
photo_principale: visibilities.contains('principal') ? 1 : 0,
|
||||||
photo_privee: visibilities.contains('private') ? 1 : 0);
|
photo_privee: visibilities.contains('private') ? 1 : 0);
|
||||||
await visitPhotoBox.putAsync(updatedPhoto);
|
|
||||||
|
visitPhotoBox.put(updatedPhoto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> putPhotoCompetitor(int photoId, int competitorId) async {
|
void putPhotoCompetitor(int photoId, int competitorId) {
|
||||||
final photo = visitPhotoBox.get(photoId);
|
final photo = visitPhotoBox.get(photoId);
|
||||||
|
|
||||||
if (photo != null) {
|
if (photo != null) {
|
||||||
final updatedPhoto = photo.copyWith(id_concurrence_lien: competitorId);
|
final updatedPhoto = photo.copyWith(id_concurrence_lien: competitorId);
|
||||||
await visitPhotoBox.putAsync(updatedPhoto);
|
visitPhotoBox.put(updatedPhoto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ final _entities = <ModelEntity>[
|
||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(13, 6298506278273268036),
|
id: const IdUid(13, 6298506278273268036),
|
||||||
name: 'VisitPhoto',
|
name: 'VisitPhoto',
|
||||||
lastPropertyId: const IdUid(11, 7594245284938827569),
|
lastPropertyId: const IdUid(13, 3286310216758176958),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
|
|
@ -301,6 +301,11 @@ final _entities = <ModelEntity>[
|
||||||
id: const IdUid(11, 7594245284938827569),
|
id: const IdUid(11, 7594245284938827569),
|
||||||
name: 'id_concurrence_lien',
|
name: 'id_concurrence_lien',
|
||||||
type: 6,
|
type: 6,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(13, 3286310216758176958),
|
||||||
|
name: 'depuis_galerie',
|
||||||
|
type: 1,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
|
|
@ -504,7 +509,8 @@ ModelDefinition getObjectBoxModel() {
|
||||||
102253757473665009,
|
102253757473665009,
|
||||||
1526411175344533047,
|
1526411175344533047,
|
||||||
1603887098520719919,
|
1603887098520719919,
|
||||||
427077651567855068
|
427077651567855068,
|
||||||
|
7039119413270734559
|
||||||
],
|
],
|
||||||
retiredRelationUids: const [],
|
retiredRelationUids: const [],
|
||||||
modelVersion: 5,
|
modelVersion: 5,
|
||||||
|
|
@ -761,7 +767,7 @@ ModelDefinition getObjectBoxModel() {
|
||||||
objectToFB: (VisitPhoto object, fb.Builder fbb) {
|
objectToFB: (VisitPhoto object, fb.Builder fbb) {
|
||||||
final image_nameOffset = fbb.writeString(object.image_name);
|
final image_nameOffset = fbb.writeString(object.image_name);
|
||||||
final tagsOffset = fbb.writeString(object.tags);
|
final tagsOffset = fbb.writeString(object.tags);
|
||||||
fbb.startTable(12);
|
fbb.startTable(14);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.id_visite);
|
fbb.addInt64(1, object.id_visite);
|
||||||
fbb.addInt64(2, object.id_photo_typologie);
|
fbb.addInt64(2, object.id_photo_typologie);
|
||||||
|
|
@ -772,6 +778,7 @@ ModelDefinition getObjectBoxModel() {
|
||||||
fbb.addInt64(7, object.photo_principale);
|
fbb.addInt64(7, object.photo_principale);
|
||||||
fbb.addOffset(8, tagsOffset);
|
fbb.addOffset(8, tagsOffset);
|
||||||
fbb.addInt64(10, object.id_concurrence_lien);
|
fbb.addInt64(10, object.id_concurrence_lien);
|
||||||
|
fbb.addBool(12, object.depuis_galerie);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
|
|
@ -798,7 +805,9 @@ ModelDefinition getObjectBoxModel() {
|
||||||
date_photo: DateTime.fromMillisecondsSinceEpoch(
|
date_photo: DateTime.fromMillisecondsSinceEpoch(
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 12, 0)),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 12, 0)),
|
||||||
id_concurrence_lien:
|
id_concurrence_lien:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 24, 0));
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 24, 0),
|
||||||
|
depuis_galerie: const fb.BoolReader()
|
||||||
|
.vTableGet(buffer, rootOffset, 28, false));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
|
|
@ -1081,6 +1090,10 @@ class VisitPhoto_ {
|
||||||
/// see [VisitPhoto.id_concurrence_lien]
|
/// see [VisitPhoto.id_concurrence_lien]
|
||||||
static final id_concurrence_lien =
|
static final id_concurrence_lien =
|
||||||
QueryIntegerProperty<VisitPhoto>(_entities[6].properties[9]);
|
QueryIntegerProperty<VisitPhoto>(_entities[6].properties[9]);
|
||||||
|
|
||||||
|
/// see [VisitPhoto.depuis_galerie]
|
||||||
|
static final depuis_galerie =
|
||||||
|
QueryBooleanProperty<VisitPhoto>(_entities[6].properties[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Visit] entity fields to define ObjectBox queries.
|
/// [Visit] entity fields to define ObjectBox queries.
|
||||||
|
|
|
||||||
|
|
@ -89,18 +89,11 @@ class SharedPrefs {
|
||||||
_sharedPrefs.setString('key_photo', value);
|
_sharedPrefs.setString('key_photo', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get/set id_distrib
|
/// get/set last id_visite
|
||||||
int get id_distrib => _sharedPrefs.getInt('key_id_distrib') ?? 0;
|
int get last_id_visite => _sharedPrefs.getInt('key_last_id_visite') ?? 0;
|
||||||
|
|
||||||
set id_distrib(int value) {
|
set last_id_visite(int value) {
|
||||||
_sharedPrefs.setInt('key_id_distrib', value);
|
_sharedPrefs.setInt('key_last_id_visite', value);
|
||||||
}
|
|
||||||
|
|
||||||
/// get/set id_visite
|
|
||||||
int get id_visite => _sharedPrefs.getInt('key_id_visite') ?? 0;
|
|
||||||
|
|
||||||
set id_visite(int value) {
|
|
||||||
_sharedPrefs.setInt('key_id_visite', value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get/set isSimulator
|
/// get/set isSimulator
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ class _HomePageState extends State<HomePage>
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleTabSelection() {
|
void _handleTabSelection() {
|
||||||
// TODO a voir si on laisse setState ??
|
|
||||||
/*
|
/*
|
||||||
setState(() {
|
setState(() {
|
||||||
});
|
});
|
||||||
|
|
@ -99,7 +98,7 @@ class _HomePageState extends State<HomePage>
|
||||||
icon: Icon(Icons.home,
|
icon: Icon(Icons.home,
|
||||||
color: _currentIndex == 0 ? PRIMARY_COLOR : CHARCOAL)),
|
color: _currentIndex == 0 ? PRIMARY_COLOR : CHARCOAL)),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
label: 'Visits',
|
label: 'Synchro',
|
||||||
icon: Icon(Icons.sync,
|
icon: Icon(Icons.sync,
|
||||||
color: _currentIndex == 1 ? ASSENT_COLOR : CHARCOAL)),
|
color: _currentIndex == 1 ? ASSENT_COLOR : CHARCOAL)),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ we used AutomaticKeepAliveClientMixin to keep the state when moving from 1 navba
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:badges/badges.dart' as badges;
|
import 'package:badges/badges.dart' as badges;
|
||||||
|
|
@ -43,13 +44,13 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
|
|
||||||
String defaultLang = 'en';
|
String defaultLang = 'en';
|
||||||
|
|
||||||
late LanguageCubit _languageCubit;
|
DateTime _todayDate = DateTime.now();
|
||||||
|
|
||||||
bool _isLoading = true;
|
late LanguageCubit _languageCubit;
|
||||||
String _errorMessage = '';
|
|
||||||
|
|
||||||
late List<VisitModel> todayVisitData = [];
|
late List<VisitModel> todayVisitData = [];
|
||||||
late List<VisitModel> previousVisitData = [];
|
late List<VisitModel> previousVisitData = [];
|
||||||
|
VisitModel? lastVisitData = null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -65,21 +66,22 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
|
|
||||||
loadData().then((_) {
|
loadData().then((_) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
|
||||||
|
|
||||||
// Listen particular event
|
// Listen particular event
|
||||||
subVisitPhotoCountEvent =
|
subVisitPhotoCountEvent =
|
||||||
eventBus.on<VisitPhotoCountEvent>().listen((e) {
|
eventBus.on<VisitPhotoCountEvent>().listen((e) {
|
||||||
|
SharedPrefs().last_id_visite = e.id_visite;
|
||||||
setState(() {
|
setState(() {
|
||||||
for (int i = 0; i < todayVisitData.length; i++) {
|
for (int i = 0; i < todayVisitData.length; i++) {
|
||||||
if (todayVisitData[i].id_visite == e.id_visite) {
|
if (todayVisitData[i].id_visite == e.id_visite) {
|
||||||
todayVisitData[i].photoCount = e.photoCount;
|
todayVisitData[i].photoCount = e.photoCount;
|
||||||
|
lastVisitData = todayVisitData[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < previousVisitData.length; i++) {
|
for (int i = 0; i < previousVisitData.length; i++) {
|
||||||
if (previousVisitData[i].id_visite == e.id_visite) {
|
if (previousVisitData[i].id_visite == e.id_visite) {
|
||||||
previousVisitData[i].photoCount = e.photoCount;
|
previousVisitData[i].photoCount = e.photoCount;
|
||||||
|
lastVisitData = previousVisitData[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -114,9 +116,9 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
// if we used AutomaticKeepAliveClientMixin, we must call super.build(context);
|
// if we used AutomaticKeepAliveClientMixin, we must call super.build(context);
|
||||||
super.build(context);
|
super.build(context);
|
||||||
final double boxImageSize = (MediaQuery.of(context).size.width / 3);
|
final double boxImageSize = (MediaQuery.of(context).size.width / 3);
|
||||||
if (_isLoading) {
|
final formattedDate =
|
||||||
return Center(child: CircularProgressIndicator());
|
DateFormat('EEEE d MMMM y', 'fr_FR').format(_todayDate);
|
||||||
}
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
|
@ -149,22 +151,93 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
body: ListView(
|
body: ListView(
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: AlwaysScrollableScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.calendar_today),
|
||||||
|
SizedBox(width: 8.0),
|
||||||
|
Text(
|
||||||
|
formattedDate,
|
||||||
|
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_buildLastVisit(boxImageSize),
|
||||||
_buildTodayVisits(boxImageSize),
|
_buildTodayVisits(boxImageSize),
|
||||||
_builPreviousVisits(boxImageSize),
|
_builPreviousVisits(boxImageSize),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final result = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => SyncCalendarPage()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Refresh the widget if the synchronization was successful.
|
||||||
|
if (result == true) {
|
||||||
|
setState(() {
|
||||||
|
loadData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text('Synchronisation'),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildLastVisit(boxImageSize) {
|
||||||
|
if (lastVisitData == null) {
|
||||||
|
return SizedBox.shrink(); // Rien ne sera affiché
|
||||||
|
} else {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text('Last visit access', style: GlobalStyle.horizontalTitle),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(top: 8),
|
||||||
|
height: boxImageSize * GlobalStyle.cardHeightMultiplication,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
child: buildHorizontalVisitListCard(context, lastVisitData)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildTodayVisits(boxImageSize) {
|
Widget _buildTodayVisits(boxImageSize) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
|
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Text('Today Visits', style: GlobalStyle.horizontalTitle),
|
Text('Today Visits', style: GlobalStyle.horizontalTitle),
|
||||||
|
Container(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 2.0, horizontal: 8.0),
|
||||||
|
child: badges.Badge(
|
||||||
|
badgeStyle: badges.BadgeStyle(
|
||||||
|
badgeColor: Colors.black,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.all(todayVisitData.length >= 10 ? 2 : 6),
|
||||||
|
),
|
||||||
|
badgeContent: Text(
|
||||||
|
todayVisitData.length.toString(),
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -175,11 +248,18 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
SizedBox(height: 16), // Ajout de l'espace ici
|
SizedBox(height: 16), // Ajout de l'espace ici
|
||||||
Text('Aucune visite ce jour'),
|
Text('Aucune visite ce jour'),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
Navigator.push(
|
final result = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => SyncCalendarPage()),
|
MaterialPageRoute(builder: (context) => SyncCalendarPage()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Refresh the widget if the synchronization was successful.
|
||||||
|
if (result == true) {
|
||||||
|
setState(() {
|
||||||
|
loadData();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Text('Synchroniser'),
|
child: Text('Synchroniser'),
|
||||||
),
|
),
|
||||||
|
|
@ -329,13 +409,26 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
|
|
||||||
/// Initializes data when the page loads.
|
/// Initializes data when the page loads.
|
||||||
Future<void> loadData() async {
|
Future<void> loadData() async {
|
||||||
try {
|
// visite model initialisation
|
||||||
// visite model initialisation
|
todayVisitData = await VisitModel.getTodayVisit();
|
||||||
todayVisitData = await VisitModel.getTodayVisit();
|
previousVisitData = await VisitModel.getPreviousVisit();
|
||||||
previousVisitData = await VisitModel.getPreviousVisit();
|
|
||||||
} catch (e) {
|
// Search for the visit matching last_id_visit
|
||||||
// set errorMessage for debug
|
int lastIdVisite = SharedPrefs().last_id_visite;
|
||||||
_errorMessage = 'Error loading visites : $e';
|
|
||||||
|
lastVisitData = null;
|
||||||
|
|
||||||
|
if (lastIdVisite > 0) {
|
||||||
|
for (var visit in todayVisitData) {
|
||||||
|
if (visit.id_visite == lastIdVisite) {
|
||||||
|
lastVisitData = visit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastVisitData == null) {
|
||||||
|
SharedPrefs().last_id_visite = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:mobdr/main.dart';
|
|
||||||
import 'package:mobdr/events.dart';
|
|
||||||
import 'package:mobdr/config/global_style.dart';
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
import 'package:mobdr/service/shared_prefs.dart';
|
|
||||||
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
|
||||||
|
|
||||||
//TODO Rechercher toutes les utilisations
|
//TODO Rechercher toutes les utilisations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:mobdr/service/shared_prefs.dart';
|
import 'package:mobdr/service/shared_prefs.dart';
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
import 'package:mobdr/ui/onboarding.dart';
|
import 'package:mobdr/ui/onboarding.dart';
|
||||||
import 'package:mobdr/ui/authentication/signin.dart';
|
import 'package:mobdr/ui/home.dart';
|
||||||
|
|
||||||
class SplashScreenPage extends StatefulWidget {
|
class SplashScreenPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
|
@ -28,14 +28,11 @@ class _SplashScreenPageState extends State<SplashScreenPage> {
|
||||||
|
|
||||||
if (SharedPrefs().onboarding == 0) {
|
if (SharedPrefs().onboarding == 0) {
|
||||||
SharedPrefs().onboarding = 1;
|
SharedPrefs().onboarding = 1;
|
||||||
|
|
||||||
// for this example we will use pushReplacement because we want to go back to the list
|
|
||||||
Navigator.pushReplacement(context,
|
Navigator.pushReplacement(context,
|
||||||
MaterialPageRoute(builder: (context) => OnBoardingPage()));
|
MaterialPageRoute(builder: (context) => OnBoardingPage()));
|
||||||
} else {
|
} else {
|
||||||
// for this example we will use pushReplacement because we want to go back to the list
|
|
||||||
Navigator.pushReplacement(
|
Navigator.pushReplacement(
|
||||||
context, MaterialPageRoute(builder: (context) => SigninPage()));
|
context, MaterialPageRoute(builder: (context) => HomePage()));
|
||||||
}
|
}
|
||||||
// if you use this splash screen on the very first time when you open the page, use below code
|
// if you use this splash screen on the very first time when you open the page, use below code
|
||||||
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => OnBoardingPage()), (Route<dynamic> route) => false);
|
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => OnBoardingPage()), (Route<dynamic> route) => false);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
|
|
||||||
|
class CheckConnectionPage extends StatefulWidget {
|
||||||
|
final Widget redirectPage;
|
||||||
|
|
||||||
|
const CheckConnectionPage({Key? key, required this.redirectPage})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CheckConnectionPageState createState() => _CheckConnectionPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CheckConnectionPageState extends State<CheckConnectionPage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Mayday ..."),
|
||||||
|
backgroundColor:
|
||||||
|
Colors.red, // Définir la couleur de fond de l'appbar en rouge
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/no_connection.png',
|
||||||
|
width: 250,
|
||||||
|
),
|
||||||
|
SizedBox(height: 32),
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"No internet connection",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
"You are not connected. Check your connection.",
|
||||||
|
style: TextStyle(fontSize: 14),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 32),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
child: const Text("Check Connection"),
|
||||||
|
onPressed: () async {
|
||||||
|
final connectivityResult =
|
||||||
|
await Connectivity().checkConnectivity();
|
||||||
|
if (connectivityResult == ConnectivityResult.none) {
|
||||||
|
await showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (_) => NetworkErrorDialog(
|
||||||
|
onRetryPressed: () async {
|
||||||
|
final connectivityResult =
|
||||||
|
await Connectivity().checkConnectivity();
|
||||||
|
if (connectivityResult == ConnectivityResult.none) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Please turn on your wifi or mobile data')));
|
||||||
|
} else {
|
||||||
|
Navigator.pop(context);
|
||||||
|
// redirect to UploadPhotosPage here
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// redirect to UploadPhotosPage here
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkErrorDialog extends StatelessWidget {
|
||||||
|
const NetworkErrorDialog({Key? key, this.onRetryPressed}) : super(key: key);
|
||||||
|
|
||||||
|
final VoidCallback? onRetryPressed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('No Internet Connection'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.error, color: Colors.red, size: 48),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Text(
|
||||||
|
'Please check your internet connection and try again.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: const Text('Go Back'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: onRetryPressed,
|
||||||
|
child: const Text('Retry'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ class _SyncCalendarPageState extends State<SyncCalendarPage> {
|
||||||
|
|
||||||
void _popScreen() {
|
void _popScreen() {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop(_syncSuccessful);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
|
|
||||||
import 'package:mobdr/main.dart';
|
import 'package:mobdr/main.dart';
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
|
|
@ -9,6 +10,7 @@ import 'package:mobdr/model/visit_model.dart';
|
||||||
import 'package:mobdr/ui/visit/visit_photo_typology.dart';
|
import 'package:mobdr/ui/visit/visit_photo_typology.dart';
|
||||||
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
||||||
import 'package:mobdr/ui/sync/upload_photos.dart';
|
import 'package:mobdr/ui/sync/upload_photos.dart';
|
||||||
|
import 'package:mobdr/ui/sync/check_connection.dart';
|
||||||
|
|
||||||
class TabVisitListPage extends StatefulWidget {
|
class TabVisitListPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
|
@ -17,9 +19,6 @@ class TabVisitListPage extends StatefulWidget {
|
||||||
|
|
||||||
class _TabVisitListPageState extends State<TabVisitListPage>
|
class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
// _listKey is used for AnimatedList
|
|
||||||
final GlobalKey<AnimatedListState> _listKey = GlobalKey();
|
|
||||||
|
|
||||||
// keep the state to do not refresh when switch navbar
|
// keep the state to do not refresh when switch navbar
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
@ -31,6 +30,9 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
|
|
||||||
late StreamSubscription subVisitPhotoCountEvent;
|
late StreamSubscription subVisitPhotoCountEvent;
|
||||||
|
|
||||||
|
// _listKey is used for AnimatedList
|
||||||
|
var _listKey = GlobalKey<AnimatedListState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
@ -73,28 +75,57 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
iconTheme: IconThemeData(
|
iconTheme: IconThemeData(
|
||||||
color: GlobalStyle.appBarIconThemeColor,
|
color: GlobalStyle.appBarIconThemeColor,
|
||||||
),
|
),
|
||||||
elevation: GlobalStyle.appBarElevation,
|
elevation: GlobalStyle.appBarElevation,
|
||||||
title: Text(
|
title: Text(
|
||||||
'Visit List',
|
'Synchronization',
|
||||||
style: GlobalStyle.appBarTitle,
|
style: GlobalStyle.appBarTitle,
|
||||||
),
|
),
|
||||||
backgroundColor: GlobalStyle.appBarBackgroundColor,
|
backgroundColor: GlobalStyle.appBarBackgroundColor,
|
||||||
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle),
|
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle),
|
||||||
body: Column(children: [
|
body: Column(
|
||||||
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: AnimatedList(
|
child: AnimatedList(
|
||||||
key: _listKey,
|
key: _listKey,
|
||||||
initialItemCount: modelData.length,
|
initialItemCount: modelData.length,
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: AlwaysScrollableScrollPhysics(),
|
||||||
itemBuilder: (context, index, animation) {
|
itemBuilder: (context, index, animation) {
|
||||||
return _buildVisitelistCard(
|
return Dismissible(
|
||||||
modelData[index], boxImageSize, animation, index);
|
key: UniqueKey(),
|
||||||
},
|
direction: DismissDirection.endToStart,
|
||||||
)),
|
onDismissed: (direction) {
|
||||||
|
// the photo must be removed
|
||||||
|
setState(() {
|
||||||
|
modelData.removeAt(index);
|
||||||
|
_listKey = GlobalKey<AnimatedListState>();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
background: Container(
|
||||||
|
color: Colors.red,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Positioned.fill(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Icon(
|
||||||
|
Icons.delete,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: _buildVisitelistCard(
|
||||||
|
modelData[index], boxImageSize, animation, index),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(12),
|
padding: EdgeInsets.all(12),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
@ -114,11 +145,11 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// TODO functionality to be implemented
|
// TODO functionality to be implemented
|
||||||
/*`
|
/*`
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ChatUsPage()));
|
builder: (context) => ChatUsPage()));
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
@ -135,10 +166,7 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Route route = MaterialPageRoute(
|
navigateToPage(context, 0);
|
||||||
builder: (context) => UploadPhotosPage(pp_id_visite: 0),
|
|
||||||
);
|
|
||||||
Navigator.push(context, route);
|
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
@ -146,20 +174,24 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
margin: EdgeInsets.only(right: 8),
|
margin: EdgeInsets.only(right: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
border: Border.all(width: 1, color: SOFT_BLUE),
|
border: Border.all(width: 1, color: Colors.red),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(
|
borderRadius: BorderRadius.all(
|
||||||
10) // <--- border radius here
|
Radius.circular(10),
|
||||||
)),
|
)),
|
||||||
child: Text('Synchronize ALL',
|
child: Text(
|
||||||
style: TextStyle(
|
'Synchronize ALL visits',
|
||||||
color: SOFT_BLUE, fontWeight: FontWeight.bold)),
|
style: TextStyle(
|
||||||
|
color: Colors.red, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
]));
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildVisitelistCard(VisitModel data, boxImageSize, animation, index) {
|
Widget _buildVisitelistCard(VisitModel data, boxImageSize, animation, index) {
|
||||||
|
|
@ -283,11 +315,7 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
))
|
))
|
||||||
: OutlinedButton(
|
: OutlinedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Route route = MaterialPageRoute(
|
navigateToPage(context, data.id_visite);
|
||||||
builder: (context) => UploadPhotosPage(
|
|
||||||
pp_id_visite: data.id_visite),
|
|
||||||
);
|
|
||||||
Navigator.push(context, route);
|
|
||||||
},
|
},
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
minimumSize: MaterialStateProperty.all(
|
minimumSize: MaterialStateProperty.all(
|
||||||
|
|
@ -324,6 +352,26 @@ class _TabVisitListPageState extends State<TabVisitListPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> navigateToPage(BuildContext context, int id_visite) async {
|
||||||
|
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||||
|
|
||||||
|
if (connectivityResult == ConnectivityResult.none) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => CheckConnectionPage(
|
||||||
|
redirectPage: UploadPhotosPage(pp_id_visite: id_visite),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => UploadPhotosPage(pp_id_visite: id_visite)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Initializes data when the page loads.
|
/// Initializes data when the page loads.
|
||||||
Future<void> loadData() async {
|
Future<void> loadData() async {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,6 @@ class PhotoTagPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PhotoTagPageState extends State<PhotoTagPage> {
|
class _PhotoTagPageState extends State<PhotoTagPage> {
|
||||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
||||||
|
|
||||||
late List<String> allTagsList = [];
|
late List<String> allTagsList = [];
|
||||||
late List<String> _selectedTags = [];
|
late List<String> _selectedTags = [];
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
|
|
||||||
|
|
@ -40,17 +40,17 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
String _errorMessage = '';
|
String _errorMessage = '';
|
||||||
|
|
||||||
// Typology list
|
// Typology list
|
||||||
late List<PhotoTypology> _typologiesList = [];
|
late List<PhotoTypology> _photoTypologiesList = [];
|
||||||
int _typologyIndex = 0;
|
int _photoTypologyIndex = 0;
|
||||||
|
|
||||||
List<String> _visibilities = [];
|
List<String> _visibilities = [];
|
||||||
|
|
||||||
late List<String> tagList = [];
|
late List<String> tagList = [];
|
||||||
late VisitPhoto _photo;
|
late VisitPhoto _visitPhoto;
|
||||||
|
|
||||||
// competitors
|
// competitors
|
||||||
List<EtabCompetitor> _competitorsList = [];
|
List<EtabCompetitor> _etabCompetitorsList = [];
|
||||||
String _competitor = '';
|
String _etabCompetitor = '';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -104,8 +104,8 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
onWillPop: () {
|
onWillPop: () {
|
||||||
// fred
|
// fred
|
||||||
Map<String, dynamic> result = {
|
Map<String, dynamic> result = {
|
||||||
'change_typologie': _typologyIndex !=
|
'change_typologie': _photoTypologyIndex !=
|
||||||
_typologiesList.indexWhere((typology) =>
|
_photoTypologiesList.indexWhere((typology) =>
|
||||||
typology.id_photo_typologie == widget.pp_id_typologie),
|
typology.id_photo_typologie == widget.pp_id_typologie),
|
||||||
'tags': tagList.join(","),
|
'tags': tagList.join(","),
|
||||||
'photo_principale': _visibilities.contains('principal') ? 1 : 0,
|
'photo_principale': _visibilities.contains('principal') ? 1 : 0,
|
||||||
|
|
@ -213,8 +213,8 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
Wrap(
|
Wrap(
|
||||||
children: List.generate(_typologiesList.length, (index) {
|
children: List.generate(_photoTypologiesList.length, (index) {
|
||||||
return radioSize(_typologiesList[index].libelle, index);
|
return radioSize(_photoTypologiesList[index].libelle, index);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -225,27 +225,29 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_typologyIndex = index;
|
_photoTypologyIndex = index;
|
||||||
});
|
});
|
||||||
|
|
||||||
// save photo typology in the database
|
// save photo typology in the database
|
||||||
objectbox.putPhotoTypologie(
|
objectbox.putPhotoTypologie(
|
||||||
widget.pp_imageId, _typologiesList[index].id_photo_typologie);
|
widget.pp_imageId, _photoTypologiesList[index].id_photo_typologie);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
||||||
margin: EdgeInsets.only(right: 8, top: 8),
|
margin: EdgeInsets.only(right: 8, top: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _typologyIndex == index ? SOFT_BLUE : Colors.white,
|
color: _photoTypologyIndex == index ? SOFT_BLUE : Colors.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
width: 1,
|
width: 1,
|
||||||
color: _typologyIndex == index ? SOFT_BLUE : Colors.grey[300]!),
|
color: _photoTypologyIndex == index
|
||||||
|
? SOFT_BLUE
|
||||||
|
: Colors.grey[300]!),
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(10) // <--- border radius here
|
Radius.circular(10) // <--- border radius here
|
||||||
)),
|
)),
|
||||||
child: Text(txt,
|
child: Text(txt,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: _typologyIndex == index ? Colors.white : CHARCOAL)),
|
color: _photoTypologyIndex == index ? Colors.white : CHARCOAL)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -338,7 +340,7 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
builder: (context) => PhotoTagPage(
|
builder: (context) => PhotoTagPage(
|
||||||
pp_langage: widget.pp_visitModel.langage,
|
pp_langage: widget.pp_visitModel.langage,
|
||||||
pp_id_distrib: widget.pp_visitModel.id_distrib,
|
pp_id_distrib: widget.pp_visitModel.id_distrib,
|
||||||
pp_photoId: this._photo.id,
|
pp_photoId: this._visitPhoto.id,
|
||||||
pp_currentTags: tagList),
|
pp_currentTags: tagList),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -412,7 +414,7 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(10) // <--- border radius here
|
Radius.circular(10) // <--- border radius here
|
||||||
)),
|
)),
|
||||||
child: _competitor == ''
|
child: _etabCompetitor == ''
|
||||||
? Row(
|
? Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -435,7 +437,7 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(_competitor,
|
Text(_etabCompetitor,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: CHARCOAL,
|
color: CHARCOAL,
|
||||||
fontWeight: FontWeight.bold)),
|
fontWeight: FontWeight.bold)),
|
||||||
|
|
@ -473,19 +475,19 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
Flexible(
|
Flexible(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
itemCount: _competitorsList.length,
|
itemCount: _etabCompetitorsList.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
EtabCompetitor competitor = _competitorsList[index];
|
EtabCompetitor competitor = _etabCompetitorsList[index];
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_competitor = competitor.nom;
|
_etabCompetitor = competitor.nom;
|
||||||
});
|
});
|
||||||
|
|
||||||
// save photo competitor in the database
|
// save photo competitor in the database
|
||||||
objectbox.putPhotoCompetitor(widget.pp_visitModel.id,
|
objectbox.putPhotoCompetitor(
|
||||||
competitor.id_concurrence_lien);
|
widget.pp_imageId, competitor.id_concurrence_lien);
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
|
@ -513,26 +515,29 @@ class _VisitPhotoTypologyDetailPageState
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// photo typologies initialization
|
// photo typologies initialization
|
||||||
_typologiesList = objectbox.getPhotoTypologiesList();
|
_photoTypologiesList = objectbox.getPhotoTypologiesList();
|
||||||
|
|
||||||
_typologyIndex = _typologiesList.indexWhere(
|
_photoTypologyIndex = _photoTypologiesList.indexWhere(
|
||||||
(typology) => typology.id_photo_typologie == widget.pp_id_typologie);
|
(typology) => typology.id_photo_typologie == widget.pp_id_typologie);
|
||||||
|
|
||||||
// get photo object
|
// get photo object
|
||||||
_photo = objectbox.getPhotoById(photoId)!;
|
_visitPhoto = objectbox.getPhotoById(photoId)!;
|
||||||
|
|
||||||
// visibilities initialization
|
// visibilities initialization
|
||||||
if (_photo.photo_privee == 1) _visibilities.add('private');
|
if (_visitPhoto.photo_privee == 1) _visibilities.add('private');
|
||||||
if (_photo.photo_principale == 1) _visibilities.add('principal');
|
if (_visitPhoto.photo_principale == 1) _visibilities.add('principal');
|
||||||
|
|
||||||
// photo tag initialization
|
// photo tag initialization
|
||||||
tags = _photo.tags;
|
tags = _visitPhoto.tags;
|
||||||
tagList = tags.isEmpty ? [] : _photo.tags.split(",");
|
tagList = tags.isEmpty ? [] : _visitPhoto.tags.split(",");
|
||||||
|
|
||||||
// competitor initialization
|
// competitor initialization
|
||||||
_competitorsList =
|
_etabCompetitorsList =
|
||||||
objectbox.getEtabCompetitorList(widget.pp_visitModel.id_etab);
|
objectbox.getEtabCompetitorList(widget.pp_visitModel.id_etab);
|
||||||
_competitor = "";
|
|
||||||
|
final etabCompetitor =
|
||||||
|
objectbox.getEtabCompetitorByLink(_visitPhoto.id_concurrence_lien);
|
||||||
|
_etabCompetitor = etabCompetitor != null ? etabCompetitor.nom : "";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// set errorMessage for debug
|
// set errorMessage for debug
|
||||||
_errorMessage = 'Error loading photo: $e';
|
_errorMessage = 'Error loading photo: $e';
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
@ -138,20 +139,19 @@ class _VisitPhotoTypologyListPageState
|
||||||
Container(
|
Container(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// TODO functionality to be implemented
|
ImportImageFromGallery();
|
||||||
/*`
|
/*Navigator.push(
|
||||||
Navigator.push(
|
context,
|
||||||
context,
|
MaterialPageRoute(
|
||||||
MaterialPageRoute(
|
builder: (context) => PhotoPickPage()));
|
||||||
builder: (context) => ChatUsPage()));
|
*/
|
||||||
*/
|
|
||||||
},
|
},
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: SOFT_BLUE,
|
color: SOFT_BLUE,
|
||||||
padding: EdgeInsets.all(9),
|
padding: EdgeInsets.all(9),
|
||||||
child:
|
child: Icon(Icons.photo_library,
|
||||||
Icon(Icons.chat, color: Colors.white, size: 16)),
|
color: Colors.white, size: 16)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -443,7 +443,6 @@ class _VisitPhotoTypologyListPageState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO ƒuture void ?
|
|
||||||
void loadData() {
|
void loadData() {
|
||||||
_visitPhotoData = objectbox.getAllVisitTypologyPhotos(
|
_visitPhotoData = objectbox.getAllVisitTypologyPhotos(
|
||||||
widget.pp_visitModel.id_visite, widget.pp_id_typologie);
|
widget.pp_visitModel.id_visite, widget.pp_id_typologie);
|
||||||
|
|
@ -474,6 +473,7 @@ class _VisitPhotoTypologyListPageState
|
||||||
_listPhotos.add(VisitPhoto(
|
_listPhotos.add(VisitPhoto(
|
||||||
id_visite: widget.pp_visitModel.id_visite,
|
id_visite: widget.pp_visitModel.id_visite,
|
||||||
id_photo_typologie: widget.pp_id_typologie,
|
id_photo_typologie: widget.pp_id_typologie,
|
||||||
|
depuis_galerie: false,
|
||||||
image_name: myPhoto.path.split('/').last));
|
image_name: myPhoto.path.split('/').last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -542,8 +542,11 @@ class _VisitPhotoTypologyListPageState
|
||||||
// delete file on database
|
// delete file on database
|
||||||
objectbox.delPhotoByName(removedItem.image_name);
|
objectbox.delPhotoByName(removedItem.image_name);
|
||||||
|
|
||||||
// delete file on local storage
|
// if the photo is not from the gallery
|
||||||
deleteFile(new File(removedItem.getImage()));
|
if (removedItem.depuis_galerie == false) {
|
||||||
|
// delete file on local storage
|
||||||
|
deleteFile(new File(removedItem.getImage()));
|
||||||
|
}
|
||||||
|
|
||||||
// This builder is just so that the animation has something
|
// This builder is just so that the animation has something
|
||||||
// to work with before it disappears from view since the original
|
// to work with before it disappears from view since the original
|
||||||
|
|
@ -650,4 +653,47 @@ class _VisitPhotoTypologyListPageState
|
||||||
|
|
||||||
return tempFile;
|
return tempFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> ImportImageFromGallery() async {
|
||||||
|
try {
|
||||||
|
// get images from gallery
|
||||||
|
List<XFile>? images = await ImagePicker().pickMultiImage();
|
||||||
|
|
||||||
|
// if images have been selected
|
||||||
|
if (images.length > 0) {
|
||||||
|
final List<VisitPhoto> _listPhotos = [];
|
||||||
|
|
||||||
|
for (var image in images) {
|
||||||
|
// to insert into database
|
||||||
|
_listPhotos.add(VisitPhoto(
|
||||||
|
id_visite: widget.pp_visitModel.id_visite,
|
||||||
|
id_photo_typologie: widget.pp_id_typologie,
|
||||||
|
depuis_galerie: true,
|
||||||
|
image_name: image.path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert photo(s) in database (async)
|
||||||
|
final addedPhotos = await objectbox.addPhotos(_listPhotos);
|
||||||
|
|
||||||
|
// insert photo(s) in widget at the beginning (0)
|
||||||
|
_visitPhotoData.insertAll(0, addedPhotos);
|
||||||
|
|
||||||
|
// if new photos are taken
|
||||||
|
if (addedPhotos.length > 0) {
|
||||||
|
visitPhotoCount += addedPhotos.length;
|
||||||
|
// a global refresh event is sent
|
||||||
|
eventBus.fire(VisitPhotoCountEvent(
|
||||||
|
widget.pp_visitModel.id_visite, visitPhotoCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh widget
|
||||||
|
setState(() {
|
||||||
|
_listKey = GlobalKey();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Gestion de l'erreur
|
||||||
|
print('Erreur lors de la sélection d\'images : $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import connectivity_plus
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
import objectbox_flutter_libs
|
import objectbox_flutter_libs
|
||||||
import package_info_plus
|
import package_info_plus
|
||||||
|
|
@ -14,6 +15,7 @@ import sqflite
|
||||||
import wakelock_macos
|
import wakelock_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
|
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
|
||||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||||
|
|
|
||||||
36
pubspec.lock
36
pubspec.lock
|
|
@ -241,6 +241,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.0"
|
version: "1.17.0"
|
||||||
|
connectivity_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: connectivity_plus
|
||||||
|
sha256: b74247fad72c171381dbe700ca17da24deac637ab6d43c343b42867acb95c991
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.6"
|
||||||
|
connectivity_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: connectivity_plus_platform_interface
|
||||||
|
sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.4"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -297,6 +313,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.4"
|
version: "2.2.4"
|
||||||
|
dbus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dbus
|
||||||
|
sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.8"
|
||||||
debounce_throttle:
|
debounce_throttle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -529,10 +553,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: image_picker
|
name: image_picker
|
||||||
sha256: "64b21d9f0e065f9ab0e4dde458076226c97382cc0c6949144cb874c62bf8e9f8"
|
sha256: "3da954c3b8906d82ecb50fd5e2b5401758f06d5678904eed6cbc06172283a263"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.7"
|
version: "0.8.7+4"
|
||||||
image_picker_android:
|
image_picker_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -653,6 +677,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
nm:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nm
|
||||||
|
sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.0"
|
||||||
numerus:
|
numerus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ dependencies:
|
||||||
wakelock: ^0.6.2
|
wakelock: ^0.6.2
|
||||||
shimmer: 2.0.0
|
shimmer: 2.0.0
|
||||||
|
|
||||||
image_picker: ^0.8.7
|
# https://pub.dev/packages/image_picker
|
||||||
|
image_picker: ^0.8.7+4
|
||||||
|
|
||||||
# https://pub.dev/packages/camera
|
# https://pub.dev/packages/camera
|
||||||
camera: ^0.10.4
|
camera: ^0.10.4
|
||||||
|
|
@ -89,6 +90,9 @@ dependencies:
|
||||||
|
|
||||||
# https://pub.dev/packages/badges
|
# https://pub.dev/packages/badges
|
||||||
badges: ^3.1.1
|
badges: ^3.1.1
|
||||||
|
|
||||||
|
# https://pub.dev/packages/connectivity_plus
|
||||||
|
connectivity_plus: ^3.0.6
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
@ -165,6 +169,7 @@ flutter:
|
||||||
- assets/images/process_timeline/status4.png
|
- assets/images/process_timeline/status4.png
|
||||||
- assets/images/process_timeline/status5.png
|
- assets/images/process_timeline/status5.png
|
||||||
- assets/images/simulator.jpeg
|
- assets/images/simulator.jpeg
|
||||||
|
- assets/images/no_connection.png
|
||||||
|
|
||||||
- assets/lang/fr.json
|
- assets/lang/fr.json
|
||||||
- assets/lang/en.json
|
- assets/lang/en.json
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,13 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||||
#include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h>
|
#include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h>
|
||||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||||
ObjectboxFlutterLibsPluginRegisterWithRegistrar(
|
ObjectboxFlutterLibsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("ObjectboxFlutterLibsPlugin"));
|
registry->GetRegistrarForPlugin("ObjectboxFlutterLibsPlugin"));
|
||||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
connectivity_plus
|
||||||
objectbox_flutter_libs
|
objectbox_flutter_libs
|
||||||
permission_handler_windows
|
permission_handler_windows
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue