feat: add camera plugin

release/mobdr-v0.0.1
Frédérik Benoist 2023-03-28 00:15:08 +02:00
parent a9f140c1a9
commit 235e285020
35 changed files with 2864 additions and 252 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "automatic"
}

View File

@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
compileSdkVersion 33
ndkVersion flutter.ndkVersion
compileOptions {
@ -47,8 +47,8 @@ android {
applicationId "com.example.mobdr"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
minSdkVersion 21
targetSdkVersion 33 // TODO flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

View File

@ -31,4 +31,14 @@
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Permissions options for the `storage` group -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- Permissions options for the `camera` group -->
<uses-permission android:name="android.permission.CAMERA"/>
</manifest>

View File

@ -47,5 +47,8 @@
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>NSPhotoLibraryUsageDescription</key>
<key>NSCameraUsageDescription</key>
<key>NSMicrophoneUsageDescription</key>
</dict>
</plist>

View File

@ -0,0 +1,138 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
class CustomCameraPreview extends StatefulWidget {
final List<File> photoFiles;
final CameraController cameraController;
CustomCameraPreview(
{Key? key, required this.photoFiles, required this.cameraController})
: super(key: key);
@override
_CustomCameraPreviewState createState() => _CustomCameraPreviewState();
}
class _CustomCameraPreviewState extends State<CustomCameraPreview> {
@override
Widget build(BuildContext context) {
return Stack(
alignment: FractionalOffset.center,
children: <Widget>[
Positioned.fill(
child: AspectRatio(
aspectRatio: widget.cameraController.value.aspectRatio,
child: CameraPreview(widget.cameraController)),
),
Positioned(
bottom: 5,
child: FloatingActionButton(
heroTag: "camera",
backgroundColor: Colors.white,
onPressed: () async {
//you can give limit that's user can take how many photo
if (widget.photoFiles.length != 10) {
//take a photo
var videoFile = await widget.cameraController.takePicture();
File file = File(videoFile.path);
//add photo into files list
widget.photoFiles.add(file);
}
},
child: const Icon(
Icons.camera_alt,
color: Colors.black,
),
)),
_confirmButton(),
_rejectButton(),
Positioned(
bottom: 80,
child: SizedBox(
height: 80,
width: MediaQuery.of(context).size.width, // TODO context.width,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 2.0),
decoration: BoxDecoration(
border: Border.all(width: 2.0, color: Colors.white)),
child: index >= widget.photoFiles.length
? Container(color: Colors.white, width: 100)
: Stack(
children: [
Image.file(
widget.photoFiles[index],
fit: BoxFit.cover,
height: 100,
width: 100,
),
Positioned(
top: 2.5,
right: 2.5,
child: Container(
height: 20,
width: 20,
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle),
child: GestureDetector(
onTap: () {
setState(() {
widget.photoFiles.removeAt(index);
});
},
child: const Icon(Icons.close,
size: 12, color: Colors.black),
),
),
),
],
),
);
},
itemCount: 10,
),
)),
],
);
}
Positioned _rejectButton() {
return Positioned(
bottom: 5,
left: 5,
child: FloatingActionButton(
heroTag: "close",
backgroundColor: Colors.black,
onPressed: () {
Navigator.pop(context, false);
},
child: const Icon(
Icons.close,
color: Colors.white,
),
),
);
}
Positioned _confirmButton() {
return Positioned(
bottom: 5,
right: 5,
child: FloatingActionButton(
heroTag: "confirm",
backgroundColor: Colors.black,
onPressed: () {
Navigator.pop(context, true);
},
child: const Icon(
Icons.check,
color: Colors.white,
),
));
}
}

View File

@ -0,0 +1,5 @@
class AppConstants {
static String API_URL = "http://10.0.3.2:8081/";
static const FONT_FAMILY = "Poppins";
}

View File

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
class MyColors {
static const MaterialColor colorPrimary = MaterialColor(
0xFF189fd7,
<int, Color>{
50: Color(0xFF189fd7),
100: Color(0xFF189fd7),
200: Color(0xFF189fd7),
300: Color(0xFF189fd7),
400: Color(0xFF189fd7),
500: Color(0xFF189fd7),
600: Color(0xFF189fd7),
700: Color(0xFF189fd7),
800: Color(0xFF189fd7),
900: Color(0xFF189fd7),
},
);
static const MaterialColor colorPrimarySwitch = MaterialColor(
0xFF25aae1,
<int, Color>{
50: Color(0xFF25aae1),
100: Color(0xFF25aae1),
200: Color(0xFF25aae1),
300: Color(0xFF25aae1),
400: Color(0xFF25aae1),
500: Color(0xFF25aae1),
600: Color(0xFF25aae1),
700: Color(0xFF25aae1),
800: Color(0xFF25aae1),
900: Color(0xFF25aae1),
},
);
}

View File

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
extension ContextExtension on BuildContext {
MediaQueryData get mediaQuery => MediaQuery.of(this);
}
extension MediaQueryExtension on BuildContext {
double get getHeight => mediaQuery.size.height;
double get getWidth => mediaQuery.size.width;
double get lowHeightValue => getHeight * 0.01;
double get mediumHeightValue => getHeight * 0.05;
double get highHeightValue => getHeight * 0.08;
double get lowWidthValue => getWidth * 0.01;
double get mediumWidthValue => getWidth * 0.05;
double get highWidthValue => getWidth * 0.08;
}
extension ThemeExtension on BuildContext {
ThemeData get theme => Theme.of(this);
TextTheme get textTheme => theme.textTheme;
ColorScheme get colors => theme.colorScheme;
}
extension PaddingExtension on BuildContext {
EdgeInsets get paddingHeightLow => EdgeInsets.all(lowHeightValue);
EdgeInsets get paddingHeightMedium => EdgeInsets.all(mediumHeightValue);
EdgeInsets get paddingHeightHigh => EdgeInsets.all(highHeightValue);
EdgeInsets get paddingWidthLow => EdgeInsets.all(lowWidthValue);
EdgeInsets get paddingWidthMedium => EdgeInsets.all(mediumWidthValue);
EdgeInsets get paddingWidthHigh => EdgeInsets.all(highWidthValue);
}
extension MarginExtension on BuildContext {
EdgeInsets get marginHeightLow => EdgeInsets.all(lowHeightValue);
EdgeInsets get marginHeightMedium => EdgeInsets.all(mediumHeightValue);
EdgeInsets get marginHeightHigh => EdgeInsets.all(highHeightValue);
EdgeInsets get marginWidthLow => EdgeInsets.all(lowWidthValue);
EdgeInsets get marginWidthMedium => EdgeInsets.all(mediumWidthValue);
EdgeInsets get marginWidthHigh => EdgeInsets.all(highWidthValue);
}

View File

@ -0,0 +1,7 @@
extension EmailValidator on String {
bool isValidEmail() {
return RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
.hasMatch(this);
}
}

View File

@ -0,0 +1,6 @@
abstract class Routes {
static const INITIAL = '/';
static const LOGIN = '/login';
static const CAMERA = '/camera';
static const LIST = '/list';
}

View File

@ -13,7 +13,7 @@ class Photo {
int id_photo;
int id_visite;
int id_photo_typologie;
String photo;
String image;
DateTime date_photo;
int id_photo_mp4;
int photo_privee;
@ -25,21 +25,28 @@ class Photo {
int uploaded;
Photo(
this.id_photo,
this.id_visite,
this.id_photo_typologie,
this.photo,
this.id_photo_mp4,
this.photo_privee,
this.photo_principale,
this.photo_tag1,
this.photo_tag2,
this.photo_tag3,
this.photo_tag4,
{this.id = 0,
required this.id_visite,
required this.id_photo_typologie,
required this.image,
this.id_photo = 0,
this.id_photo_mp4 = 0,
this.photo_privee = 0,
this.photo_principale = 0,
this.photo_tag1 = '',
this.photo_tag2 = '',
this.photo_tag3 = '',
this.photo_tag4 = '',
DateTime? date_photo,
this.uploaded = 0})
: date_photo = date_photo ?? DateTime.now();
String get dateFormat => DateFormat('dd.MM.yyyy hh:mm:ss').format(date_photo);
/*
Photo.fromJson(Map<String, dynamic> json)
: id_visite = json['id_visite'],
id_photo_typologie = json['id_photo_typologie'],
image = json['image'];
*/
}

View File

@ -0,0 +1,44 @@
import 'package:objectbox/objectbox.dart';
import 'package:mobdr/objectbox.g.dart';
import 'package:xml/xml.dart';
// ignore_for_file: public_member_api_docs
@Entity()
class PhotoTypology {
// specify the id
@Id()
int id = 0;
int id_photo_typologie;
String libelle;
int ordre;
PhotoTypology({
this.id = 0,
required this.id_photo_typologie,
required this.libelle,
required this.ordre,
});
PhotoTypology.fromJson(Map<String, dynamic> json)
: id_photo_typologie = json['id_photo_typologie'],
libelle = getI18nLabel(json['libelle']),
ordre = json['ordre'];
}
String getI18nLabel(String label) {
try {
String translatedText = '';
final document = XmlDocument.parse(label);
translatedText = document.children[0].getElement('fr')!.text;
if (translatedText == '') {
translatedText = document.children[0].getElement('fr')!.text;
}
return translatedText;
} catch (e) {}
return label;
}

View File

@ -1,3 +1,4 @@
import 'package:intl/intl.dart';
import 'package:objectbox/objectbox.dart';
import 'package:mobdr/objectbox.g.dart';
@ -10,35 +11,32 @@ class Visite {
int id = 0;
int id_visite;
DateTime date_visite;
String type_visite;
String title;
bool allDay;
String start;
int id_distrib_visite;
int id_etab;
int abandon;
String end;
Visite(
{this.id = 0,
required this.id_visite,
required this.date_visite,
required this.type_visite,
required this.title,
required this.allDay,
required this.start,
required this.id_distrib_visite,
required this.id_etab,
required this.abandon,
required this.end});
required this.abandon});
Visite.fromJson(Map<String, dynamic> json)
: id_visite = json['id_visite'],
date_visite = DateTime.parse(json['start']),
type_visite = json['type_visite'],
title = json['title'],
allDay = json['allDay'],
start = json['start'],
id_distrib_visite = json['id_distrib_visite'],
id_etab = json['id_etab'],
abandon = json['abandon'],
end = json['end'];
abandon = json['abandon'];
}

View File

@ -18,6 +18,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'objectbox.dart';
import 'package:wakelock/wakelock.dart';
/// Provides access to the ObjectBox Store throughout the app.
late ObjectBox objectbox;
@ -36,6 +37,10 @@ Future<void> main() async {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
/// pour wakelock
WidgetsFlutterBinding.ensureInitialized();
Wakelock.enable();
runApp(MyApp());
});
}

View File

@ -0,0 +1,12 @@
class PhotoModel {
late int id;
late int id_visite;
late int id_photo_typologie;
late String image;
PhotoModel(
{required this.id,
required this.id_visite,
required this.id_photo_typologie,
required this.image});
}

View File

@ -0,0 +1,13 @@
class ProductModel {
late int id;
late String name;
double? price;
late String image;
double? rating;
int? review;
late int sale;
int? stock;
String? location;
ProductModel({required this.id, required this.name, this.price, required this.image, this.rating, this.review, required this.sale, this.stock, this.location});
}

View File

@ -0,0 +1,44 @@
import 'package:mobdr/config/constant.dart';
class VisiteModel {
late int id;
late String name;
late double price;
late String image;
late double rating;
late int review;
late int sale;
late int stock;
late String location;
late int photo;
late String date;
VisiteModel(
{required this.id,
required this.name,
required this.price,
required this.photo,
required this.image,
required this.rating,
required this.review,
required this.sale,
required this.stock,
required this.location,
required this.date});
}
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')
];

View File

@ -1,68 +0,0 @@
import 'package:mobdr/config/constant.dart';
class WishlistModel {
late int id;
late String name;
late double price;
late String image;
late double rating;
late int review;
late int sale;
late int stock;
late String location;
late int photo;
late String date;
WishlistModel(
{required this.id,
required this.name,
required this.price,
required this.photo,
required this.image,
required this.rating,
required this.review,
required this.sale,
required this.stock,
required this.location,
required this.date});
}
List<WishlistModel> wishlistData = [
WishlistModel(
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'),
WishlistModel(
id: 2,
name: 'BARDI Smart PLUG WiFi Wireless Colokan - IoT Smart Home',
price: 11.46,
photo: 2,
image: GLOBAL_URL + '/apps/ecommerce/product/69.jpg',
rating: 5,
review: 1062,
sale: 4797,
stock: 0,
location: 'Brooklyn',
date: 'Dimanche 26/02/2023 15:00'),
WishlistModel(
id: 3,
name: 'ipad Pro 2020 11-inch 128GB Wi-Fi Only - Silver',
price: 866,
photo: 3,
image: GLOBAL_URL + '/apps/ecommerce/product/49.jpg',
rating: 5,
review: 22,
sale: 468,
stock: 25,
location: 'Brooklyn',
date: 'Dimanche 26/02/2023 16:00'),
];

View File

@ -290,6 +290,33 @@ class ApiProvider {
}
}
/// Synchronize "Photos"
Future<String> SyncPhotos() async {
try {
/// get "Photo typologies"
response = await getCrud(
ApiConstants.baseUrl +
ApiConstants.externalEndpoint +
ApiConstants.restEndpoint +
'/mobDR/visite/typologie',
null);
if (response.statusCode == STATUS_OK) {
/// fill box "Photo typologies"
objectbox.addPhotoTypologies(response.data['typologies']);
}
/// all ok
if (response.statusCode == STATUS_OK) {
return 'OK';
} else {
return response.statusMessage ?? 'Unknow error ...';
}
} catch (ex) {
return ex.toString(); // return ex.response!.data;
}
}
Future<String> getExample(apiToken) async {
response =
await getConnect(ApiConstants.baseUrl + '/example/getData', apiToken);

View File

@ -195,7 +195,7 @@
},
{
"id": "7:8290500625256822711",
"lastPropertyId": "10:103801570610300983",
"lastPropertyId": "11:3119168728902810585",
"name": "Visite",
"properties": [
{
@ -224,11 +224,6 @@
"name": "allDay",
"type": 1
},
{
"id": "6:4582947574501853036",
"name": "start",
"type": 9
},
{
"id": "7:3559563062004847001",
"name": "id_distrib_visite",
@ -245,9 +240,9 @@
"type": 6
},
{
"id": "10:103801570610300983",
"name": "end",
"type": 9
"id": "11:3119168728902810585",
"name": "date_visite",
"type": 10
}
],
"relations": []
@ -288,7 +283,7 @@
},
{
"id": "9:6788844671665652158",
"lastPropertyId": "14:4568092734700892012",
"lastPropertyId": "15:1865824860595482227",
"name": "Photo",
"properties": [
{
@ -312,11 +307,6 @@
"name": "id_photo_typologie",
"type": 6
},
{
"id": "5:1940661113633121688",
"name": "photo",
"type": 9
},
{
"id": "6:234947897575384032",
"name": "date_photo",
@ -361,12 +351,46 @@
"id": "14:4568092734700892012",
"name": "uploaded",
"type": 6
},
{
"id": "15:1865824860595482227",
"name": "image",
"type": 9
}
],
"relations": []
},
{
"id": "10:2779194860339140505",
"lastPropertyId": "4:5588276375011055284",
"name": "PhotoTypology",
"properties": [
{
"id": "1:4533312085241813844",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "2:2320922325597284914",
"name": "id_photo_typologie",
"type": 6
},
{
"id": "3:1537297388817386361",
"name": "libelle",
"type": 9
},
{
"id": "4:5588276375011055284",
"name": "ordre",
"type": 6
}
],
"relations": []
}
],
"lastEntityId": "9:6788844671665652158",
"lastEntityId": "10:2779194860339140505",
"lastIndexId": "0:0",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
@ -379,7 +403,10 @@
"retiredPropertyUids": [
402019719780433349,
2876428622751679696,
6435857490868115471
6435857490868115471,
4582947574501853036,
103801570610300983,
1940661113633121688
],
"retiredRelationUids": [],
"version": 1

View File

@ -5,7 +5,12 @@ import 'package:mobdr/db/box_concurrent.dart';
import 'package:mobdr/db/box_visite.dart';
import 'package:mobdr/db/box_visite_tag.dart';
import 'package:mobdr/db/box_photo.dart';
import 'package:mobdr/db/box_photo_typology.dart';
import 'model.dart';
import 'package:mobdr/model/visite_model.dart';
import 'package:mobdr/model/photo_model.dart';
import 'objectbox.g.dart'; // created by `flutter pub run build_runner build`
/// Provides access to the ObjectBox Store throughout the app.
@ -36,6 +41,9 @@ class ObjectBox {
/// A Box of "Photo"
late final Box<Photo> photoBox;
/// A Box of "Photo typology"
late final Box<PhotoTypology> photoTypologyBox;
/// A Box of log.
late final Box<Log> logBox;
@ -47,6 +55,7 @@ class ObjectBox {
visiteBox = Box<Visite>(store);
visiteTagBox = Box<VisiteTag>(store);
photoBox = Box<Photo>(store);
photoTypologyBox = Box<PhotoTypology>(store);
logBox = Box<Log>(store);
// Add some demo data if the box is empty.
@ -57,6 +66,10 @@ class ObjectBox {
userBox.removeAll();
etabBox.removeAll();
concurrentBox.removeAll();
visiteBox.removeAll();
visiteTagBox.removeAll();
photoBox.removeAll();
//photoTypologyBox.removeAll();
// Add some demo data if the box is empty.
if (userBox.isEmpty()) {
@ -227,7 +240,20 @@ class ObjectBox {
/// VISITE ------------------------------------------------------------------
///
// A function that converts a response body list into a List<Concurrent>.
Stream<List<Visite>> getVisites() {
// Query for all visites, sorted by their date.
// https://docs.objectbox.io/queries
final builder =
visiteBox.query().order(Visite_.date_visite, flags: Order.descending);
// Build and watch the query,
// set triggerImmediately to emit the query immediately on listen.
return builder
.watch(triggerImmediately: true)
// Map it to a list of notes to be used by a StreamBuilder.
.map((query) => query.find());
}
// A function that converts a response body list into a List<Visite>.
List<Visite> parseVisites(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed.map<Visite>((json) => Visite.fromJson(json)).toList();
@ -243,6 +269,7 @@ class ObjectBox {
Future<void> addVisite(
int _id_visite,
DateTime _date_visite,
String _type_visite,
String _title,
bool _allDay,
@ -256,14 +283,13 @@ class ObjectBox {
_addVisiteInTx,
Visite(
id_visite: _id_visite,
date_visite: _date_visite,
type_visite: _type_visite,
title: _title,
allDay: _allDay,
start: _start,
id_distrib_visite: _id_distrib_visite,
id_etab: _id_etab,
abandon: _abandon,
end: _end));
abandon: _abandon));
static void _addVisiteInTx(Store store, _Visite) {
store.box<Visite>().put(_Visite);
@ -276,7 +302,7 @@ class ObjectBox {
/// VISITE TAG ---------------------------------------------------------------
///
// A function that converts a response body list into a List<Concurrent>.
// A function that converts a response body list into a List<VisiteTag>.
List<VisiteTag> parseVisiteTags(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed.map<VisiteTag>((json) => VisiteTag.fromJson(json)).toList();
@ -316,33 +342,18 @@ class ObjectBox {
/// PHOTO --------------------------------------------------------------------
///
Future<void> addPhoto(
int id_photo,
int id_visite,
int id_photo_typologie,
String photo,
int id_photo_mp4,
int photo_privee,
int photo_principale,
String photo_tag1,
String photo_tag2,
String photo_tag3,
String photo_tag4) =>
void addPhotos(List<Photo> _listPhotos) {
store.box<Photo>().putMany(_listPhotos);
}
Future<void> addPhoto(int id_visite, int id_photo_typologie, String image) =>
store.runInTransactionAsync(
TxMode.write,
_addPhotoInTx,
Photo(
id_photo,
id_visite,
id_photo_typologie,
photo,
id_photo_mp4,
photo_privee,
photo_principale,
photo_tag1,
photo_tag2,
photo_tag3,
photo_tag4));
id_visite: id_visite,
id_photo_typologie: id_photo_typologie,
image: image));
static void _addPhotoInTx(Store store, _Photo) {
// Perform ObjectBox operations that take longer than a few milliseconds
@ -350,6 +361,16 @@ class ObjectBox {
store.box<Photo>().put(_Photo);
}
List<Photo> getPhotos2() {
// Query for all photos, sorted by their date.
// https://docs.objectbox.io/queries
final query = photoBox
.query()
.order(Photo_.date_photo, flags: Order.descending)
.build();
return query.find();
}
Stream<List<Photo>> getPhotos() {
// Query for all photos, sorted by their date.
// https://docs.objectbox.io/queries
@ -363,6 +384,60 @@ class ObjectBox {
.map((query) => query.find());
}
int getVisitPhotoCount(int _id_visite, int _id_Photo_typologie) {
final builder = photoBox
.query(Photo_.id_visite.equals(_id_visite) &
Photo_.id_photo_typologie.equals(_id_Photo_typologie))
.build();
return builder.count();
}
/// PHOTO TYPOLOGY -----------------------------------------------------------
///
List<PhotoTypology> parsePhotoTypologies(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed
.map<PhotoTypology>((json) => PhotoTypology.fromJson(json))
.toList();
}
Future<void> addPhotoTypologies(List<dynamic> _listPhotoTypologies) =>
store.runInTransactionAsync(TxMode.write, _addPhotoTypologiesInTx,
parsePhotoTypologies(_listPhotoTypologies));
static void _addPhotoTypologiesInTx(Store store, _PhotoTypologies) {
store.box<PhotoTypology>().putMany(_PhotoTypologies);
}
Future<void> addPhotoTypology(
int id_photo_typologie, String libelle, int ordre) =>
store.runInTransactionAsync(
TxMode.write,
_addPhotoTypologyInTx,
PhotoTypology(
id_photo_typologie: id_photo_typologie,
libelle: libelle,
ordre: ordre));
static void _addPhotoTypologyInTx(Store store, _PhotoTypology) {
// Perform ObjectBox operations that take longer than a few milliseconds
// here. To keep it simple, this example just puts a single object.
store.box<PhotoTypology>().put(_PhotoTypology);
}
Stream<List<PhotoTypology>> getPhotoTypologies() {
// Query for all Typologies, sorted by their order.
// https://docs.objectbox.io/queries
final builder = photoTypologyBox.query().order(PhotoTypology_.ordre);
// Build and watch the query,
// set triggerImmediately to emit the query immediately on listen.
return builder
.watch(triggerImmediately: true)
// Map it to a list of notes to be used by a StreamBuilder.
.map((query) => query.find());
}
/// LOG ----------------------------------------------------------------------
///
Future<void> addLog(String type, String module, String libelle, int duree) =>

View File

@ -4,7 +4,7 @@
// With a Dart package, run `dart run build_runner build`.
// See also https://docs.objectbox.io/getting-started#generate-objectbox-code
// ignore_for_file: camel_case_types
// ignore_for_file: camel_case_types, depend_on_referenced_packages
// coverage:ignore-file
import 'dart:typed_data';
@ -18,6 +18,7 @@ import 'db/box_concurrent.dart';
import 'db/box_etab.dart';
import 'db/box_log.dart';
import 'db/box_photo.dart';
import 'db/box_photo_typology.dart';
import 'db/box_user.dart';
import 'db/box_visite.dart';
import 'db/box_visite_tag.dart';
@ -219,7 +220,7 @@ final _entities = <ModelEntity>[
ModelEntity(
id: const IdUid(7, 8290500625256822711),
name: 'Visite',
lastPropertyId: const IdUid(10, 103801570610300983),
lastPropertyId: const IdUid(11, 3119168728902810585),
flags: 0,
properties: <ModelProperty>[
ModelProperty(
@ -247,11 +248,6 @@ final _entities = <ModelEntity>[
name: 'allDay',
type: 1,
flags: 0),
ModelProperty(
id: const IdUid(6, 4582947574501853036),
name: 'start',
type: 9,
flags: 0),
ModelProperty(
id: const IdUid(7, 3559563062004847001),
name: 'id_distrib_visite',
@ -268,9 +264,9 @@ final _entities = <ModelEntity>[
type: 6,
flags: 0),
ModelProperty(
id: const IdUid(10, 103801570610300983),
name: 'end',
type: 9,
id: const IdUid(11, 3119168728902810585),
name: 'date_visite',
type: 10,
flags: 0)
],
relations: <ModelRelation>[],
@ -312,7 +308,7 @@ final _entities = <ModelEntity>[
ModelEntity(
id: const IdUid(9, 6788844671665652158),
name: 'Photo',
lastPropertyId: const IdUid(14, 4568092734700892012),
lastPropertyId: const IdUid(15, 1865824860595482227),
flags: 0,
properties: <ModelProperty>[
ModelProperty(
@ -335,11 +331,6 @@ final _entities = <ModelEntity>[
name: 'id_photo_typologie',
type: 6,
flags: 0),
ModelProperty(
id: const IdUid(5, 1940661113633121688),
name: 'photo',
type: 9,
flags: 0),
ModelProperty(
id: const IdUid(6, 234947897575384032),
name: 'date_photo',
@ -384,6 +375,40 @@ final _entities = <ModelEntity>[
id: const IdUid(14, 4568092734700892012),
name: 'uploaded',
type: 6,
flags: 0),
ModelProperty(
id: const IdUid(15, 1865824860595482227),
name: 'image',
type: 9,
flags: 0)
],
relations: <ModelRelation>[],
backlinks: <ModelBacklink>[]),
ModelEntity(
id: const IdUid(10, 2779194860339140505),
name: 'PhotoTypology',
lastPropertyId: const IdUid(4, 5588276375011055284),
flags: 0,
properties: <ModelProperty>[
ModelProperty(
id: const IdUid(1, 4533312085241813844),
name: 'id',
type: 6,
flags: 1),
ModelProperty(
id: const IdUid(2, 2320922325597284914),
name: 'id_photo_typologie',
type: 6,
flags: 0),
ModelProperty(
id: const IdUid(3, 1537297388817386361),
name: 'libelle',
type: 9,
flags: 0),
ModelProperty(
id: const IdUid(4, 5588276375011055284),
name: 'ordre',
type: 6,
flags: 0)
],
relations: <ModelRelation>[],
@ -410,7 +435,7 @@ Future<Store> openStore(
ModelDefinition getObjectBoxModel() {
final model = ModelInfo(
entities: _entities,
lastEntityId: const IdUid(9, 6788844671665652158),
lastEntityId: const IdUid(10, 2779194860339140505),
lastIndexId: const IdUid(0, 0),
lastRelationId: const IdUid(0, 0),
lastSequenceId: const IdUid(0, 0),
@ -419,7 +444,10 @@ ModelDefinition getObjectBoxModel() {
retiredPropertyUids: const [
402019719780433349,
2876428622751679696,
6435857490868115471
6435857490868115471,
4582947574501853036,
103801570610300983,
1940661113633121688
],
retiredRelationUids: const [],
modelVersion: 5,
@ -643,19 +671,16 @@ ModelDefinition getObjectBoxModel() {
objectToFB: (Visite object, fb.Builder fbb) {
final type_visiteOffset = fbb.writeString(object.type_visite);
final titleOffset = fbb.writeString(object.title);
final startOffset = fbb.writeString(object.start);
final endOffset = fbb.writeString(object.end);
fbb.startTable(11);
fbb.startTable(12);
fbb.addInt64(0, object.id);
fbb.addInt64(1, object.id_visite);
fbb.addOffset(2, type_visiteOffset);
fbb.addOffset(3, titleOffset);
fbb.addBool(4, object.allDay);
fbb.addOffset(5, startOffset);
fbb.addInt64(6, object.id_distrib_visite);
fbb.addInt64(7, object.id_etab);
fbb.addInt64(8, object.abandon);
fbb.addOffset(9, endOffset);
fbb.addInt64(10, object.date_visite.millisecondsSinceEpoch);
fbb.finish(fbb.endTable());
return object.id;
},
@ -667,22 +692,20 @@ ModelDefinition getObjectBoxModel() {
id: const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0),
id_visite:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
date_visite: DateTime.fromMillisecondsSinceEpoch(
const fb.Int64Reader().vTableGet(buffer, rootOffset, 24, 0)),
type_visite: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 8, ''),
title: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 10, ''),
allDay: const fb.BoolReader()
.vTableGet(buffer, rootOffset, 12, false),
start: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 14, ''),
id_distrib_visite:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0),
id_etab:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
abandon:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0),
end: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 22, ''));
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0));
return object;
}),
@ -732,17 +755,16 @@ ModelDefinition getObjectBoxModel() {
object.id = id;
},
objectToFB: (Photo object, fb.Builder fbb) {
final photoOffset = fbb.writeString(object.photo);
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);
fbb.startTable(15);
final imageOffset = fbb.writeString(object.image);
fbb.startTable(16);
fbb.addInt64(0, object.id);
fbb.addInt64(1, object.id_photo);
fbb.addInt64(2, object.id_visite);
fbb.addInt64(3, object.id_photo_typologie);
fbb.addOffset(4, photoOffset);
fbb.addInt64(5, object.date_photo.millisecondsSinceEpoch);
fbb.addInt64(6, object.id_photo_mp4);
fbb.addInt64(7, object.photo_privee);
@ -752,6 +774,7 @@ ModelDefinition getObjectBoxModel() {
fbb.addOffset(11, photo_tag3Offset);
fbb.addOffset(12, photo_tag4Offset);
fbb.addInt64(13, object.uploaded);
fbb.addOffset(14, imageOffset);
fbb.finish(fbb.endTable());
return object.id;
},
@ -760,27 +783,64 @@ ModelDefinition getObjectBoxModel() {
final rootOffset = buffer.derefObject(0);
final object = Photo(
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0),
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0),
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 12, ''),
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0),
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0),
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 22, ''),
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 24, ''),
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 26, ''),
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 28, ''),
id: const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0),
date_photo: DateTime.fromMillisecondsSinceEpoch(
const fb.Int64Reader().vTableGet(buffer, rootOffset, 14, 0)),
uploaded:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 30, 0));
id_visite:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0),
id_photo_typologie:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0),
image: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 32, ''),
id_photo:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
id_photo_mp4:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0),
photo_privee:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0),
photo_principale:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0),
photo_tag1: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 22, ''),
photo_tag2: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 24, ''),
photo_tag3: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 26, ''),
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;
}),
PhotoTypology: EntityDefinition<PhotoTypology>(
model: _entities[8],
toOneRelations: (PhotoTypology object) => [],
toManyRelations: (PhotoTypology object) => {},
getId: (PhotoTypology object) => object.id,
setId: (PhotoTypology object, int id) {
object.id = id;
},
objectToFB: (PhotoTypology object, fb.Builder fbb) {
final libelleOffset = fbb.writeString(object.libelle);
fbb.startTable(5);
fbb.addInt64(0, object.id);
fbb.addInt64(1, object.id_photo_typologie);
fbb.addOffset(2, libelleOffset);
fbb.addInt64(3, object.ordre);
fbb.finish(fbb.endTable());
return object.id;
},
objectFromFB: (Store store, ByteData fbData) {
final buffer = fb.BufferContext(fbData);
final rootOffset = buffer.derefObject(0);
final object = PhotoTypology(
id: const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0),
id_photo_typologie:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
libelle: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 8, ''),
ordre:
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0));
return object;
})
@ -918,23 +978,21 @@ class Visite_ {
static final allDay =
QueryBooleanProperty<Visite>(_entities[5].properties[4]);
/// see [Visite.start]
static final start = QueryStringProperty<Visite>(_entities[5].properties[5]);
/// see [Visite.id_distrib_visite]
static final id_distrib_visite =
QueryIntegerProperty<Visite>(_entities[5].properties[6]);
QueryIntegerProperty<Visite>(_entities[5].properties[5]);
/// see [Visite.id_etab]
static final id_etab =
QueryIntegerProperty<Visite>(_entities[5].properties[7]);
QueryIntegerProperty<Visite>(_entities[5].properties[6]);
/// see [Visite.abandon]
static final abandon =
QueryIntegerProperty<Visite>(_entities[5].properties[8]);
QueryIntegerProperty<Visite>(_entities[5].properties[7]);
/// see [Visite.end]
static final end = QueryStringProperty<Visite>(_entities[5].properties[9]);
/// see [Visite.date_visite]
static final date_visite =
QueryIntegerProperty<Visite>(_entities[5].properties[8]);
}
/// [VisiteTag] entity fields to define ObjectBox queries.
@ -976,42 +1034,61 @@ class Photo_ {
static final id_photo_typologie =
QueryIntegerProperty<Photo>(_entities[7].properties[3]);
/// see [Photo.photo]
static final photo = QueryStringProperty<Photo>(_entities[7].properties[4]);
/// see [Photo.date_photo]
static final date_photo =
QueryIntegerProperty<Photo>(_entities[7].properties[5]);
QueryIntegerProperty<Photo>(_entities[7].properties[4]);
/// see [Photo.id_photo_mp4]
static final id_photo_mp4 =
QueryIntegerProperty<Photo>(_entities[7].properties[6]);
QueryIntegerProperty<Photo>(_entities[7].properties[5]);
/// see [Photo.photo_privee]
static final photo_privee =
QueryIntegerProperty<Photo>(_entities[7].properties[7]);
QueryIntegerProperty<Photo>(_entities[7].properties[6]);
/// see [Photo.photo_principale]
static final photo_principale =
QueryIntegerProperty<Photo>(_entities[7].properties[8]);
QueryIntegerProperty<Photo>(_entities[7].properties[7]);
/// see [Photo.photo_tag1]
static final photo_tag1 =
QueryStringProperty<Photo>(_entities[7].properties[9]);
QueryStringProperty<Photo>(_entities[7].properties[8]);
/// see [Photo.photo_tag2]
static final photo_tag2 =
QueryStringProperty<Photo>(_entities[7].properties[10]);
QueryStringProperty<Photo>(_entities[7].properties[9]);
/// see [Photo.photo_tag3]
static final photo_tag3 =
QueryStringProperty<Photo>(_entities[7].properties[11]);
QueryStringProperty<Photo>(_entities[7].properties[10]);
/// see [Photo.photo_tag4]
static final photo_tag4 =
QueryStringProperty<Photo>(_entities[7].properties[12]);
QueryStringProperty<Photo>(_entities[7].properties[11]);
/// see [Photo.uploaded]
static final uploaded =
QueryIntegerProperty<Photo>(_entities[7].properties[13]);
QueryIntegerProperty<Photo>(_entities[7].properties[12]);
/// see [Photo.image]
static final image = QueryStringProperty<Photo>(_entities[7].properties[13]);
}
/// [PhotoTypology] entity fields to define ObjectBox queries.
class PhotoTypology_ {
/// see [PhotoTypology.id]
static final id =
QueryIntegerProperty<PhotoTypology>(_entities[8].properties[0]);
/// see [PhotoTypology.id_photo_typologie]
static final id_photo_typologie =
QueryIntegerProperty<PhotoTypology>(_entities[8].properties[1]);
/// see [PhotoTypology.libelle]
static final libelle =
QueryStringProperty<PhotoTypology>(_entities[8].properties[2]);
/// see [PhotoTypology.ordre]
static final ordre =
QueryIntegerProperty<PhotoTypology>(_entities[8].properties[3]);
}

View File

@ -0,0 +1,82 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:mobdr/core/components/custom_camera_preview.dart';
class CameraPage extends StatefulWidget {
const CameraPage({Key? key, required this.photoFiles}) : super(key: key);
final List<File> photoFiles;
@override
_CameraPageState createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> {
CameraController? controller;
late List cameras;
late int selectedCameraIdx;
@override
void initState() {
super.initState();
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.isNotEmpty) {
setState(() {
selectedCameraIdx = 0;
});
_initCameraController(cameras[selectedCameraIdx]).then((void v) {});
} else {
print("No camera available");
}
}).catchError((err) {
print('Error: $err.code\nError Message: $err.message');
});
}
@override
void dispose() {
// Dispose the controller when the widget is disposed.
controller?.dispose();
super.dispose();
}
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller!.dispose();
}
controller = CameraController(cameraDescription, ResolutionPreset.high);
controller!.addListener(() {
if (mounted) {
setState(() {});
}
if (controller!.value.hasError) {
print('Camera error ${controller!.value.errorDescription}');
}
});
try {
await controller!.initialize();
} on CameraException catch (e) {
print(e.description);
}
if (mounted) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
if (controller == null || !controller!.value.isInitialized) {
return const Center(
child: CircularProgressIndicator(
color: Colors.red,
));
}
return CustomCameraPreview(
photoFiles: widget.photoFiles,
cameraController: controller!,
);
}
}

485
lib/ui/home/photo_list.dart Normal file
View File

@ -0,0 +1,485 @@
import 'dart:async';
import 'dart:io';
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:mobdr/model/photo_model.dart';
import 'package:mobdr/ui/reusable/cache_image_network.dart';
import 'package:mobdr/ui/reusable/global_widget.dart';
import 'package:mobdr/ui/home/photo_camera.dart';
import 'package:mobdr/objectbox.dart';
import 'package:mobdr/db/box_photo.dart';
class PhotoListPage extends StatefulWidget {
@override
_PhotoListPageState createState() => _PhotoListPageState();
}
class _PhotoListPageState extends State<PhotoListPage> {
final _globalWidget = GlobalWidget();
// initialize photos files list
final List<File> photoFiles = [];
List<PhotoModel> _photoData = [];
Color _color1 = Color(0xff777777);
Color _color2 = Color(0xFF515151);
// _listKey is used for AnimatedList
var _listKey = GlobalKey<AnimatedListState>();
@override
void initState() {
super.initState();
_loadData();
}
@override
void dispose() {
super.dispose();
}
void _loadData() {
for (Photo myPhoto in objectbox.getPhotos2()) {
_photoData.add(PhotoModel(
id: myPhoto.id,
id_visite: myPhoto.id_visite,
id_photo_typologie: myPhoto.id_photo_typologie,
image: myPhoto.image));
}
}
@override
Widget build(BuildContext context) {
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
systemOverlayStyle: SystemUiOverlayStyle.dark,
elevation: 0,
title: Text(
'Catégorie : A trier',
style: TextStyle(fontSize: 18, color: Colors.black),
),
backgroundColor: Colors.white,
actions: [
GestureDetector(
onTap: () {
Fluttertoast.showToast(
msg: 'Click message', toastLength: Toast.LENGTH_SHORT);
},
child: Icon(Icons.email, color: _color1)),
IconButton(
icon: _globalWidget.customNotifIcon(
count: 8,
notifColor: _color1,
notifSize: 24,
labelSize: 14),
//icon: _globalWidget.customNotifIcon2(8, _color1),
onPressed: () {
Fluttertoast.showToast(
msg: 'Click notification',
toastLength: Toast.LENGTH_SHORT);
}),
],
),
body: RefreshIndicator(
onRefresh: refreshData,
child: AnimatedList(
key: _listKey,
initialItemCount: _photoData.length,
physics: AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index, animation) {
return _buildPhotolistCard(
_photoData[index], boxImageSize, animation, index);
},
),
),
floatingActionButton: fabCart(context));
}
Widget _buildPhotolistCard(
PhotoModel photoData, boxImageSize, animation, index) {
return SizeTransition(
sizeFactor: animation,
child: Container(
margin: EdgeInsets.fromLTRB(12, 6, 12, 0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Container(
margin: EdgeInsets.all(8),
child: Column(
children: [
GestureDetector(
onTap: () {
Fluttertoast.showToast(
msg: 'Click ' + photoData.image,
toastLength: Toast.LENGTH_SHORT);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Image.file(
File(photoData.image),
fit: BoxFit.cover,
height: 100,
width: 150,
),
),
SizedBox(
width: 10,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
photoData.id_photo_typologie.toString(),
style: TextStyle(fontSize: 13, color: _color2),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
Container(
margin: EdgeInsets.only(top: 5),
child: Text((index + 1).toString(),
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold)),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Row(
children: [
Icon(Icons.location_on,
color: SOFT_GREY, size: 12),
Text(
' ' +
photoData.id_photo_typologie
.toString(),
style: TextStyle(
fontSize: 11, color: SOFT_GREY))
],
),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Row(
children: [
Text(
'(' +
photoData.id_photo_typologie
.toString() +
')',
style: TextStyle(
fontSize: 11, color: SOFT_GREY))
],
),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Text(
photoData.id_photo_typologie.toString() +
' ' +
'Sale',
style: TextStyle(
fontSize: 11, color: SOFT_GREY)),
),
],
),
)
],
),
),
Container(
margin: EdgeInsets.only(top: 12),
child: Row(
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeleteFavorite(index, boxImageSize);
},
child: Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
width: 1, color: Colors.grey[300]!)),
child: Icon(Icons.delete, color: _color1, size: 20),
),
),
SizedBox(
width: 8,
),
Expanded(
child: (1 == 0) // (productData.stock == 0)
? TextButton(
style: ButtonStyle(
minimumSize:
MaterialStateProperty.all(Size(0, 30)),
backgroundColor:
MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) =>
Colors.grey[300]!,
),
overlayColor: MaterialStateProperty.all(
Colors.transparent),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
)),
),
onPressed: null,
child: Text(
'Out of Stock',
style: TextStyle(
color: Colors.grey[600],
fontWeight: FontWeight.bold,
fontSize: 13),
textAlign: TextAlign.center,
))
: OutlinedButton(
onPressed: () {
Fluttertoast.showToast(
msg:
'Item has been added to Shopping Cart');
},
style: ButtonStyle(
minimumSize:
MaterialStateProperty.all(Size(0, 30)),
overlayColor: MaterialStateProperty.all(
Colors.transparent),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
)),
side: MaterialStateProperty.all(
BorderSide(color: SOFT_BLUE, width: 1.0),
)),
child: Text(
'Copier dans galerie',
style: TextStyle(
color: SOFT_BLUE,
fontWeight: FontWeight.bold,
fontSize: 13),
textAlign: TextAlign.center,
)),
),
SizedBox(
width: 8,
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeleteFavorite(index, boxImageSize);
},
child: Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
width: 1, color: Colors.grey[300]!)),
child: Icon(Icons.rotate_right_rounded,
color: _color1, size: 20),
),
),
SizedBox(
width: 8,
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeleteFavorite(index, boxImageSize);
},
child: Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
width: 1, color: Colors.grey[300]!)),
child: Icon(Icons.rotate_left_rounded,
color: _color1, size: 20),
),
)
],
),
)
],
),
),
),
),
);
}
Widget fabCart(context) {
return FloatingActionButton(
onPressed: () {
Route route = MaterialPageRoute(
builder: (context) => CameraPage(photoFiles: photoFiles));
Navigator.push(context, route).then((val) {
/// if the user has validated photos
if (val == true) {
savePhotos();
} else {
deletePhotos();
}
});
},
child: Stack(children: [
Icon(Icons.add_a_photo, color: BLACK21, size: 42),
Positioned(
right: 0,
bottom: 0,
child: Container(
padding: EdgeInsets.all(1),
decoration: BoxDecoration(
color: PRIMARY_COLOR,
borderRadius: BorderRadius.circular(14),
),
constraints: BoxConstraints(
minWidth: 16,
minHeight: 16,
),
child: Center(
child: Text(
_photoData.length.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
),
)
]),
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0))),
);
}
void savePhotos() {
print("Save PHOTOS ----:" + photoFiles.length.toString());
if (photoFiles.length > 0) {
final List<Photo> _listPhotos = [];
for (var photo in photoFiles) {
_listPhotos
.add(Photo(id_visite: 0, id_photo_typologie: 0, image: photo.path));
}
objectbox.addPhotos(_listPhotos);
/// refresh widget PhotoListPage
refreshData();
}
}
void deletePhotos() {
print("DELETE PHOTO ------------");
// delete files on local storage
photoFiles.forEach((element) {
//deleteFile(File(element.path));
//element.delete();
});
}
void showPopupDeleteFavorite(index, boxImageSize) {
// set up the buttons
Widget cancelButton = TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('No', style: TextStyle(color: SOFT_BLUE)));
Widget continueButton = TextButton(
onPressed: () {
int removeIndex = index;
var removedItem = _photoData.removeAt(removeIndex);
// This builder is just so that the animation has something
// to work with before it disappears from view since the original
// has already been deleted.
AnimatedRemovedItemBuilder builder = (context, animation) {
// A method to build the Card widget.
return _buildPhotolistCard(
removedItem, boxImageSize, animation, removeIndex);
};
_listKey.currentState!.removeItem(removeIndex, builder);
Navigator.pop(context);
Fluttertoast.showToast(
msg: 'Item has been deleted from your favorite',
toastLength: Toast.LENGTH_SHORT);
},
child: Text('Yes', style: TextStyle(color: SOFT_BLUE)));
// set up the AlertDialog
AlertDialog alert = AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
title: Text(
'Delete Favorite',
style: TextStyle(fontSize: 18),
),
content: Text('Are you sure to delete this item from your Favorite ?',
style: TextStyle(fontSize: 13, color: _color1)),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Future<void> deleteFile(File file) async {
try {
if (await file.exists()) {
await file.delete();
}
} catch (e) {
// Error in getting access to the file.
// todo toast
print(e.toString());
}
}
Future refreshData() async {
/// clear all data
/// TODO on pourrait simplement ajouter les nouvelles photos (bien mieux)
_photoData.clear();
photoFiles.clear();
/// reload all photo data from database
_loadData();
/// reinitialiez AnimatedList widget
setState(() => _listKey = GlobalKey());
}
}

369
lib/ui/home/photo_pick.dart Normal file
View File

@ -0,0 +1,369 @@
/*
install plugin in pubspec.yaml
- image_picker => to pick image from storage or camera (https://pub.dev/packages/image_picker)
add this to ios Info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>I need this permission to test upload photo</string>
<key>NSCameraUsageDescription</key>
<string>I need this permission to test upload photo</string>
<key>NSMicrophoneUsageDescription</key>
<string>I need this permission to test upload photo</string>
When using package image_picker: ^0.8.0+4, we should add this permission at AndroidManifest
android/app/src/debug/AndroidManifest.xml | android/app/src/main/AndroidManifest.xml | android/app/src/profile/AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- permission_handler => to handle permission such as storage, camera (https://pub.dev/packages/permission_handler)
From above link, you should add this to the podfile if you are running on iOS:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
flutter_additional_ios_build_settings(target)
# You can enable the permissions needed here. For example to enable camera
# permission, just remove the `#` character in front so it looks like this:
#
# ## dart: PermissionGroup.camera
# 'PERMISSION_CAMERA=1'
#
# Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
# 'PERMISSION_EVENTS=1',
## dart: PermissionGroup.reminders
# 'PERMISSION_REMINDERS=1',
## dart: PermissionGroup.contacts
# 'PERMISSION_CONTACTS=1',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
# 'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.speech
# 'PERMISSION_SPEECH_RECOGNIZER=1',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
# 'PERMISSION_LOCATION=1',
## dart: PermissionGroup.notification
# 'PERMISSION_NOTIFICATIONS=1',
## dart: PermissionGroup.mediaLibrary
# 'PERMISSION_MEDIA_LIBRARY=1',
## dart: PermissionGroup.sensors
# 'PERMISSION_SENSORS=1',
## dart: PermissionGroup.bluetooth
# 'PERMISSION_BLUETOOTH=1',
## dart: PermissionGroup.appTrackingTransparency
# 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_CRITICAL_ALERTS=1'
]
end
end
end
we add some logic function so if the user press back or done with this pages, cache images will be deleted and not makes the storage full
Don't forget to add all images and sound used in this pages at the pubspec.yaml
*** IMPORTANT NOTES FOR IOS ***
Image Picker will crash if you pick image for a second times, this error only exist on iOS Simulator 14 globaly around the world but not error on the real device
If you want to use iOS Simulator, you need to downgrade and using iOS Simulator 13
Follow this step to downgrade :
1. Xcode > Preferences
2. Select the "Components" tab.
3. Download and select Simulator 13 after the download is finish
4. Press "Check and Install Now".
5. After that, use Simulator 13 instead of simulator 14
*/
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:universal_io/io.dart' as IO;
import 'package:mobdr/ui/reusable/global_widget.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_picker_android/image_picker_android.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
class PhotoPickPage extends StatefulWidget {
@override
_PhotoPickPageState createState() => _PhotoPickPageState();
}
class _PhotoPickPageState extends State<PhotoPickPage> {
// initialize global widget
final _globalWidget = GlobalWidget();
Color _color1 = Color(0xFF0181cc);
Color _color2 = Color(0xff777777);
File? _image;
final _picker = ImagePicker();
dynamic _selectedFile;
@override
void initState() {
super.initState();
}
@override
void dispose() {
if (!kIsWeb) {
if (_selectedFile != null && _selectedFile!.existsSync()) {
_selectedFile!.deleteSync();
}
}
_selectedFile = null;
super.dispose();
}
Future requestPermission(Permission permission) async {
final result = await permission.request();
return result;
}
void _askPermissionCamera() {
requestPermission(Permission.camera).then(_onStatusRequestedCamera);
}
void _askPermissionStorage() {
requestPermission(Permission.storage).then(_onStatusRequested);
}
void _askPermissionPhotos() {
requestPermission(Permission.photos).then(_onStatusRequested);
}
void _onStatusRequested(status) {
if (status != PermissionStatus.granted) {
if (IO.Platform.isIOS) {
openAppSettings();
} else {
if (status == PermissionStatus.permanentlyDenied) {
openAppSettings();
}
}
} else {
_getImage(ImageSource.gallery);
}
}
void _onStatusRequestedCamera(status) {
if (status != PermissionStatus.granted) {
if (IO.Platform.isIOS) {
openAppSettings();
} else {
if (status == PermissionStatus.permanentlyDenied) {
openAppSettings();
}
}
} else {
_getImage(ImageSource.camera);
}
}
void _getImage(ImageSource source) async {
final ImagePickerPlatform imagePickerImplementation =
ImagePickerPlatform.instance;
if (imagePickerImplementation is ImagePickerAndroid) {
imagePickerImplementation.useAndroidPhotoPicker = true;
}
final pickedFile = await _picker.pickImage(
source: source, maxWidth: 640, imageQuality: 100);
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
}
});
if (_image != null) {
this.setState(() {
if (!kIsWeb) {
if (_selectedFile != null && _selectedFile!.existsSync()) {
_selectedFile!.deleteSync();
}
}
if (kIsWeb) {
_selectedFile = pickedFile;
} else {
_selectedFile = _image;
}
_image = null;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: _globalWidget.globalAppBar(),
body: Stack(
children: <Widget>[
SingleChildScrollView(
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
_getImageWidget(),
SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
(!kIsWeb)
? GestureDetector(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.camera_alt,
color: _color2,
size: 40,
),
SizedBox(width: 10),
Text('Camera'),
],
),
onTap: () {
_askPermissionCamera();
},
)
: SizedBox.shrink(),
Container(
width: (!kIsWeb) ? 20 : 0,
),
GestureDetector(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.photo,
color: _color2,
size: 40,
),
SizedBox(width: 10),
Text('Gallery'),
],
),
onTap: () {
if (kIsWeb) {
_getImage(ImageSource.gallery);
} else {
if (IO.Platform.isIOS) {
_askPermissionPhotos();
} else {
_askPermissionStorage();
}
}
},
),
],
),
_buttonSave()
],
),
)
],
));
}
Widget _getImageWidget() {
if (_selectedFile != null) {
return (kIsWeb)
? Image.network(
_selectedFile!.path,
width: (kIsWeb) ? 640 : MediaQuery.of(context).size.width - 16,
fit: BoxFit.fill,
)
: Image.file(
_selectedFile!,
width: (kIsWeb) ? 640 : MediaQuery.of(context).size.width - 16,
fit: BoxFit.fill,
);
} else {
return Image.asset(
'assets/images/placeholder.jpg',
width: (kIsWeb) ? 250 : MediaQuery.of(context).size.width - 16,
fit: BoxFit.fill,
);
}
}
Widget _buttonSave() {
if (_selectedFile != null) {
return Container(
margin: EdgeInsets.fromLTRB(0, 50, 0, 0),
child: SizedBox(
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) => _color1,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3.0),
)),
),
onPressed: () {
if (_selectedFile != null) {
if ((!kIsWeb)) {
// if run on android or ios, should check the file exist or not
if (_selectedFile!.existsSync()) {
Fluttertoast.showToast(
msg: 'Click save success',
toastLength: Toast.LENGTH_SHORT);
}
} else {
Fluttertoast.showToast(
msg: 'Click save success',
toastLength: Toast.LENGTH_SHORT);
}
} else {
Fluttertoast.showToast(
backgroundColor: Colors.red,
textColor: Colors.white,
msg: 'File not found',
fontSize: 13,
toastLength: Toast.LENGTH_SHORT);
}
},
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 30, vertical: 5),
child: Text(
'Save',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white),
textAlign: TextAlign.center,
),
)),
),
);
} else {
return Container();
}
}
}

View File

@ -0,0 +1,102 @@
import 'dart:async';
import 'package:mobdr/main.dart';
import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/config/constant.dart';
import 'package:flutter/material.dart';
import 'package:mobdr/db/box_photo_typology.dart';
import 'package:mobdr/ui/home/photo_list.dart';
class PhotoTypologyPage extends StatefulWidget {
@override
_PhotoTypologyPageState createState() => _PhotoTypologyPageState();
}
class _PhotoTypologyPageState extends State<PhotoTypologyPage> {
GestureDetector Function(BuildContext, int) _itemBuilder(
List<PhotoTypology> PhotoTypology) =>
(BuildContext context, int index) => GestureDetector(
onTap: () {
Route route =
MaterialPageRoute(builder: (context) => PhotoListPage());
Navigator.push(context, route).then(onGoBack);
},
///objectbox.noteBox.remove(PhotoTypology[index].id),
child: Row(
children: <Widget>[
Expanded(
child: Container(
decoration: const BoxDecoration(
border:
Border(bottom: BorderSide(color: Colors.black12))),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0, horizontal: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
PhotoTypology[index].libelle +
" " +
objectbox
.getVisitPhotoCount(0,
PhotoTypology[index].id_photo_typologie)
.toString(),
style: const TextStyle(
fontSize: 15.0,
),
// Provide a Key for the integration test
key: Key('list_log_$index'),
),
Icon(Icons.chevron_right, size: 20, color: SOFT_GREY),
],
),
),
),
),
],
),
);
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
FutureOr onGoBack(dynamic value) {
//refreshData();
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(
color: GlobalStyle.appBarIconThemeColor,
),
elevation: GlobalStyle.appBarElevation,
title: Text(
'Visite de ...',
style: GlobalStyle.appBarTitle,
),
backgroundColor: GlobalStyle.appBarBackgroundColor,
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle),
body: Column(children: <Widget>[
Expanded(
child: StreamBuilder<List<PhotoTypology>>(
stream: objectbox.getPhotoTypologies(),
builder: (context, snapshot) => ListView.builder(
shrinkWrap: true,
//padding: const EdgeInsets.symmetric(horizontal: 20.0),
itemCount: snapshot.hasData ? snapshot.data!.length : 0,
itemBuilder: _itemBuilder(snapshot.data ?? []))))
]));
}
}

View File

@ -9,9 +9,10 @@ import 'package:mobdr/cubit/language/app_localizations.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mobdr/service/shared_prefs.dart';
import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/model/wishlist_model.dart';
import 'package:mobdr/model/visite_model.dart';
import 'package:mobdr/ui/general/chat_us.dart';
import 'package:mobdr/ui/general/notification.dart';
import 'package:mobdr/ui/home/photo_typology.dart';
import 'package:mobdr/ui/general/product_detail/product_detail.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
import 'package:mobdr/ui/reusable/cache_image_network.dart';
@ -107,17 +108,17 @@ class _TabHomePageState extends State<TabHomePage>
),
body: AnimatedList(
key: _listKey,
initialItemCount: wishlistData.length,
initialItemCount: visiteData.length,
physics: AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index, animation) {
return _buildWishlistCard(
wishlistData[index], boxImageSize, animation, index);
return _buildVisitelistCard(
visiteData[index], boxImageSize, animation, index);
},
));
}
Widget _buildWishlistCard(
WishlistModel wishlistData, boxImageSize, animation, index) {
Widget _buildVisitelistCard(
VisiteModel visiteData, boxImageSize, animation, index) {
return SizeTransition(
sizeFactor: animation,
child: Container(
@ -138,14 +139,14 @@ class _TabHomePageState extends State<TabHomePage>
context,
MaterialPageRoute(
builder: (context) => ProductDetailPage(
name: wishlistData.name,
image: wishlistData.image,
price: wishlistData.price,
photo: wishlistData.photo,
rating: wishlistData.rating,
review: wishlistData.review,
sale: wishlistData.sale,
date: wishlistData.date)));
name: visiteData.name,
image: visiteData.image,
price: visiteData.price,
photo: visiteData.photo,
rating: visiteData.rating,
review: visiteData.review,
sale: visiteData.sale,
date: visiteData.date)));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
@ -156,7 +157,7 @@ class _TabHomePageState extends State<TabHomePage>
child: buildCacheNetworkImage(
width: boxImageSize,
height: boxImageSize,
url: wishlistData.image)),
url: visiteData.image)),
SizedBox(
width: 10,
),
@ -165,7 +166,7 @@ class _TabHomePageState extends State<TabHomePage>
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
wishlistData.name,
visiteData.name,
style: GlobalStyle.productName
.copyWith(fontSize: 13),
maxLines: 3,
@ -174,7 +175,7 @@ class _TabHomePageState extends State<TabHomePage>
Container(
margin: EdgeInsets.only(top: 5),
child: Text(
wishlistData.photo.toString() + ' Photo(s)',
visiteData.photo.toString() + ' Photo(s)',
style: GlobalStyle.productPrice),
),
Container(
@ -183,7 +184,7 @@ class _TabHomePageState extends State<TabHomePage>
children: [
Icon(Icons.location_on,
color: SOFT_GREY, size: 12),
Text(' ' + wishlistData.location,
Text(' ' + visiteData.location,
style: GlobalStyle.productLocation)
],
),
@ -193,18 +194,15 @@ class _TabHomePageState extends State<TabHomePage>
child: Row(
children: [
_reusableWidget.createRatingBar(
rating: wishlistData.rating, size: 12),
Text(
'(' +
wishlistData.review.toString() +
')',
rating: visiteData.rating, size: 12),
Text('(' + visiteData.review.toString() + ')',
style: GlobalStyle.productTotalReview)
],
),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Text(wishlistData.date,
child: Text(visiteData.date,
style: GlobalStyle.productSale),
),
],
@ -218,7 +216,7 @@ class _TabHomePageState extends State<TabHomePage>
child: Row(
children: [
Expanded(
child: (wishlistData.stock == 0)
child: (visiteData.stock == 0)
? TextButton(
style: ButtonStyle(
minimumSize:
@ -250,15 +248,7 @@ class _TabHomePageState extends State<TabHomePage>
context,
MaterialPageRoute(
builder: (context) =>
ProductDetailPage(
name: wishlistData.name,
image: wishlistData.image,
price: wishlistData.price,
photo: wishlistData.photo,
rating: wishlistData.rating,
review: wishlistData.review,
sale: wishlistData.sale,
date: wishlistData.date)));
PhotoTypologyPage()));
},
style: ButtonStyle(
minimumSize:

View File

@ -0,0 +1,835 @@
/*
This function is used to add beautiful shimmer loading to the pages
(https://pub.dev/packages/shimmer)
*/
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
double _containerHeight = 20;
double _spaceHeight = 10;
Color _shimmerColor = Colors.grey[200]!;
Color _shimmerColorDark = Colors.grey[500]!;
class ShimmerLoading{
Widget buildShimmerContent(){
return ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: 8,
itemBuilder: (BuildContext context, int index) {
return Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(20, 20, 20, 0),
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
child: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 110,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
color: Colors.white,
),
child: Container(
width: 80,
),
),
),
SizedBox(
width: 20,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 5),
padding: EdgeInsets.only(left: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
color: Colors.white,
)),
),
SizedBox(
height: _spaceHeight,
),
Container(
padding: EdgeInsets.only(left: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
color: Colors.white,
)),
),
SizedBox(
height: _spaceHeight,
),
Container(
padding: EdgeInsets.only(left: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
width: 100,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
color: Colors.white,
)),
),
],
),
),
],
),
),
period: Duration(milliseconds: 1000),
),
),
Container(
margin: EdgeInsets.only(top: 20),
color: _shimmerColor,
height: 1),
],
);
},
);
}
Widget buildShimmerImageHorizontal(boxImageSize) {
return ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: 8,
padding: EdgeInsets.symmetric(horizontal: 16),
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.only(left: index == 0 ? 0 : 12),
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
child: Container(
width: boxImageSize,
height: boxImageSize,
color: _shimmerColor,
),
),
),
period: Duration(milliseconds: 1000),
),
);
},
);
}
Widget buildShimmerHorizontalProduct(boxImageSize) {
return ListView.builder(
itemCount: 8,
padding: EdgeInsets.symmetric(horizontal: 12),
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.only(left: index == 0 ? 0 : 8),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Container(
width: boxImageSize,
height: boxImageSize,
child: Column(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
child: Container(
width: boxImageSize,
height: boxImageSize,
color: _shimmerColor,
),
),
Container(
margin: EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
width: 50,
),
SizedBox(
height: _spaceHeight,
),
Row(
children: [
for(int i=1;i<=5;i++) Icon(Icons.star, color: _shimmerColor, size: 12),
],
)
],
),
),
],
),
),
),
),
);
},
);
}
Widget buildShimmerProductDiscount(boxImageSize) {
return ListView.builder(
itemCount: 8,
padding: EdgeInsets.symmetric(horizontal: 12),
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.only(left: index == 0 ? 0 : 8),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Container(
width: boxImageSize,
height: boxImageSize,
child: Column(
children: <Widget>[
Stack(
children: [
Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
child: Container(
width: boxImageSize,
height: boxImageSize,
color: _shimmerColor,
),
),
),
Positioned(
right: 0,
top:10,
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColorDark,
period: Duration(milliseconds: 1000),
child: Container(
decoration: BoxDecoration(
color: _shimmerColorDark,
borderRadius: BorderRadius.only(topLeft: Radius.circular(6), bottomLeft: Radius.circular(6))
),
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Container(
width: 20,
height: 12,
),
),
),
)
],
),
Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Container(
margin: EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
width: 50,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
width: 50,
),
],
),
),
),
],
),
),
),
);
},
);
}
Widget buildShimmerProductDiscount2(boxImageSize) {
return GridView.count(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
primary: false,
childAspectRatio: 4/6.7,
shrinkWrap: true,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
crossAxisCount: 2,
children: List.generate(8, (index) {
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Column(
children: <Widget>[
Stack(
children: [
Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
child: Container(
width: boxImageSize,
height: boxImageSize,
color: _shimmerColor,
),
),
),
Positioned(
right: 0,
top:10,
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColorDark,
period: Duration(milliseconds: 1000),
child: Container(
decoration: BoxDecoration(
color: _shimmerColorDark,
borderRadius: BorderRadius.only(topLeft: Radius.circular(6), bottomLeft: Radius.circular(6))
),
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Container(
width: 20,
height: 12,
),
),
),
)
],
),
Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Container(
margin: EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
],
),
),
),
],
),
),
);
}),
);
}
Widget buildShimmerBannerSlider(bannerWidth, bannerHeight) {
return Column(
children: [
Container(
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
child: Container(
child: Container(
width: bannerWidth,
height: bannerHeight,
color: _shimmerColor,
),
),
period: Duration(milliseconds: 1000),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children : List.generate(5, (index) {
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _shimmerColor,
),
);
})
),
],
);
}
Widget buildShimmerBanner(bannerWidth, bannerHeight) {
return Container(
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
child: Container(
child: Container(
width: bannerWidth,
height: bannerHeight,
color: _shimmerColor,
),
),
period: Duration(milliseconds: 1000),
),
);
}
Widget buildShimmerProduct(boxImageSize) {
return GridView.count(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
primary: false,
childAspectRatio: 5/8,
shrinkWrap: true,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
crossAxisCount: 2,
children: List.generate(8, (index) {
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Column(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
child: Container(
width: boxImageSize,
height: boxImageSize,
color: _shimmerColor,
),
),
Container(
margin: EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
width: 50,
),
SizedBox(
height: _spaceHeight,
),
Row(
children: [
for(int i=1;i<=5;i++) Icon(Icons.star, color: _shimmerColor, size: 12),
],
)
],
),
),
],
),
),
),
);
}),
);
}
Widget buildShimmerTrending(boxImageSize) {
return GridView.count(
padding: EdgeInsets.symmetric(horizontal: 12),
primary: false,
childAspectRatio: 4/1.6,
shrinkWrap: true,
crossAxisSpacing: 2,
mainAxisSpacing: 2,
crossAxisCount: 2,
children: List.generate(4, (index) {
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)),
child: Container(
width: (boxImageSize)*(1.6/4)-12-1,
height: (boxImageSize)*(1.6/4)-12-1,
color: _shimmerColor,
)
),
Expanded(
child: Container(
margin: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
],
),
),
)
],
),
)
),
);
}),
);
}
Widget buildShimmerCategory() {
return GridView.count(
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
primary: false,
childAspectRatio: 1.1,
shrinkWrap: true,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
crossAxisCount: 4,
children: List.generate(8, (index) {
return Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Column(
children: [
Container(
width: 40,
height: 40,
color: _shimmerColor,
),
SizedBox(
height: _spaceHeight,
),
Container(
width: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
]),
);
}),
);
}
Widget buildShimmerCategoryHorizontal() {
return GridView.count(
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
primary: false,
childAspectRatio: 1.07,
shrinkWrap: true,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
crossAxisCount: 2,
scrollDirection: Axis.horizontal,
children: List.generate(16, (index) {
return Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Column(
children: [
Container(
width: 40,
height: 40,
color: _shimmerColor,
),
SizedBox(
height: _spaceHeight,
),
Container(
width: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: 12,
),
]),
);
}),
);
}
Widget buildShimmerList() {
return Container(
child: Shimmer.fromColors(
highlightColor: Colors.white,
baseColor: _shimmerColor,
period: Duration(milliseconds: 1000),
child: Container(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(horizontal: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
),
SizedBox(
height: _spaceHeight,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: _shimmerColor,
),
height: _containerHeight,
),
],
),
),
],
),
),
),
);
}
}

View File

@ -212,17 +212,24 @@ class _TabSyncPageState extends State<TabSyncPage>
///FRED
var apiResponseEtabs = await _apiProvider.SyncEtablissements();
var apiResponseVisites = await _apiProvider.SyncVisites();
var apiResponsePhotos = await _apiProvider.SyncPhotos();
if (apiResponseEtabs == 'OK') {
print("Sync Etabs OK");
print("SyncEtablissements OK");
} else {
print("SyncEtablissements Error:" + apiResponseEtabs);
}
if (apiResponseVisites == 'OK') {
print("Sync Visites OK");
print("SyncVisites OK");
} else {
print("SyncVisites Error:" + apiResponseEtabs);
print("SyncVisites Error:" + apiResponseVisites);
}
if (apiResponsePhotos == 'OK') {
print("SyncPhotos OK");
} else {
print("SyncPhotos Error:" + apiResponsePhotos);
}
///

View File

@ -10,6 +10,7 @@ import package_info_plus
import path_provider_foundation
import shared_preferences_foundation
import sqflite
import wakelock_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
@ -17,4 +18,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin"))
}

View File

@ -18,6 +18,8 @@ PODS:
- sqflite (0.0.2):
- FlutterMacOS
- FMDB (>= 2.7.5)
- wakelock_macos (0.0.1):
- FlutterMacOS
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
@ -26,6 +28,7 @@ DEPENDENCIES:
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
- wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`)
SPEC REPOS:
trunk:
@ -45,6 +48,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos
sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
wakelock_macos:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos
SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
@ -55,6 +60,7 @@ SPEC CHECKSUMS:
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7

View File

@ -137,6 +137,46 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
camera:
dependency: "direct main"
description:
name: camera
sha256: ad1c53c554a2f3e5708f3b01eb738d60b902bb61f7f4ad420c65c715e65a7379
url: "https://pub.dev"
source: hosted
version: "0.10.3+2"
camera_android:
dependency: transitive
description:
name: camera_android
sha256: "772c111c78f31f868b98dbf6dbeda8d6ff77acea773a92ea5705ee2f7949ebfb"
url: "https://pub.dev"
source: hosted
version: "0.10.5"
camera_avfoundation:
dependency: transitive
description:
name: camera_avfoundation
sha256: "7ac8b950672716722af235eed7a7c37896853669800b7da706bb0a9fd41d3737"
url: "https://pub.dev"
source: hosted
version: "0.9.13+1"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
sha256: "00d972adee2e8a282b4d7445e8e694aa1dc0c36b70455b99afa96fbf5e814119"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
camera_web:
dependency: transitive
description:
name: camera_web
sha256: d77965f32479ee6d8f48205dcf10f845d7210595c6c00faa51eab265d1cae993
url: "https://pub.dev"
source: hosted
version: "0.3.1+3"
carousel_slider:
dependency: "direct main"
description:
@ -193,6 +233,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
url: "https://pub.dev"
source: hosted
version: "0.3.3+4"
crypto:
dependency: transitive
description:
@ -303,7 +351,7 @@ packages:
source: hosted
version: "0.7.0"
flutter_cache_manager:
dependency: transitive
dependency: "direct main"
description:
name: flutter_cache_manager
sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3"
@ -323,6 +371,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf
url: "https://pub.dev"
source: hosted
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
@ -405,6 +461,46 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: "64b21d9f0e065f9ab0e4dde458076226c97382cc0c6949144cb874c62bf8e9f8"
url: "https://pub.dev"
source: hosted
version: "0.8.7"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: dfb5b0f28b8786fcc662b7ed42bfb4b82a6cbbd74da1958384b10d40bdf212a7
url: "https://pub.dev"
source: hosted
version: "0.8.6+6"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c"
url: "https://pub.dev"
source: hosted
version: "2.1.12"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: "50e882fe0a06bf0c8f7f5bce78d30975f279213293afc9471dc35f05617c50ff"
url: "https://pub.dev"
source: hosted
version: "0.8.7+1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8"
url: "https://pub.dev"
source: hosted
version: "2.6.3"
intl:
dependency: "direct main"
description:
@ -497,26 +593,26 @@ packages:
dependency: "direct main"
description:
name: objectbox
sha256: c18d41f4e81e5a30fc0e2200e9e8306f5ccc8a9b61fe3746426359690c33dc7b
sha256: a8a3052e430a1e6f91496dc4ffe7c2accab12d24ddfd09412f19541e9f2fe124
url: "https://pub.dev"
source: hosted
version: "1.7.2"
version: "2.0.0"
objectbox_flutter_libs:
dependency: "direct main"
description:
name: objectbox_flutter_libs
sha256: "179a2edfca5eb80abee6e829ebff69872ad20c9f07c2527fe9d098f4bf5a5b83"
sha256: "03801ed3b35d73dacef612880f0a84ed0cce6b3b2efee2c93d47356584e8c942"
url: "https://pub.dev"
source: hosted
version: "1.7.2"
version: "2.0.0"
objectbox_generator:
dependency: "direct dev"
description:
name: objectbox_generator
sha256: "728a9ccf4d6a2ac44a016f6cb9798e4a31ee92b79828526181e0de97a3506c28"
sha256: "078796e874f33520df8ae7690f334fdcd3cd1d3cfe7aa2887e8ecf9182343c68"
url: "https://pub.dev"
source: hosted
version: "1.7.2"
version: "2.0.0"
octo_image:
dependency: transitive
description:
@ -613,6 +709,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.11.1"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8"
url: "https://pub.dev"
source: hosted
version: "10.2.0"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2"
url: "https://pub.dev"
source: hosted
version: "10.2.0"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: "9c370ef6a18b1c4b2f7f35944d644a56aa23576f23abee654cf73968de93f163"
url: "https://pub.dev"
source: hosted
version: "9.0.7"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84"
url: "https://pub.dev"
source: hosted
version: "3.9.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b
url: "https://pub.dev"
source: hosted
version: "0.1.2"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
url: "https://pub.dev"
source: hosted
version: "5.1.0"
pin_code_fields:
dependency: "direct main"
description:
@ -677,6 +821,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.1"
quiver:
dependency: transitive
description:
name: quiver
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
url: "https://pub.dev"
source: hosted
version: "3.2.1"
rxdart:
dependency: transitive
description:
@ -757,6 +909,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.3"
shimmer:
dependency: "direct main"
description:
name: shimmer
sha256: "1f1009b5845a1f88f1c5630212279540486f97409e9fc3f63883e71070d107bf"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
sky_engine:
dependency: transitive
description: flutter
@ -898,6 +1058,46 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
wakelock:
dependency: "direct main"
description:
name: wakelock
sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db"
url: "https://pub.dev"
source: hosted
version: "0.6.2"
wakelock_macos:
dependency: transitive
description:
name: wakelock_macos
sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd"
url: "https://pub.dev"
source: hosted
version: "0.4.0"
wakelock_platform_interface:
dependency: transitive
description:
name: wakelock_platform_interface
sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
wakelock_web:
dependency: transitive
description:
name: wakelock_web
sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5"
url: "https://pub.dev"
source: hosted
version: "0.4.0"
wakelock_windows:
dependency: transitive
description:
name: wakelock_windows
sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
watcher:
dependency: transitive
description:
@ -930,6 +1130,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
xml:
dependency: "direct main"
description:
name: xml
sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
url: "https://pub.dev"
source: hosted
version: "6.2.2"
yaml:
dependency: transitive
description:

View File

@ -32,7 +32,7 @@ dependencies:
sdk: flutter
dio: 5.0.2
objectbox: ^1.7.2
objectbox: ^2.0.0
objectbox_flutter_libs: any
pin_code_fields: 7.4.0
@ -47,6 +47,15 @@ dependencies:
flutter_bloc: 8.1.2
flutter_html: 3.0.0-alpha.6
wakelock: ^0.6.2
shimmer: 2.0.0
image_picker: ^0.8.7
camera: ^0.10.3+2
permission_handler: 10.2.0
flutter_cache_manager: ^3.3.0
#https://pub.dev/packages/intl
intl: 0.17.0
@ -56,6 +65,7 @@ dependencies:
shared_preferences: 2.0.18
timelines: ^0.1.0
universal_io: 2.2.0
xml: ^6.2.2
dev_dependencies:
flutter_test:

View File

@ -7,8 +7,11 @@
#include "generated_plugin_registrant.h"
#include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
ObjectboxFlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ObjectboxFlutterLibsPlugin"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
}

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
objectbox_flutter_libs
permission_handler_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST