Updates for photo model
parent
ee76c40294
commit
d76f037333
|
|
@ -10,7 +10,6 @@ class Photo {
|
||||||
@Id()
|
@Id()
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
int id_photo;
|
|
||||||
int id_visite;
|
int id_visite;
|
||||||
int id_photo_typologie;
|
int id_photo_typologie;
|
||||||
String image;
|
String image;
|
||||||
|
|
@ -19,10 +18,7 @@ class Photo {
|
||||||
int id_photo_mp4;
|
int id_photo_mp4;
|
||||||
int photo_privee;
|
int photo_privee;
|
||||||
int photo_principale;
|
int photo_principale;
|
||||||
String photo_tag1;
|
String tags;
|
||||||
String photo_tag2;
|
|
||||||
String photo_tag3;
|
|
||||||
String photo_tag4;
|
|
||||||
int uploaded;
|
int uploaded;
|
||||||
|
|
||||||
Photo(
|
Photo(
|
||||||
|
|
@ -31,20 +27,43 @@ class Photo {
|
||||||
required this.id_photo_typologie,
|
required this.id_photo_typologie,
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.image_name,
|
required this.image_name,
|
||||||
this.id_photo = 0,
|
|
||||||
this.id_photo_mp4 = 0,
|
this.id_photo_mp4 = 0,
|
||||||
this.photo_privee = 0,
|
this.photo_privee = 0,
|
||||||
this.photo_principale = 0,
|
this.photo_principale = 0,
|
||||||
this.photo_tag1 = '',
|
this.tags = '',
|
||||||
this.photo_tag2 = '',
|
|
||||||
this.photo_tag3 = '',
|
|
||||||
this.photo_tag4 = '',
|
|
||||||
DateTime? date_photo,
|
DateTime? date_photo,
|
||||||
this.uploaded = 0})
|
this.uploaded = 0})
|
||||||
: date_photo = date_photo ?? DateTime.now();
|
: date_photo = date_photo ?? DateTime.now();
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
Photo copyWith({
|
||||||
|
int? id,
|
||||||
|
int? id_visite,
|
||||||
|
int? id_photo_typologie,
|
||||||
|
String? image,
|
||||||
|
String? image_name,
|
||||||
|
DateTime? date_photo,
|
||||||
|
int? id_photo_mp4,
|
||||||
|
int? photo_privee,
|
||||||
|
int? photo_principale,
|
||||||
|
String? tags,
|
||||||
|
int? uploaded,
|
||||||
|
}) {
|
||||||
|
return Photo(
|
||||||
|
id: id ?? this.id,
|
||||||
|
id_visite: id_visite ?? this.id_visite,
|
||||||
|
id_photo_typologie: id_photo_typologie ?? this.id_photo_typologie,
|
||||||
|
image: image ?? this.image,
|
||||||
|
image_name: image_name ?? this.image_name,
|
||||||
|
date_photo: date_photo ?? this.date_photo,
|
||||||
|
id_photo_mp4: id_photo_mp4 ?? this.id_photo_mp4,
|
||||||
|
photo_privee: photo_privee ?? this.photo_privee,
|
||||||
|
photo_principale: photo_principale ?? this.photo_principale,
|
||||||
|
tags: tags ?? this.tags,
|
||||||
|
uploaded: uploaded ?? this.uploaded,
|
||||||
|
);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Photo.fromJson(Map<String, dynamic> json)
|
Photo.fromJson(Map<String, dynamic> json)
|
||||||
: id_visite = json['id_visite'],
|
: id_visite = json['id_visite'],
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
class PhotoModel {
|
class PhotoModel {
|
||||||
|
late int id;
|
||||||
late int id_visite;
|
late int id_visite;
|
||||||
late int id_photo_typologie;
|
late int id_photo_typologie;
|
||||||
late String image;
|
late String image;
|
||||||
late String image_name;
|
late String image_name;
|
||||||
|
|
||||||
PhotoModel(
|
PhotoModel(
|
||||||
{required this.id_visite,
|
{required this.id,
|
||||||
|
required this.id_visite,
|
||||||
required this.id_photo_typologie,
|
required this.id_photo_typologie,
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.image_name});
|
required this.image_name});
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,56 @@
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/main.dart';
|
||||||
|
|
||||||
class VisiteModel {
|
class VisiteModel {
|
||||||
late int id;
|
late int id;
|
||||||
late String name;
|
late String name;
|
||||||
late double price;
|
late int photo;
|
||||||
|
late String date;
|
||||||
late String image;
|
late String image;
|
||||||
|
late String type_visite;
|
||||||
|
late double price;
|
||||||
late double rating;
|
late double rating;
|
||||||
late int review;
|
late int review;
|
||||||
late int sale;
|
late int sale;
|
||||||
late int stock;
|
late int stock;
|
||||||
late String location;
|
late String location;
|
||||||
late int photo;
|
|
||||||
late String date;
|
|
||||||
|
|
||||||
VisiteModel(
|
VisiteModel({
|
||||||
{required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.price,
|
required this.photo,
|
||||||
required this.photo,
|
required this.date,
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.rating,
|
required this.type_visite,
|
||||||
required this.review,
|
required this.price,
|
||||||
required this.sale,
|
required this.rating,
|
||||||
required this.stock,
|
required this.review,
|
||||||
required this.location,
|
required this.sale,
|
||||||
required this.date});
|
required this.stock,
|
||||||
|
required this.location,
|
||||||
|
});
|
||||||
|
|
||||||
|
static Future<List<VisiteModel>> getAllVisites() async {
|
||||||
|
// Retrieve all visits from the database using the getAllVisites() method
|
||||||
|
final visites = await objectbox.getAllVisites();
|
||||||
|
|
||||||
|
// Map each retrieved visit to VisiteModel
|
||||||
|
final visiteModels = visites
|
||||||
|
.map((visite) => VisiteModel(
|
||||||
|
id: visite.id,
|
||||||
|
name: visite.title,
|
||||||
|
photo: 1,
|
||||||
|
date: visite.date_visite.toString(),
|
||||||
|
image: visite.url_photo_principale,
|
||||||
|
type_visite: visite.type_visite,
|
||||||
|
price: 0,
|
||||||
|
rating: 0,
|
||||||
|
review: 0,
|
||||||
|
sale: 0,
|
||||||
|
stock: 10,
|
||||||
|
location: ""))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
// Return the list of VisiteModel
|
||||||
|
return visiteModels;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VisiteModel> visiteData = [
|
|
||||||
VisiteModel(
|
|
||||||
id: 1,
|
|
||||||
name: "Villeneuve d'asc ONE-STEP",
|
|
||||||
price: 62,
|
|
||||||
photo: 1,
|
|
||||||
image:
|
|
||||||
'https://mp4.ikksgroup.com/photos/1/0/1/8/4/4/101844-thumbnail.JPG',
|
|
||||||
rating: 5,
|
|
||||||
review: 42,
|
|
||||||
sale: 4,
|
|
||||||
stock: 5,
|
|
||||||
location: "Villeneuve d'asc",
|
|
||||||
date: 'Dimanche 26/02/2023 14:00')
|
|
||||||
];
|
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ class ApiProvider {
|
||||||
ApiConstants.externalEndpoint +
|
ApiConstants.externalEndpoint +
|
||||||
ApiConstants.restEndpoint +
|
ApiConstants.restEndpoint +
|
||||||
'/mobDR/visite/calendrier',
|
'/mobDR/visite/calendrier',
|
||||||
{"id_utilisateur": 6, "start": 20230101, "end": 20230131});
|
{"id_utilisateur": 6, "start": 20230101, "end": 20230501});
|
||||||
|
|
||||||
/// get "Visite tags" list
|
/// get "Visite tags" list
|
||||||
response2 = await getCrud(
|
response2 = await getCrud(
|
||||||
|
|
@ -274,6 +274,9 @@ class ApiProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response2.statusCode == STATUS_OK) {
|
if (response2.statusCode == STATUS_OK) {
|
||||||
|
// remove all objects
|
||||||
|
objectbox.visiteTagBox.removeAll();
|
||||||
|
|
||||||
/// fill box "visiteTag"
|
/// fill box "visiteTag"
|
||||||
objectbox.addVisiteTags(response2.data['tags']);
|
objectbox.addVisiteTags(response2.data['tags']);
|
||||||
}
|
}
|
||||||
|
|
@ -302,6 +305,9 @@ class ApiProvider {
|
||||||
null);
|
null);
|
||||||
|
|
||||||
if (response.statusCode == STATUS_OK) {
|
if (response.statusCode == STATUS_OK) {
|
||||||
|
// remove all objects
|
||||||
|
objectbox.photoTypologyBox.removeAll();
|
||||||
|
|
||||||
/// fill box "Photo typologies"
|
/// fill box "Photo typologies"
|
||||||
objectbox.addPhotoTypologies(response.data['typologies']);
|
objectbox.addPhotoTypologies(response.data['typologies']);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "7:8290500625256822711",
|
"id": "7:8290500625256822711",
|
||||||
"lastPropertyId": "11:3119168728902810585",
|
"lastPropertyId": "13:1900114397693432703",
|
||||||
"name": "Visite",
|
"name": "Visite",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
|
|
@ -243,6 +243,11 @@
|
||||||
"id": "11:3119168728902810585",
|
"id": "11:3119168728902810585",
|
||||||
"name": "date_visite",
|
"name": "date_visite",
|
||||||
"type": 10
|
"type": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13:1900114397693432703",
|
||||||
|
"name": "url_photo_principale",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
|
|
@ -283,7 +288,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9:6788844671665652158",
|
"id": "9:6788844671665652158",
|
||||||
"lastPropertyId": "16:539065583624712715",
|
"lastPropertyId": "17:7248999677905103482",
|
||||||
"name": "Photo",
|
"name": "Photo",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
|
|
@ -292,11 +297,6 @@
|
||||||
"type": 6,
|
"type": 6,
|
||||||
"flags": 1
|
"flags": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "2:7877546811840884522",
|
|
||||||
"name": "id_photo",
|
|
||||||
"type": 6
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "3:1374846727562410311",
|
"id": "3:1374846727562410311",
|
||||||
"name": "id_visite",
|
"name": "id_visite",
|
||||||
|
|
@ -327,26 +327,6 @@
|
||||||
"name": "photo_principale",
|
"name": "photo_principale",
|
||||||
"type": 6
|
"type": 6
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "10:2757780641715705310",
|
|
||||||
"name": "photo_tag1",
|
|
||||||
"type": 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "11:6494338359539955476",
|
|
||||||
"name": "photo_tag2",
|
|
||||||
"type": 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "12:5293139139799032553",
|
|
||||||
"name": "photo_tag3",
|
|
||||||
"type": 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "13:2141346538986140281",
|
|
||||||
"name": "photo_tag4",
|
|
||||||
"type": 9
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "14:4568092734700892012",
|
"id": "14:4568092734700892012",
|
||||||
"name": "uploaded",
|
"name": "uploaded",
|
||||||
|
|
@ -361,6 +341,11 @@
|
||||||
"id": "16:539065583624712715",
|
"id": "16:539065583624712715",
|
||||||
"name": "image_name",
|
"name": "image_name",
|
||||||
"type": 9
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "17:7248999677905103482",
|
||||||
|
"name": "tags",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
|
|
@ -396,7 +381,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastEntityId": "10:2779194860339140505",
|
"lastEntityId": "10:2779194860339140505",
|
||||||
"lastIndexId": "0:0",
|
"lastIndexId": "1:7907819717055295102",
|
||||||
"lastRelationId": "0:0",
|
"lastRelationId": "0:0",
|
||||||
"lastSequenceId": "0:0",
|
"lastSequenceId": "0:0",
|
||||||
"modelVersion": 5,
|
"modelVersion": 5,
|
||||||
|
|
@ -404,14 +389,22 @@
|
||||||
"retiredEntityUids": [
|
"retiredEntityUids": [
|
||||||
7401686910042688313
|
7401686910042688313
|
||||||
],
|
],
|
||||||
"retiredIndexUids": [],
|
"retiredIndexUids": [
|
||||||
|
7907819717055295102
|
||||||
|
],
|
||||||
"retiredPropertyUids": [
|
"retiredPropertyUids": [
|
||||||
402019719780433349,
|
402019719780433349,
|
||||||
2876428622751679696,
|
2876428622751679696,
|
||||||
6435857490868115471,
|
6435857490868115471,
|
||||||
4582947574501853036,
|
4582947574501853036,
|
||||||
103801570610300983,
|
103801570610300983,
|
||||||
1940661113633121688
|
1940661113633121688,
|
||||||
|
2757780641715705310,
|
||||||
|
6494338359539955476,
|
||||||
|
5293139139799032553,
|
||||||
|
2141346538986140281,
|
||||||
|
7877546811840884522,
|
||||||
|
3784190804330297742
|
||||||
],
|
],
|
||||||
"retiredRelationUids": [],
|
"retiredRelationUids": [],
|
||||||
"version": 1
|
"version": 1
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class ObjectBox {
|
||||||
userBox.removeAll();
|
userBox.removeAll();
|
||||||
etabBox.removeAll();
|
etabBox.removeAll();
|
||||||
concurrentBox.removeAll();
|
concurrentBox.removeAll();
|
||||||
visiteBox.removeAll();
|
//visiteBox.removeAll();
|
||||||
//visiteTagBox.removeAll();
|
//visiteTagBox.removeAll();
|
||||||
//photoBox.removeAll();
|
//photoBox.removeAll();
|
||||||
//photoTypologyBox.removeAll();
|
//photoTypologyBox.removeAll();
|
||||||
|
|
@ -240,7 +240,7 @@ class ObjectBox {
|
||||||
/// VISITE ------------------------------------------------------------------
|
/// VISITE ------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
|
||||||
Stream<List<Visite>> getVisites() {
|
Stream<List<Visite>> getVisitesStream() {
|
||||||
// Query for all visites, sorted by their date.
|
// Query for all visites, sorted by their date.
|
||||||
// https://docs.objectbox.io/queries
|
// https://docs.objectbox.io/queries
|
||||||
final builder =
|
final builder =
|
||||||
|
|
@ -253,12 +253,23 @@ class ObjectBox {
|
||||||
.map((query) => query.find());
|
.map((query) => query.find());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Visite> getAllVisites() {
|
||||||
|
// Query for all visites, sorted by their date.
|
||||||
|
final builder = visiteBox
|
||||||
|
.query()
|
||||||
|
.order(Visite_.date_visite, flags: Order.descending)
|
||||||
|
.build();
|
||||||
|
// Execute the query and return the result.
|
||||||
|
return builder.find();
|
||||||
|
}
|
||||||
|
|
||||||
// A function that converts a response body list into a List<Visite>.
|
// A function that converts a response body list into a List<Visite>.
|
||||||
List<Visite> parseVisites(List responseDataList) {
|
List<Visite> parseVisites(List responseDataList) {
|
||||||
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
||||||
return parsed.map<Visite>((json) => Visite.fromJson(json)).toList();
|
return parsed.map<Visite>((json) => Visite.fromJson(json)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO : Enregistre urlphotoprincipale sur le disque pour l'avoir en cache ?
|
||||||
Future<void> addVisites(List<dynamic> _listVisites) =>
|
Future<void> addVisites(List<dynamic> _listVisites) =>
|
||||||
store.runInTransactionAsync(
|
store.runInTransactionAsync(
|
||||||
TxMode.write, _addVisitesInTx, parseVisites(_listVisites));
|
TxMode.write, _addVisitesInTx, parseVisites(_listVisites));
|
||||||
|
|
@ -277,7 +288,8 @@ class ObjectBox {
|
||||||
int _id_distrib_visite,
|
int _id_distrib_visite,
|
||||||
int _id_etab,
|
int _id_etab,
|
||||||
int _abandon,
|
int _abandon,
|
||||||
String _end) =>
|
String _end,
|
||||||
|
String _url_photo_principale) =>
|
||||||
store.runInTransactionAsync(
|
store.runInTransactionAsync(
|
||||||
TxMode.write,
|
TxMode.write,
|
||||||
_addVisiteInTx,
|
_addVisiteInTx,
|
||||||
|
|
@ -289,7 +301,8 @@ class ObjectBox {
|
||||||
allDay: _allDay,
|
allDay: _allDay,
|
||||||
id_distrib_visite: _id_distrib_visite,
|
id_distrib_visite: _id_distrib_visite,
|
||||||
id_etab: _id_etab,
|
id_etab: _id_etab,
|
||||||
abandon: _abandon));
|
abandon: _abandon,
|
||||||
|
url_photo_principale: _url_photo_principale));
|
||||||
|
|
||||||
static void _addVisiteInTx(Store store, _Visite) {
|
static void _addVisiteInTx(Store store, _Visite) {
|
||||||
store.box<Visite>().put(_Visite);
|
store.box<Visite>().put(_Visite);
|
||||||
|
|
@ -299,10 +312,11 @@ class ObjectBox {
|
||||||
return visiteBox.count();
|
return visiteBox.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// VISITE TAG ---------------------------------------------------------------
|
//TODO changer en PHOTO TAG / mettre dans l'ordre CRUD
|
||||||
|
/// PHOTO TAG ---------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
|
||||||
// A function that converts a response body list into a List<VisiteTag>.
|
// converts a response body list into a List<VisiteTag>.
|
||||||
List<VisiteTag> parseVisiteTags(List responseDataList) {
|
List<VisiteTag> parseVisiteTags(List responseDataList) {
|
||||||
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
||||||
return parsed.map<VisiteTag>((json) => VisiteTag.fromJson(json)).toList();
|
return parsed.map<VisiteTag>((json) => VisiteTag.fromJson(json)).toList();
|
||||||
|
|
@ -316,6 +330,7 @@ class ObjectBox {
|
||||||
store.box<VisiteTag>().putMany(_VisiteTags);
|
store.box<VisiteTag>().putMany(_VisiteTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// save new tag for a distributor / langage
|
||||||
Future<void> addVisiteTag(
|
Future<void> addVisiteTag(
|
||||||
int _id_visite_tag,
|
int _id_visite_tag,
|
||||||
int _id_distrib,
|
int _id_distrib,
|
||||||
|
|
@ -336,23 +351,38 @@ class ObjectBox {
|
||||||
store.box<VisiteTag>().put(_VisiteTag);
|
store.box<VisiteTag>().put(_VisiteTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> getVisiteTagsLabels() {
|
List<String> getVisiteTagsLabels(int distribId, String langage) {
|
||||||
final query = visiteTagBox
|
final query = visiteTagBox
|
||||||
.query(VisiteTag_.langage.equals('fr'))
|
.query(VisiteTag_.id_distrib.equals(distribId) &
|
||||||
.order(VisiteTag_.libelle)
|
VisiteTag_.langage.equals(langage))
|
||||||
|
//.order(VisiteTag_.libelle)
|
||||||
.build();
|
.build();
|
||||||
final visiteTags = query.find();
|
PropertyQuery<String> pq = query.property(VisiteTag_.libelle);
|
||||||
return visiteTags.map((VisiteTag) => VisiteTag.libelle).toList();
|
pq.distinct = true;
|
||||||
|
pq.caseSensitive = false;
|
||||||
|
return pq.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getVisiteTagCount() {
|
int getVisiteTagCount() {
|
||||||
return visiteTagBox.count();
|
return visiteTagBox.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> putPhotoTags(int photoId, List<String> tags) async {
|
||||||
|
final photo = photoBox.get(photoId);
|
||||||
|
|
||||||
|
if (photo != null) {
|
||||||
|
final updatedPhoto = photo.copyWith(tags: tags.join(","));
|
||||||
|
await photoBox.putAsync(updatedPhoto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// PHOTO --------------------------------------------------------------------
|
/// PHOTO --------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
void addPhotos(List<Photo> _listPhotos) {
|
///
|
||||||
store.box<Photo>().putManyAsync(_listPhotos);
|
|
||||||
|
Future<List<Photo>> addPhotos(List<Photo> photos) async {
|
||||||
|
final addedPhotos = await photoBox.putAndGetManyAsync(photos);
|
||||||
|
return addedPhotos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addPhoto(int id_visite, int id_photo_typologie, String image,
|
Future<void> addPhoto(int id_visite, int id_photo_typologie, String image,
|
||||||
|
|
@ -372,7 +402,7 @@ class ObjectBox {
|
||||||
store.box<Photo>().put(_Photo);
|
store.box<Photo>().put(_Photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Photo> getPhotos2() {
|
List<Photo> getAllPhotos() {
|
||||||
// Query for all photos, sorted by their date.
|
// Query for all photos, sorted by their date.
|
||||||
// https://docs.objectbox.io/queries
|
// https://docs.objectbox.io/queries
|
||||||
final query = photoBox
|
final query = photoBox
|
||||||
|
|
@ -382,6 +412,18 @@ class ObjectBox {
|
||||||
return query.find();
|
return query.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieves a Photo object from the ObjectBox database with the specified ID.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// id_photo: The ID of the photo to retrieve.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// A Photo object, or null if no object is found.
|
||||||
|
Photo? getPhotoById(int id_photo) {
|
||||||
|
final photo = photoBox.get(id_photo);
|
||||||
|
return photo;
|
||||||
|
}
|
||||||
|
|
||||||
Stream<List<Photo>> getPhotos() {
|
Stream<List<Photo>> getPhotos() {
|
||||||
// Query for all photos, sorted by their date.
|
// Query for all photos, sorted by their date.
|
||||||
// https://docs.objectbox.io/queries
|
// https://docs.objectbox.io/queries
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ final _entities = <ModelEntity>[
|
||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(7, 8290500625256822711),
|
id: const IdUid(7, 8290500625256822711),
|
||||||
name: 'Visite',
|
name: 'Visite',
|
||||||
lastPropertyId: const IdUid(11, 3119168728902810585),
|
lastPropertyId: const IdUid(13, 1900114397693432703),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
|
|
@ -267,6 +267,11 @@ final _entities = <ModelEntity>[
|
||||||
id: const IdUid(11, 3119168728902810585),
|
id: const IdUid(11, 3119168728902810585),
|
||||||
name: 'date_visite',
|
name: 'date_visite',
|
||||||
type: 10,
|
type: 10,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(13, 1900114397693432703),
|
||||||
|
name: 'url_photo_principale',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
|
|
@ -308,7 +313,7 @@ final _entities = <ModelEntity>[
|
||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(9, 6788844671665652158),
|
id: const IdUid(9, 6788844671665652158),
|
||||||
name: 'Photo',
|
name: 'Photo',
|
||||||
lastPropertyId: const IdUid(16, 539065583624712715),
|
lastPropertyId: const IdUid(17, 7248999677905103482),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
|
|
@ -316,11 +321,6 @@ final _entities = <ModelEntity>[
|
||||||
name: 'id',
|
name: 'id',
|
||||||
type: 6,
|
type: 6,
|
||||||
flags: 1),
|
flags: 1),
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(2, 7877546811840884522),
|
|
||||||
name: 'id_photo',
|
|
||||||
type: 6,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
id: const IdUid(3, 1374846727562410311),
|
id: const IdUid(3, 1374846727562410311),
|
||||||
name: 'id_visite',
|
name: 'id_visite',
|
||||||
|
|
@ -351,26 +351,6 @@ final _entities = <ModelEntity>[
|
||||||
name: 'photo_principale',
|
name: 'photo_principale',
|
||||||
type: 6,
|
type: 6,
|
||||||
flags: 0),
|
flags: 0),
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(10, 2757780641715705310),
|
|
||||||
name: 'photo_tag1',
|
|
||||||
type: 9,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(11, 6494338359539955476),
|
|
||||||
name: 'photo_tag2',
|
|
||||||
type: 9,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(12, 5293139139799032553),
|
|
||||||
name: 'photo_tag3',
|
|
||||||
type: 9,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(13, 2141346538986140281),
|
|
||||||
name: 'photo_tag4',
|
|
||||||
type: 9,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
id: const IdUid(14, 4568092734700892012),
|
id: const IdUid(14, 4568092734700892012),
|
||||||
name: 'uploaded',
|
name: 'uploaded',
|
||||||
|
|
@ -385,6 +365,11 @@ final _entities = <ModelEntity>[
|
||||||
id: const IdUid(16, 539065583624712715),
|
id: const IdUid(16, 539065583624712715),
|
||||||
name: 'image_name',
|
name: 'image_name',
|
||||||
type: 9,
|
type: 9,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(17, 7248999677905103482),
|
||||||
|
name: 'tags',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
|
|
@ -441,18 +426,24 @@ ModelDefinition getObjectBoxModel() {
|
||||||
final model = ModelInfo(
|
final model = ModelInfo(
|
||||||
entities: _entities,
|
entities: _entities,
|
||||||
lastEntityId: const IdUid(10, 2779194860339140505),
|
lastEntityId: const IdUid(10, 2779194860339140505),
|
||||||
lastIndexId: const IdUid(0, 0),
|
lastIndexId: const IdUid(1, 7907819717055295102),
|
||||||
lastRelationId: const IdUid(0, 0),
|
lastRelationId: const IdUid(0, 0),
|
||||||
lastSequenceId: const IdUid(0, 0),
|
lastSequenceId: const IdUid(0, 0),
|
||||||
retiredEntityUids: const [7401686910042688313],
|
retiredEntityUids: const [7401686910042688313],
|
||||||
retiredIndexUids: const [],
|
retiredIndexUids: const [7907819717055295102],
|
||||||
retiredPropertyUids: const [
|
retiredPropertyUids: const [
|
||||||
402019719780433349,
|
402019719780433349,
|
||||||
2876428622751679696,
|
2876428622751679696,
|
||||||
6435857490868115471,
|
6435857490868115471,
|
||||||
4582947574501853036,
|
4582947574501853036,
|
||||||
103801570610300983,
|
103801570610300983,
|
||||||
1940661113633121688
|
1940661113633121688,
|
||||||
|
2757780641715705310,
|
||||||
|
6494338359539955476,
|
||||||
|
5293139139799032553,
|
||||||
|
2141346538986140281,
|
||||||
|
7877546811840884522,
|
||||||
|
3784190804330297742
|
||||||
],
|
],
|
||||||
retiredRelationUids: const [],
|
retiredRelationUids: const [],
|
||||||
modelVersion: 5,
|
modelVersion: 5,
|
||||||
|
|
@ -676,7 +667,9 @@ ModelDefinition getObjectBoxModel() {
|
||||||
objectToFB: (Visite object, fb.Builder fbb) {
|
objectToFB: (Visite object, fb.Builder fbb) {
|
||||||
final type_visiteOffset = fbb.writeString(object.type_visite);
|
final type_visiteOffset = fbb.writeString(object.type_visite);
|
||||||
final titleOffset = fbb.writeString(object.title);
|
final titleOffset = fbb.writeString(object.title);
|
||||||
fbb.startTable(12);
|
final url_photo_principaleOffset =
|
||||||
|
fbb.writeString(object.url_photo_principale);
|
||||||
|
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.addOffset(2, type_visiteOffset);
|
fbb.addOffset(2, type_visiteOffset);
|
||||||
|
|
@ -686,6 +679,7 @@ ModelDefinition getObjectBoxModel() {
|
||||||
fbb.addInt64(7, object.id_etab);
|
fbb.addInt64(7, object.id_etab);
|
||||||
fbb.addInt64(8, object.abandon);
|
fbb.addInt64(8, object.abandon);
|
||||||
fbb.addInt64(10, object.date_visite.millisecondsSinceEpoch);
|
fbb.addInt64(10, object.date_visite.millisecondsSinceEpoch);
|
||||||
|
fbb.addOffset(12, url_photo_principaleOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
|
|
@ -710,7 +704,10 @@ ModelDefinition getObjectBoxModel() {
|
||||||
id_etab:
|
id_etab:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
|
||||||
abandon:
|
abandon:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0));
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0),
|
||||||
|
url_photo_principale:
|
||||||
|
const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGet(buffer, rootOffset, 28, ''));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
|
|
@ -760,28 +757,21 @@ ModelDefinition getObjectBoxModel() {
|
||||||
object.id = id;
|
object.id = id;
|
||||||
},
|
},
|
||||||
objectToFB: (Photo object, fb.Builder fbb) {
|
objectToFB: (Photo object, fb.Builder fbb) {
|
||||||
final photo_tag1Offset = fbb.writeString(object.photo_tag1);
|
|
||||||
final photo_tag2Offset = fbb.writeString(object.photo_tag2);
|
|
||||||
final photo_tag3Offset = fbb.writeString(object.photo_tag3);
|
|
||||||
final photo_tag4Offset = fbb.writeString(object.photo_tag4);
|
|
||||||
final imageOffset = fbb.writeString(object.image);
|
final imageOffset = fbb.writeString(object.image);
|
||||||
final image_nameOffset = fbb.writeString(object.image_name);
|
final image_nameOffset = fbb.writeString(object.image_name);
|
||||||
fbb.startTable(17);
|
final tagsOffset = fbb.writeString(object.tags);
|
||||||
|
fbb.startTable(18);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.id_photo);
|
|
||||||
fbb.addInt64(2, object.id_visite);
|
fbb.addInt64(2, object.id_visite);
|
||||||
fbb.addInt64(3, object.id_photo_typologie);
|
fbb.addInt64(3, object.id_photo_typologie);
|
||||||
fbb.addInt64(5, object.date_photo.millisecondsSinceEpoch);
|
fbb.addInt64(5, object.date_photo.millisecondsSinceEpoch);
|
||||||
fbb.addInt64(6, object.id_photo_mp4);
|
fbb.addInt64(6, object.id_photo_mp4);
|
||||||
fbb.addInt64(7, object.photo_privee);
|
fbb.addInt64(7, object.photo_privee);
|
||||||
fbb.addInt64(8, object.photo_principale);
|
fbb.addInt64(8, object.photo_principale);
|
||||||
fbb.addOffset(9, photo_tag1Offset);
|
|
||||||
fbb.addOffset(10, photo_tag2Offset);
|
|
||||||
fbb.addOffset(11, photo_tag3Offset);
|
|
||||||
fbb.addOffset(12, photo_tag4Offset);
|
|
||||||
fbb.addInt64(13, object.uploaded);
|
fbb.addInt64(13, object.uploaded);
|
||||||
fbb.addOffset(14, imageOffset);
|
fbb.addOffset(14, imageOffset);
|
||||||
fbb.addOffset(15, image_nameOffset);
|
fbb.addOffset(15, image_nameOffset);
|
||||||
|
fbb.addOffset(16, tagsOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
|
|
@ -799,23 +789,18 @@ ModelDefinition getObjectBoxModel() {
|
||||||
.vTableGet(buffer, rootOffset, 32, ''),
|
.vTableGet(buffer, rootOffset, 32, ''),
|
||||||
image_name: const fb.StringReader(asciiOptimization: true)
|
image_name: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 34, ''),
|
.vTableGet(buffer, rootOffset, 34, ''),
|
||||||
id_photo:
|
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
|
|
||||||
id_photo_mp4:
|
id_photo_mp4:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0),
|
||||||
photo_privee:
|
photo_privee:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
|
||||||
photo_principale:
|
photo_principale:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0),
|
||||||
photo_tag1: const fb.StringReader(asciiOptimization: true)
|
tags: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 22, ''),
|
.vTableGet(buffer, rootOffset, 36, ''),
|
||||||
photo_tag2: const fb.StringReader(asciiOptimization: true)
|
date_photo: DateTime.fromMillisecondsSinceEpoch(
|
||||||
.vTableGet(buffer, rootOffset, 24, ''),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 14, 0)),
|
||||||
photo_tag3:
|
uploaded:
|
||||||
const fb.StringReader(asciiOptimization: true).vTableGet(buffer, rootOffset, 26, ''),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 30, 0));
|
||||||
photo_tag4: const fb.StringReader(asciiOptimization: true).vTableGet(buffer, rootOffset, 28, ''),
|
|
||||||
date_photo: DateTime.fromMillisecondsSinceEpoch(const fb.Int64Reader().vTableGet(buffer, rootOffset, 14, 0)),
|
|
||||||
uploaded: const fb.Int64Reader().vTableGet(buffer, rootOffset, 30, 0));
|
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
|
|
@ -1001,6 +986,10 @@ class Visite_ {
|
||||||
/// see [Visite.date_visite]
|
/// see [Visite.date_visite]
|
||||||
static final date_visite =
|
static final date_visite =
|
||||||
QueryIntegerProperty<Visite>(_entities[5].properties[8]);
|
QueryIntegerProperty<Visite>(_entities[5].properties[8]);
|
||||||
|
|
||||||
|
/// see [Visite.url_photo_principale]
|
||||||
|
static final url_photo_principale =
|
||||||
|
QueryStringProperty<Visite>(_entities[5].properties[9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [VisiteTag] entity fields to define ObjectBox queries.
|
/// [VisiteTag] entity fields to define ObjectBox queries.
|
||||||
|
|
@ -1030,60 +1019,43 @@ class Photo_ {
|
||||||
/// see [Photo.id]
|
/// see [Photo.id]
|
||||||
static final id = QueryIntegerProperty<Photo>(_entities[7].properties[0]);
|
static final id = QueryIntegerProperty<Photo>(_entities[7].properties[0]);
|
||||||
|
|
||||||
/// see [Photo.id_photo]
|
|
||||||
static final id_photo =
|
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[1]);
|
|
||||||
|
|
||||||
/// see [Photo.id_visite]
|
/// see [Photo.id_visite]
|
||||||
static final id_visite =
|
static final id_visite =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[2]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[1]);
|
||||||
|
|
||||||
/// see [Photo.id_photo_typologie]
|
/// see [Photo.id_photo_typologie]
|
||||||
static final id_photo_typologie =
|
static final id_photo_typologie =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[3]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[2]);
|
||||||
|
|
||||||
/// see [Photo.date_photo]
|
/// see [Photo.date_photo]
|
||||||
static final date_photo =
|
static final date_photo =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[4]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[3]);
|
||||||
|
|
||||||
/// see [Photo.id_photo_mp4]
|
/// see [Photo.id_photo_mp4]
|
||||||
static final id_photo_mp4 =
|
static final id_photo_mp4 =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[5]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[4]);
|
||||||
|
|
||||||
/// see [Photo.photo_privee]
|
/// see [Photo.photo_privee]
|
||||||
static final photo_privee =
|
static final photo_privee =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[6]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[5]);
|
||||||
|
|
||||||
/// see [Photo.photo_principale]
|
/// see [Photo.photo_principale]
|
||||||
static final photo_principale =
|
static final photo_principale =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[7]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[6]);
|
||||||
|
|
||||||
/// see [Photo.photo_tag1]
|
|
||||||
static final photo_tag1 =
|
|
||||||
QueryStringProperty<Photo>(_entities[7].properties[8]);
|
|
||||||
|
|
||||||
/// see [Photo.photo_tag2]
|
|
||||||
static final photo_tag2 =
|
|
||||||
QueryStringProperty<Photo>(_entities[7].properties[9]);
|
|
||||||
|
|
||||||
/// see [Photo.photo_tag3]
|
|
||||||
static final photo_tag3 =
|
|
||||||
QueryStringProperty<Photo>(_entities[7].properties[10]);
|
|
||||||
|
|
||||||
/// see [Photo.photo_tag4]
|
|
||||||
static final photo_tag4 =
|
|
||||||
QueryStringProperty<Photo>(_entities[7].properties[11]);
|
|
||||||
|
|
||||||
/// see [Photo.uploaded]
|
/// see [Photo.uploaded]
|
||||||
static final uploaded =
|
static final uploaded =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[12]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[7]);
|
||||||
|
|
||||||
/// see [Photo.image]
|
/// see [Photo.image]
|
||||||
static final image = QueryStringProperty<Photo>(_entities[7].properties[13]);
|
static final image = QueryStringProperty<Photo>(_entities[7].properties[8]);
|
||||||
|
|
||||||
/// see [Photo.image_name]
|
/// see [Photo.image_name]
|
||||||
static final image_name =
|
static final image_name =
|
||||||
QueryStringProperty<Photo>(_entities[7].properties[14]);
|
QueryStringProperty<Photo>(_entities[7].properties[9]);
|
||||||
|
|
||||||
|
/// see [Photo.tags]
|
||||||
|
static final tags = QueryStringProperty<Photo>(_entities[7].properties[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [PhotoTypology] entity fields to define ObjectBox queries.
|
/// [PhotoTypology] entity fields to define ObjectBox queries.
|
||||||
|
|
|
||||||
|
|
@ -88,4 +88,18 @@ class SharedPrefs {
|
||||||
set photo(String value) {
|
set photo(String value) {
|
||||||
_sharedPrefs.setString('key_photo', value);
|
_sharedPrefs.setString('key_photo', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get/set id_distrib
|
||||||
|
int get id_distrib => _sharedPrefs.getInt('key_id_distrib') ?? 0;
|
||||||
|
|
||||||
|
set id_distrib(int value) {
|
||||||
|
_sharedPrefs.setInt('key_id_distrib', 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:filter_list/filter_list.dart';
|
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
import 'package:mobdr/config/global_style.dart';
|
import 'package:mobdr/config/global_style.dart';
|
||||||
|
|
@ -10,14 +10,20 @@ import 'package:mobdr/main.dart';
|
||||||
import 'package:mobdr/ui/general/chat_us.dart';
|
import 'package:mobdr/ui/general/chat_us.dart';
|
||||||
import 'package:mobdr/ui/general/notification.dart';
|
import 'package:mobdr/ui/general/notification.dart';
|
||||||
import 'package:mobdr/ui/home/product_category.dart';
|
import 'package:mobdr/ui/home/product_category.dart';
|
||||||
|
import 'package:mobdr/ui/home/photo_tag.dart';
|
||||||
import 'package:mobdr/ui/home/search.dart';
|
import 'package:mobdr/ui/home/search.dart';
|
||||||
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
||||||
import 'package:mobdr/ui/shopping_cart/tab_shopping_cart.dart';
|
import 'package:mobdr/ui/shopping_cart/tab_shopping_cart.dart';
|
||||||
import 'package:mobdr/ui/reusable/global_function.dart';
|
import 'package:mobdr/ui/reusable/global_function.dart';
|
||||||
|
|
||||||
|
import 'package:mobdr/db/box_photo.dart';
|
||||||
|
|
||||||
class PhotoDetailPage extends StatefulWidget {
|
class PhotoDetailPage extends StatefulWidget {
|
||||||
|
// variables corresponding to the data parameters
|
||||||
|
final int id;
|
||||||
final String name;
|
final String name;
|
||||||
final String image;
|
final String image;
|
||||||
|
final String tags;
|
||||||
final double price;
|
final double price;
|
||||||
final int photo;
|
final int photo;
|
||||||
final double rating;
|
final double rating;
|
||||||
|
|
@ -25,10 +31,13 @@ class PhotoDetailPage extends StatefulWidget {
|
||||||
final int sale;
|
final int sale;
|
||||||
final String date;
|
final String date;
|
||||||
|
|
||||||
|
// Requiring data parameters
|
||||||
const PhotoDetailPage(
|
const PhotoDetailPage(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
|
this.id = 0,
|
||||||
this.name = '',
|
this.name = '',
|
||||||
this.image = '',
|
this.image = '',
|
||||||
|
this.tags = '',
|
||||||
this.price = 24,
|
this.price = 24,
|
||||||
this.photo = 1,
|
this.photo = 1,
|
||||||
this.rating = 4,
|
this.rating = 4,
|
||||||
|
|
@ -46,8 +55,11 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
final _globalFunction = GlobalFunction();
|
final _globalFunction = GlobalFunction();
|
||||||
final _reusableWidget = ReusableWidget();
|
final _reusableWidget = ReusableWidget();
|
||||||
|
|
||||||
|
bool _isLoading = true;
|
||||||
|
String _errorMessage = '';
|
||||||
|
|
||||||
// Typology list
|
// Typology list
|
||||||
List<String> _typologyList = objectbox.getPhotoTypologiesLabels();
|
late List<String> _typologyList = [];
|
||||||
int _typologyIndex = 0;
|
int _typologyIndex = 0;
|
||||||
|
|
||||||
List<String> _chickenParts = [];
|
List<String> _chickenParts = [];
|
||||||
|
|
@ -56,13 +68,20 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
// shopping cart count
|
// shopping cart count
|
||||||
int _shoppingCartCount = 3;
|
int _shoppingCartCount = 3;
|
||||||
|
|
||||||
// tag(s) list
|
late String tags = "";
|
||||||
final List<String> tagsList = objectbox.getVisiteTagsLabels();
|
late List<String> tagList = [];
|
||||||
List<String> selectedTagsList = [];
|
|
||||||
|
late Photo _photo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
loadData(widget.id).then((_) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -72,6 +91,24 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (_isLoading) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
} else if (_errorMessage.isNotEmpty) {
|
||||||
|
return Center(
|
||||||
|
child: AlertDialog(
|
||||||
|
title: Text("Erreur"),
|
||||||
|
content: Text("La photo est introuvable"),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: Text("OK"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
iconTheme: IconThemeData(
|
iconTheme: IconThemeData(
|
||||||
|
|
@ -150,7 +187,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
//_createProductSlider(),
|
//_createProductSlider(),
|
||||||
_buildPhotoTypology(),
|
_buildPhotoTypology(),
|
||||||
_buildPhotoVisibility(),
|
_buildPhotoVisibility(),
|
||||||
_buildPhotoTag(),
|
_buildPhotoTag(context),
|
||||||
SizedBox(height: 16)
|
SizedBox(height: 16)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -302,6 +339,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO changer chicken
|
||||||
Widget _checboxChicken({value = 'breast', primaryText = 'Chicken Breast'}) {
|
Widget _checboxChicken({value = 'breast', primaryText = 'Chicken Breast'}) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
|
|
@ -379,74 +417,69 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPhotoTag() {
|
Widget _buildPhotoTag(BuildContext context) {
|
||||||
return Container(
|
return GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
// Navigation to the PhotoTagPage
|
||||||
|
final newTags = await Navigator.push<List<String>>(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
PhotoTagPage(photoId: this._photo.id, currentTags: tagList),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Checking changes made to tags
|
||||||
|
if (newTags != null && !listEquals(tagList, newTags)) {
|
||||||
|
setState(() {
|
||||||
|
tagList = newTags;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
margin: EdgeInsets.only(top: 12),
|
margin: EdgeInsets.only(top: 12),
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text("Tags sélectionnés:"),
|
Row(
|
||||||
SizedBox(height: 8),
|
children: [
|
||||||
selectedTagsList.isEmpty
|
Text('Tags', style: GlobalStyle.sectionTitle),
|
||||||
? Text("Aucun tag sélectionné.")
|
],
|
||||||
: Column(
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Wrap(
|
||||||
children: tagsList.map((tag) => Text("- $tag")).toList(),
|
spacing: 8.0,
|
||||||
),
|
runSpacing: 8.0,
|
||||||
SizedBox(height: 16),
|
alignment: WrapAlignment.start,
|
||||||
ElevatedButton(
|
children: tagList.map((tag) {
|
||||||
onPressed: () => _openTagSelectionDialog(),
|
return Chip(
|
||||||
child: Text("Modifier"),
|
label: Text(tag),
|
||||||
|
backgroundColor: Colors.grey[300],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
));
|
),
|
||||||
}
|
),
|
||||||
|
|
||||||
Future<void> _openTagSelectionDialog() async {
|
|
||||||
await FilterListDialog.display<String>(
|
|
||||||
context,
|
|
||||||
hideSelectedTextCount: true,
|
|
||||||
themeData: FilterListThemeData(context),
|
|
||||||
headlineText: 'Select Users',
|
|
||||||
height: 500,
|
|
||||||
listData: tagsList,
|
|
||||||
selectedListData: selectedTagsList,
|
|
||||||
choiceChipLabel: (item) => item,
|
|
||||||
validateSelectedItem: (list, val) => list!.contains(val),
|
|
||||||
controlButtons: [ControlButtonType.All, ControlButtonType.Reset],
|
|
||||||
onItemSearch: (user, query) {
|
|
||||||
/// When search query change in search bar then this method will be called
|
|
||||||
///
|
|
||||||
/// Check if items contains query
|
|
||||||
return user.toLowerCase().contains(query.toLowerCase());
|
|
||||||
},
|
|
||||||
|
|
||||||
onApplyButtonClick: (list) {
|
|
||||||
setState(() {
|
|
||||||
selectedTagsList = list!;
|
|
||||||
});
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
|
|
||||||
/// uncomment below code to create custom choice chip
|
|
||||||
/*
|
|
||||||
choiceChipBuilder: (context, item, isSelected) {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border.all(
|
|
||||||
color: isSelected! ? Colors.blue[300]! : Colors.grey[300]!,
|
|
||||||
)),
|
|
||||||
child: Text(
|
|
||||||
item,
|
|
||||||
style: TextStyle(
|
|
||||||
color: isSelected ? Colors.blue[300] : Colors.grey[500]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},*/
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// data initialization on loading.
|
||||||
|
Future<void> loadData(int photoId) async {
|
||||||
|
try {
|
||||||
|
// photo typologies initialization
|
||||||
|
_typologyList = objectbox.getPhotoTypologiesLabels();
|
||||||
|
|
||||||
|
// get photo object
|
||||||
|
_photo = objectbox.getPhotoById(photoId)!;
|
||||||
|
|
||||||
|
// photo tag initialization
|
||||||
|
tags = _photo.tags;
|
||||||
|
tagList = tags.isEmpty ? [] : tags.split(",");
|
||||||
|
} catch (e) {
|
||||||
|
// set errorMessage for debug
|
||||||
|
_errorMessage = 'Error loading photo: $e';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import 'package:mobdr/config/constant.dart';
|
||||||
import 'package:mobdr/main.dart';
|
import 'package:mobdr/main.dart';
|
||||||
import 'package:mobdr/ui/reusable/global_widget.dart';
|
import 'package:mobdr/ui/reusable/global_widget.dart';
|
||||||
import 'package:mobdr/ui/home/photo_camera.dart';
|
import 'package:mobdr/ui/home/photo_camera.dart';
|
||||||
import 'package:mobdr/model/photo_model.dart';
|
|
||||||
import 'package:mobdr/db/box_photo.dart';
|
import 'package:mobdr/db/box_photo.dart';
|
||||||
import 'package:mobdr/ui/home/photo_detail.dart';
|
import 'package:mobdr/ui/home/photo_detail.dart';
|
||||||
|
|
||||||
|
|
@ -37,7 +36,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
|
|
||||||
// initialize photos files list
|
// initialize photos files list
|
||||||
final List<File> photoFiles = [];
|
final List<File> photoFiles = [];
|
||||||
List<PhotoModel> _photoData = [];
|
List<Photo> _photoData = [];
|
||||||
|
|
||||||
Color _color1 = Color(0xff777777);
|
Color _color1 = Color(0xff777777);
|
||||||
Color _color2 = Color(0xFF515151);
|
Color _color2 = Color(0xFF515151);
|
||||||
|
|
@ -57,13 +56,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadData() {
|
void _loadData() {
|
||||||
for (Photo myPhoto in objectbox.getPhotos2()) {
|
_photoData = objectbox.getAllPhotos();
|
||||||
_photoData.add(PhotoModel(
|
|
||||||
id_visite: myPhoto.id_visite,
|
|
||||||
id_photo_typologie: myPhoto.id_photo_typologie,
|
|
||||||
image: myPhoto.image,
|
|
||||||
image_name: myPhoto.image_name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -114,8 +107,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
floatingActionButton: fabCart(context));
|
floatingActionButton: fabCart(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPhotolistCard(
|
Widget _buildPhotolistCard(Photo photoData, boxImageSize, animation, index) {
|
||||||
PhotoModel photoData, boxImageSize, animation, index) {
|
|
||||||
return SizeTransition(
|
return SizeTransition(
|
||||||
sizeFactor: animation,
|
sizeFactor: animation,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
@ -136,6 +128,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => PhotoDetailPage(
|
builder: (context) => PhotoDetailPage(
|
||||||
|
id: _photoData[index].id,
|
||||||
name: 'visiteData.name',
|
name: 'visiteData.name',
|
||||||
image: _photoData[index].image,
|
image: _photoData[index].image,
|
||||||
price: 0,
|
price: 0,
|
||||||
|
|
@ -144,6 +137,12 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
review: 0,
|
review: 0,
|
||||||
sale: 0,
|
sale: 0,
|
||||||
date: '')));
|
date: '')));
|
||||||
|
|
||||||
|
// todo if qq chose à changé
|
||||||
|
// ne raffraichir que le widget en cours ==
|
||||||
|
setState(() {
|
||||||
|
_listKey = GlobalKey();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
|
@ -414,32 +413,24 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
void savePhotos() async {
|
void savePhotos() async {
|
||||||
if (photoFiles.length > 0) {
|
if (photoFiles.length > 0) {
|
||||||
final List<Photo> _listPhotos = [];
|
final List<Photo> _listPhotos = [];
|
||||||
final List<PhotoModel> _listPhotosModel = [];
|
|
||||||
|
|
||||||
for (var myTmpPhoto in photoFiles) {
|
for (var myTmpPhoto in photoFiles) {
|
||||||
/// move jpg file to photo directory
|
/// move jpg file to photo directory
|
||||||
final myPhoto = await moveFileFromTempToPhotosDir(myTmpPhoto);
|
final myPhoto = await moveFileFromTempToPhotosDir(myTmpPhoto);
|
||||||
|
|
||||||
/// database
|
/// to insert into database
|
||||||
_listPhotos.add(Photo(
|
_listPhotos.add(Photo(
|
||||||
id_visite: 0,
|
id_visite: 0,
|
||||||
id_photo_typologie: 0,
|
id_photo_typologie: 0,
|
||||||
image: myPhoto.path,
|
image: myPhoto.path,
|
||||||
image_name: myPhoto.path.split('/').last));
|
image_name: myPhoto.path.split('/').last));
|
||||||
|
|
||||||
/// widget
|
|
||||||
_listPhotosModel.add(PhotoModel(
|
|
||||||
id_visite: 0,
|
|
||||||
id_photo_typologie: 0,
|
|
||||||
image: myPhoto.path,
|
|
||||||
image_name: myPhoto.path.split('/').last));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// insert photo(s) in database (async)
|
/// insert photo(s) in database (async)
|
||||||
objectbox.addPhotos(_listPhotos);
|
final addedPhotos = await objectbox.addPhotos(_listPhotos);
|
||||||
|
|
||||||
/// insert photo(s) in widget
|
/// insert photo(s) in widget at the beginning (0)
|
||||||
_photoData.insertAll(0, _listPhotosModel);
|
_photoData.insertAll(0, addedPhotos);
|
||||||
|
|
||||||
/// refresh widget
|
/// refresh widget
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,268 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
import 'package:mobdr/main.dart';
|
||||||
|
import 'package:mobdr/config/global_style.dart';
|
||||||
|
|
||||||
|
import 'package:super_tag_editor/tag_editor.dart';
|
||||||
|
import 'package:super_tag_editor/widgets/rich_text_widget.dart';
|
||||||
|
|
||||||
|
class PhotoTagPage extends StatefulWidget {
|
||||||
|
// variables corresponding to the data parameters
|
||||||
|
final int photoId;
|
||||||
|
final List<String> currentTags;
|
||||||
|
|
||||||
|
// Requiring data parameters
|
||||||
|
const PhotoTagPage(
|
||||||
|
{Key? key, required this.photoId, required this.currentTags})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PhotoTagPageState createState() => _PhotoTagPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PhotoTagPageState extends State<PhotoTagPage> {
|
||||||
|
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
late List<String> allTagsList = [];
|
||||||
|
late List<String> _selectedTags = [];
|
||||||
|
bool isLoading = true;
|
||||||
|
|
||||||
|
final FocusNode _focusNode = FocusNode();
|
||||||
|
final TextEditingController _textEditingController = TextEditingController();
|
||||||
|
bool focusTagEnabled = false;
|
||||||
|
|
||||||
|
_onDelete(index) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTags.removeAt(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
loadData().then((_) {
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (isLoading) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
appBar: AppBar(
|
||||||
|
iconTheme: IconThemeData(
|
||||||
|
color: GlobalStyle.appBarIconThemeColor,
|
||||||
|
),
|
||||||
|
elevation: GlobalStyle.appBarElevation,
|
||||||
|
title: Text(
|
||||||
|
'Edit tags ...',
|
||||||
|
style: GlobalStyle.appBarTitle,
|
||||||
|
),
|
||||||
|
backgroundColor: GlobalStyle.appBarBackgroundColor,
|
||||||
|
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle),
|
||||||
|
body: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
TagEditor<String>(
|
||||||
|
length: _selectedTags.length,
|
||||||
|
controller: _textEditingController,
|
||||||
|
focusNode: _focusNode,
|
||||||
|
delimiters: [',', ' '],
|
||||||
|
hasAddButton: true,
|
||||||
|
resetTextOnSubmitted: true,
|
||||||
|
// This is set to grey just to illustrate the `textStyle` prop
|
||||||
|
textStyle: const TextStyle(color: Colors.grey),
|
||||||
|
onSubmitted: (outstandingValue) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTags.add(outstandingValue);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
inputDecoration: const InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: 'Enter tag ...',
|
||||||
|
),
|
||||||
|
onTagChanged: (newValue) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTags.add(newValue);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
tagBuilder: (context, index) => Container(
|
||||||
|
color: focusTagEnabled && index == _selectedTags.length - 1
|
||||||
|
? Colors.redAccent
|
||||||
|
: Colors.white,
|
||||||
|
child: _Chip(
|
||||||
|
index: index,
|
||||||
|
label: _selectedTags[index],
|
||||||
|
onDeleted: _onDelete,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// InputFormatters example, this disallow \ and /
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.deny(RegExp(r'[/\\]'))
|
||||||
|
],
|
||||||
|
useDefaultHighlight: false,
|
||||||
|
suggestionBuilder: (context, state, data, index, length,
|
||||||
|
highlight, suggestionValid) {
|
||||||
|
var borderRadius =
|
||||||
|
const BorderRadius.all(Radius.circular(20));
|
||||||
|
if (index == 0) {
|
||||||
|
borderRadius = const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(20),
|
||||||
|
topRight: Radius.circular(20),
|
||||||
|
);
|
||||||
|
} else if (index == length - 1) {
|
||||||
|
borderRadius = const BorderRadius.only(
|
||||||
|
bottomRight: Radius.circular(20),
|
||||||
|
bottomLeft: Radius.circular(20),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedTags.add(data);
|
||||||
|
});
|
||||||
|
state.resetTextField();
|
||||||
|
state.closeSuggestionBox();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: highlight
|
||||||
|
? BoxDecoration(
|
||||||
|
color: Theme.of(context).focusColor,
|
||||||
|
borderRadius: borderRadius)
|
||||||
|
: null,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: RichTextWidget(
|
||||||
|
wordSearched: suggestionValid ?? '',
|
||||||
|
textOrigin: data,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onFocusTagAction: (focused) {
|
||||||
|
setState(() {
|
||||||
|
focusTagEnabled = focused;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDeleteTagAction: () {
|
||||||
|
if (_selectedTags.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTags.removeLast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectOptionAction: (item) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTags.add(item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
suggestionsBoxElevation: 10,
|
||||||
|
findSuggestions: (String query) {
|
||||||
|
if (query.isNotEmpty) {
|
||||||
|
var lowercaseQuery = query.toLowerCase();
|
||||||
|
var filteredList = allTagsList
|
||||||
|
.where((tag) =>
|
||||||
|
!_selectedTags.contains(tag) &&
|
||||||
|
(tag.toLowerCase().startsWith(lowercaseQuery) ||
|
||||||
|
tag.toLowerCase().contains(lowercaseQuery)))
|
||||||
|
.toList(growable: false);
|
||||||
|
|
||||||
|
filteredList.sort((a, b) => a
|
||||||
|
.toLowerCase()
|
||||||
|
.indexOf(lowercaseQuery)
|
||||||
|
.compareTo(b.toLowerCase().indexOf(lowercaseQuery)));
|
||||||
|
|
||||||
|
return filteredList;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
// Save the selected tags to the database //TODO 1,fr ===
|
||||||
|
await saveSelectedTags(_selectedTags, 1, 'fr');
|
||||||
|
|
||||||
|
Navigator.pop(
|
||||||
|
context, _selectedTags.map((tag) => tag).toList());
|
||||||
|
},
|
||||||
|
child: const Text('Save'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadData() async {
|
||||||
|
// TODO 1,fr
|
||||||
|
allTagsList = await objectbox.getVisiteTagsLabels(1, 'fr');
|
||||||
|
_selectedTags = List<String>.from(widget.currentTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Saves the selected tags for a photo to the ObjectBox database.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// tags: The list of tags to save.
|
||||||
|
/// distribId: The ID of the distribution associated with the photo.
|
||||||
|
/// langage: The language code for the tags.
|
||||||
|
///
|
||||||
|
/// If the list of tags is empty, the function will exit without saving any tags.
|
||||||
|
/// Otherwise, any new tags that are not already in the database will be added,
|
||||||
|
/// and the photo's tags will be saved to the database.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// Nothing.
|
||||||
|
Future<void> saveSelectedTags(
|
||||||
|
List<String> tags, int distribId, String langage) async {
|
||||||
|
if (tags.isEmpty) {
|
||||||
|
return; // exit function without saving tags
|
||||||
|
}
|
||||||
|
|
||||||
|
// determines if there are any new tags
|
||||||
|
final newTags = tags.where((tag) => !allTagsList.contains(tag)).toList();
|
||||||
|
|
||||||
|
for (final tag in newTags) {
|
||||||
|
// insert new tag in the database
|
||||||
|
objectbox.addVisiteTag(0, distribId, tag, langage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save photo tag in the database
|
||||||
|
objectbox.putPhotoTags(widget.photoId, tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Chip extends StatelessWidget {
|
||||||
|
const _Chip({
|
||||||
|
required this.label,
|
||||||
|
required this.onDeleted,
|
||||||
|
required this.index,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String label;
|
||||||
|
final ValueChanged<int> onDeleted;
|
||||||
|
final int index;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Chip(
|
||||||
|
labelPadding: const EdgeInsets.only(left: 8.0),
|
||||||
|
label: Text(label),
|
||||||
|
deleteIcon: const Icon(
|
||||||
|
Icons.close,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
onDeleted: () {
|
||||||
|
onDeleted(index);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,9 @@ import 'package:mobdr/config/constant.dart';
|
||||||
import 'package:mobdr/cubit/language/language_cubit.dart';
|
import 'package:mobdr/cubit/language/language_cubit.dart';
|
||||||
import 'package:mobdr/cubit/language/app_localizations.dart';
|
import 'package:mobdr/cubit/language/app_localizations.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'package:mobdr/service/shared_prefs.dart';
|
import 'package:mobdr/service/shared_prefs.dart';
|
||||||
import 'package:mobdr/config/global_style.dart';
|
import 'package:mobdr/config/global_style.dart';
|
||||||
import 'package:mobdr/model/visite_model.dart';
|
import 'package:mobdr/model/visite_model.dart';
|
||||||
|
|
@ -16,8 +19,6 @@ import 'package:mobdr/ui/home/photo_typology.dart';
|
||||||
import 'package:mobdr/ui/general/product_detail/product_detail.dart';
|
import 'package:mobdr/ui/general/product_detail/product_detail.dart';
|
||||||
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
||||||
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
class TabHomePage extends StatefulWidget {
|
class TabHomePage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
|
@ -40,8 +41,15 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
|
|
||||||
late LanguageCubit _languageCubit;
|
late LanguageCubit _languageCubit;
|
||||||
|
|
||||||
|
bool _isLoading = true;
|
||||||
|
String _errorMessage = '';
|
||||||
|
|
||||||
|
late List<VisiteModel> visiteData = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
_languageCubit = BlocProvider.of<LanguageCubit>(context);
|
_languageCubit = BlocProvider.of<LanguageCubit>(context);
|
||||||
|
|
||||||
_getLocale().then((val) {
|
_getLocale().then((val) {
|
||||||
|
|
@ -50,7 +58,11 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
super.initState();
|
loadData().then((_) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -77,6 +89,13 @@ 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 / 4);
|
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
|
||||||
|
if (_isLoading) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
} else if (visiteData.isEmpty) {
|
||||||
|
return Center(
|
||||||
|
child: Text('Aucune visite trouvée.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
|
@ -165,6 +184,7 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Container(height: 8),
|
||||||
Text(
|
Text(
|
||||||
visiteData.name,
|
visiteData.name,
|
||||||
style: GlobalStyle.productName
|
style: GlobalStyle.productName
|
||||||
|
|
@ -172,39 +192,32 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(top: 5),
|
||||||
|
child: Text(visiteData.date,
|
||||||
|
style: GlobalStyle.productSale),
|
||||||
|
),
|
||||||
|
Container(height: 5),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.only(top: 5),
|
margin: EdgeInsets.only(top: 5),
|
||||||
child: Text(
|
child: Text(
|
||||||
visiteData.photo.toString() + ' Photo(s)',
|
visiteData.photo.toString() + ' Photo(s)',
|
||||||
style: GlobalStyle.productPrice),
|
style: GlobalStyle.productPrice),
|
||||||
),
|
),
|
||||||
|
Container(height: 5),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.only(top: 5),
|
margin: EdgeInsets.only(top: 5),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.location_on,
|
Icon(Icons.store, color: SOFT_GREY, size: 20),
|
||||||
color: SOFT_GREY, size: 12),
|
Text(' ' + visiteData.type_visite,
|
||||||
Text(' ' + visiteData.location,
|
style: GlobalStyle.productName
|
||||||
style: GlobalStyle.productLocation)
|
.copyWith(fontSize: 13),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.only(top: 5),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
_reusableWidget.createRatingBar(
|
|
||||||
rating: visiteData.rating, size: 12),
|
|
||||||
Text('(' + visiteData.review.toString() + ')',
|
|
||||||
style: GlobalStyle.productTotalReview)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.only(top: 5),
|
|
||||||
child: Text(visiteData.date,
|
|
||||||
style: GlobalStyle.productSale),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -282,4 +295,15 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// data initialization on loading.
|
||||||
|
Future<void> loadData() async {
|
||||||
|
try {
|
||||||
|
// visite initialisation
|
||||||
|
visiteData = await VisiteModel.getAllVisites();
|
||||||
|
} catch (e) {
|
||||||
|
// set errorMessage for debug
|
||||||
|
_errorMessage = 'Error loading visites : $e';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
74
pubspec.lock
74
pubspec.lock
|
|
@ -289,14 +289,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.4"
|
version: "2.2.4"
|
||||||
|
debounce_throttle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: debounce_throttle
|
||||||
|
sha256: c95cf47afda975fc507794a52040a16756fb2f31ad3027d4e691c41862ff5692
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: dio
|
name: dio
|
||||||
sha256: "2644a9e0965a7aa3deb09cb8ce4081db4450c178f472818c8cd34216a3070d7b"
|
sha256: "0894a098594263fe1caaba3520e3016d8a855caeb010a882273189cca10f11e9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.2"
|
version: "5.1.1"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -321,14 +329,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.4"
|
version: "6.1.4"
|
||||||
filter_list:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: filter_list
|
|
||||||
sha256: "2d80d6d19beb7847c1176e8bf6fe06d302b23eb7d1bf48c231dd730409ff9b4d"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.2"
|
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -805,6 +805,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
|
pointer_interceptor:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor
|
||||||
|
sha256: "6aa680b30d96dccef496933d00208ad25f07e047f644dc98ce03ec6141633a9a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.3+4"
|
||||||
pointycastle:
|
pointycastle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -873,58 +881,58 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: ee6257848f822b8481691f20c3e6d2bfee2e9eccb2a3d249907fcfb198c55b41
|
sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.18"
|
version: "2.1.0"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: a51a4f9375097f94df1c6e0a49c0374440d31ab026b59d58a7e7660675879db4
|
sha256: "7fa90471a6875d26ad78c7e4a675874b2043874586891128dc5899662c97db46"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.16"
|
version: "2.1.2"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "6b84fdf06b32bb336f972d373cd38b63734f3461ba56ac2ba01b56d052796259"
|
sha256: "0c1c16c56c9708aa9c361541a6f0e5cc6fc12a3232d866a687a7b7db30032b07"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.2.1"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_linux
|
name: shared_preferences_linux
|
||||||
sha256: d7fb71e6e20cd3dfffcc823a28da3539b392e53ed5fc5c2b90b55fdaa8a7e8fa
|
sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.2.0"
|
||||||
shared_preferences_platform_interface:
|
shared_preferences_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_platform_interface
|
name: shared_preferences_platform_interface
|
||||||
sha256: "824bfd02713e37603b2bdade0842e47d56e7db32b1dcdd1cae533fb88e2913fc"
|
sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.2.0"
|
||||||
shared_preferences_web:
|
shared_preferences_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: "6737b757e49ba93de2a233df229d0b6a87728cea1684da828cbc718b65dcf9d7"
|
sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.1.0"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
sha256: bd014168e8484837c39ef21065b78f305810ceabc1d4f90be6e3b392ce81b46d
|
sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.2.0"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -949,6 +957,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
simple_observable:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: simple_observable
|
||||||
|
sha256: b392795c48f8b5f301b4c8f73e15f56e38fe70f42278c649d8325e859a783301
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -1018,6 +1034,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
|
super_tag_editor:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: super_tag_editor
|
||||||
|
sha256: "0888ef22d5a1485baeb628892de449e03af4b6f901ac7f7c9ddd2f44f6199e22"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1179,5 +1203,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.19.0 <3.0.0"
|
dart: ">=2.19.2 <3.0.0"
|
||||||
flutter: ">=3.3.0"
|
flutter: ">=3.3.0"
|
||||||
|
|
|
||||||
12
pubspec.yaml
12
pubspec.yaml
|
|
@ -31,7 +31,8 @@ dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
dio: 5.0.2
|
# https://pub.dev/packages/dio
|
||||||
|
dio: 5.1.1
|
||||||
objectbox: ^2.0.0
|
objectbox: ^2.0.0
|
||||||
objectbox_flutter_libs: any
|
objectbox_flutter_libs: any
|
||||||
pin_code_fields: 7.4.0
|
pin_code_fields: 7.4.0
|
||||||
|
|
@ -55,8 +56,8 @@ dependencies:
|
||||||
permission_handler: 10.2.0
|
permission_handler: 10.2.0
|
||||||
image: ^4.0.15
|
image: ^4.0.15
|
||||||
|
|
||||||
# https://pub.dev/packages/filter_list/install
|
# https://pub.dev/packages/super_tag_editor
|
||||||
filter_list: ^1.0.2
|
super_tag_editor: ^0.1.1
|
||||||
|
|
||||||
flutter_cache_manager: ^3.3.0
|
flutter_cache_manager: ^3.3.0
|
||||||
|
|
||||||
|
|
@ -66,7 +67,10 @@ dependencies:
|
||||||
carousel_slider: 4.2.1
|
carousel_slider: 4.2.1
|
||||||
cached_network_image: 3.2.3
|
cached_network_image: 3.2.3
|
||||||
get_it: ^7.2.0
|
get_it: ^7.2.0
|
||||||
shared_preferences: 2.0.18
|
|
||||||
|
# https://pub.dev/packages/shared_preferences
|
||||||
|
shared_preferences: ^2.1.0
|
||||||
|
|
||||||
timelines: ^0.1.0
|
timelines: ^0.1.0
|
||||||
universal_io: 2.2.0
|
universal_io: 2.2.0
|
||||||
xml: ^6.2.2
|
xml: ^6.2.2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue