global update
parent
d76f037333
commit
210f50bb22
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
|
|
@ -1,4 +1,8 @@
|
||||||
PODS:
|
PODS:
|
||||||
|
- camera_avfoundation (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- device_info_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- fluttertoast (0.0.2):
|
- fluttertoast (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
@ -6,6 +10,8 @@ PODS:
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
|
- image_picker_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
- ObjectBox (1.8.1)
|
- ObjectBox (1.8.1)
|
||||||
- objectbox_flutter_libs (0.0.1):
|
- objectbox_flutter_libs (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
@ -15,6 +21,8 @@ PODS:
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- permission_handler_apple (9.0.4):
|
||||||
|
- Flutter
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
|
@ -22,15 +30,22 @@ PODS:
|
||||||
- Flutter
|
- Flutter
|
||||||
- FMDB (>= 2.7.5)
|
- FMDB (>= 2.7.5)
|
||||||
- Toast (4.0.0)
|
- Toast (4.0.0)
|
||||||
|
- wakelock (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
|
||||||
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
|
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||||
- objectbox_flutter_libs (from `.symlinks/plugins/objectbox_flutter_libs/ios`)
|
- objectbox_flutter_libs (from `.symlinks/plugins/objectbox_flutter_libs/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
||||||
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
|
- wakelock (from `.symlinks/plugins/wakelock/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
|
|
@ -39,32 +54,47 @@ SPEC REPOS:
|
||||||
- Toast
|
- Toast
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
|
camera_avfoundation:
|
||||||
|
:path: ".symlinks/plugins/camera_avfoundation/ios"
|
||||||
|
device_info_plus:
|
||||||
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
fluttertoast:
|
fluttertoast:
|
||||||
:path: ".symlinks/plugins/fluttertoast/ios"
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
|
image_picker_ios:
|
||||||
|
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||||
objectbox_flutter_libs:
|
objectbox_flutter_libs:
|
||||||
:path: ".symlinks/plugins/objectbox_flutter_libs/ios"
|
:path: ".symlinks/plugins/objectbox_flutter_libs/ios"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/ios"
|
:path: ".symlinks/plugins/path_provider_foundation/ios"
|
||||||
|
permission_handler_apple:
|
||||||
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
|
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
|
||||||
sqflite:
|
sqflite:
|
||||||
:path: ".symlinks/plugins/sqflite/ios"
|
:path: ".symlinks/plugins/sqflite/ios"
|
||||||
|
wakelock:
|
||||||
|
:path: ".symlinks/plugins/wakelock/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
|
camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
|
||||||
|
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
|
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
||||||
ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4
|
ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4
|
||||||
objectbox_flutter_libs: 61d74196d924fbc773da5f5757d1e9fab7b3cc78
|
objectbox_flutter_libs: 61d74196d924fbc773da5f5757d1e9fab7b3cc78
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||||
|
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
||||||
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
|
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
|
||||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
|
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
||||||
|
|
||||||
PODFILE CHECKSUM: b634fd49380cdd3837626153fb977533b1916433
|
PODFILE CHECKSUM: b634fd49380cdd3837626153fb977533b1916433
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,10 @@
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Cette application a besoin de votre autorisation pour accéder à votre galerie photo afin que vous puissiez sélectionner des photos pour votre profil.</string>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>Cette application a besoin de votre autorisation pour accéder à votre caméra afin que vous puissiez prendre des photos pour votre profil.</string>
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
<string>Cette application a besoin de votre autorisation pour accéder à votre microphone afin que vous puissiez enregistrer des messages audio pour envoyer à vos amis.</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
import 'package:mobdr/objectbox.g.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import 'package:mobdr/objectbox.g.dart';
|
||||||
|
import 'package:mobdr/service/shared_prefs.dart';
|
||||||
|
|
||||||
// ignore_for_file: public_member_api_docs
|
// ignore_for_file: public_member_api_docs
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
|
|
@ -12,7 +14,6 @@ class Photo {
|
||||||
|
|
||||||
int id_visite;
|
int id_visite;
|
||||||
int id_photo_typologie;
|
int id_photo_typologie;
|
||||||
String image;
|
|
||||||
String image_name;
|
String image_name;
|
||||||
DateTime date_photo;
|
DateTime date_photo;
|
||||||
int id_photo_mp4;
|
int id_photo_mp4;
|
||||||
|
|
@ -25,7 +26,6 @@ class Photo {
|
||||||
{this.id = 0,
|
{this.id = 0,
|
||||||
required this.id_visite,
|
required this.id_visite,
|
||||||
required this.id_photo_typologie,
|
required this.id_photo_typologie,
|
||||||
required this.image,
|
|
||||||
required this.image_name,
|
required this.image_name,
|
||||||
this.id_photo_mp4 = 0,
|
this.id_photo_mp4 = 0,
|
||||||
this.photo_privee = 0,
|
this.photo_privee = 0,
|
||||||
|
|
@ -35,6 +35,15 @@ class Photo {
|
||||||
this.uploaded = 0})
|
this.uploaded = 0})
|
||||||
: date_photo = date_photo ?? DateTime.now();
|
: date_photo = date_photo ?? DateTime.now();
|
||||||
|
|
||||||
|
static String? _photosDir = SharedPrefs().photosDir;
|
||||||
|
|
||||||
|
String getImage() {
|
||||||
|
if (_photosDir == null) {
|
||||||
|
throw Exception('Photos directory not initialized');
|
||||||
|
}
|
||||||
|
return '$_photosDir/$image_name';
|
||||||
|
}
|
||||||
|
|
||||||
String get dateFormat => DateFormat('dd.MM.yyyy hh:mm:ss').format(date_photo);
|
String get dateFormat => DateFormat('dd.MM.yyyy hh:mm:ss').format(date_photo);
|
||||||
|
|
||||||
Photo copyWith({
|
Photo copyWith({
|
||||||
|
|
@ -54,7 +63,6 @@ class Photo {
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
id_visite: id_visite ?? this.id_visite,
|
id_visite: id_visite ?? this.id_visite,
|
||||||
id_photo_typologie: id_photo_typologie ?? this.id_photo_typologie,
|
id_photo_typologie: id_photo_typologie ?? this.id_photo_typologie,
|
||||||
image: image ?? this.image,
|
|
||||||
image_name: image_name ?? this.image_name,
|
image_name: image_name ?? this.image_name,
|
||||||
date_photo: date_photo ?? this.date_photo,
|
date_photo: date_photo ?? this.date_photo,
|
||||||
id_photo_mp4: id_photo_mp4 ?? this.id_photo_mp4,
|
id_photo_mp4: id_photo_mp4 ?? this.id_photo_mp4,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
import 'package:mobdr/objectbox.g.dart';
|
import 'package:mobdr/objectbox.g.dart';
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
|
|
@ -20,6 +19,7 @@ class Visite {
|
||||||
int id_etab;
|
int id_etab;
|
||||||
int abandon;
|
int abandon;
|
||||||
String url_photo_principale;
|
String url_photo_principale;
|
||||||
|
String langage;
|
||||||
|
|
||||||
Visite(
|
Visite(
|
||||||
{this.id = 0,
|
{this.id = 0,
|
||||||
|
|
@ -31,7 +31,8 @@ class Visite {
|
||||||
required this.id_distrib_visite,
|
required this.id_distrib_visite,
|
||||||
required this.id_etab,
|
required this.id_etab,
|
||||||
required this.abandon,
|
required this.abandon,
|
||||||
required this.url_photo_principale});
|
required this.url_photo_principale,
|
||||||
|
required this.langage});
|
||||||
|
|
||||||
Visite.fromJson(Map<String, dynamic> json)
|
Visite.fromJson(Map<String, dynamic> json)
|
||||||
: id_visite = json['id_visite'],
|
: id_visite = json['id_visite'],
|
||||||
|
|
@ -43,5 +44,6 @@ class Visite {
|
||||||
id_etab = json['id_etab'],
|
id_etab = json['id_etab'],
|
||||||
abandon = json['abandon'],
|
abandon = json['abandon'],
|
||||||
url_photo_principale =
|
url_photo_principale =
|
||||||
ApiConstants.baseUrl + json['url_photo_principale'];
|
ApiConstants.baseUrl + json['url_photo_principale'],
|
||||||
|
langage = 'fr';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
211
lib/main.dart
211
lib/main.dart
|
|
@ -1,17 +1,11 @@
|
||||||
// ignore_for_file: prefer_const_constructors
|
// ignore_for_file: prefer_const_constructors
|
||||||
|
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
import 'dart:developer' as developer;
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:mobdr/cubit/language/language_cubit.dart';
|
|
||||||
import 'package:mobdr/cubit/language/app_localizations.dart';
|
|
||||||
import 'package:mobdr/cubit/language/initial_language.dart';
|
|
||||||
|
|
||||||
import 'package:mobdr/service/shared_prefs.dart';
|
|
||||||
|
|
||||||
import 'package:mobdr/ui/splash_screen.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
|
@ -22,9 +16,19 @@ import 'package:path_provider/path_provider.dart';
|
||||||
import 'objectbox.dart';
|
import 'objectbox.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
||||||
|
import 'package:mobdr/config/constant.dart';
|
||||||
|
|
||||||
|
import 'package:mobdr/cubit/language/language_cubit.dart';
|
||||||
|
import 'package:mobdr/cubit/language/app_localizations.dart';
|
||||||
|
import 'package:mobdr/cubit/language/initial_language.dart';
|
||||||
|
import 'package:mobdr/service/shared_prefs.dart';
|
||||||
|
import 'package:mobdr/ui/splash_screen.dart';
|
||||||
|
|
||||||
/// Provides access to the ObjectBox Store throughout the app.
|
/// Provides access to the ObjectBox Store throughout the app.
|
||||||
late ObjectBox objectbox;
|
late ObjectBox objectbox;
|
||||||
|
|
||||||
|
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
// This is required so ObjectBox can get the application directory
|
// This is required so ObjectBox can get the application directory
|
||||||
// to store the database in.
|
// to store the database in.
|
||||||
|
|
@ -62,6 +66,7 @@ class MyApp extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
initDirectories();
|
initDirectories();
|
||||||
|
initPlatformState();
|
||||||
|
|
||||||
// Initialize all bloc provider used on this entire application here
|
// Initialize all bloc provider used on this entire application here
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
|
|
@ -139,5 +144,193 @@ class MyApp extends StatelessWidget {
|
||||||
print(
|
print(
|
||||||
'The "photos" directory has been created in the documents directory.');
|
'The "photos" directory has been created in the documents directory.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save directories into shared Prefs
|
||||||
|
SharedPrefs().documentsDir = documentsDir.path;
|
||||||
|
SharedPrefs().photosDir = photosDir.path;
|
||||||
|
|
||||||
|
// Get a list of all files in the "photos" directory
|
||||||
|
final List<FileSystemEntity> files = await photosDir.list().toList();
|
||||||
|
|
||||||
|
// Print out the names of the files in the directory
|
||||||
|
for (FileSystemEntity file in files) {
|
||||||
|
print('File name: ${file.path.split('/').last}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initPlatformState() async {
|
||||||
|
var deviceData = <String, dynamic>{};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (kIsWeb) {
|
||||||
|
deviceData = _readWebBrowserInfo(await deviceInfoPlugin.webBrowserInfo);
|
||||||
|
} else {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
deviceData =
|
||||||
|
_readAndroidBuildData(await deviceInfoPlugin.androidInfo);
|
||||||
|
} else if (Platform.isIOS) {
|
||||||
|
deviceData = _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
|
||||||
|
} else if (Platform.isLinux) {
|
||||||
|
deviceData = _readLinuxDeviceInfo(await deviceInfoPlugin.linuxInfo);
|
||||||
|
} else if (Platform.isMacOS) {
|
||||||
|
deviceData = _readMacOsDeviceInfo(await deviceInfoPlugin.macOsInfo);
|
||||||
|
} else if (Platform.isWindows) {
|
||||||
|
deviceData =
|
||||||
|
_readWindowsDeviceInfo(await deviceInfoPlugin.windowsInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save if we are on a simulator
|
||||||
|
if (deviceData['isPhysicalDevice'] == false) {
|
||||||
|
SharedPrefs().isSimulator = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
print(deviceData);
|
||||||
|
} on PlatformException {
|
||||||
|
deviceData = <String, dynamic>{
|
||||||
|
'Error:': 'Failed to get platform version.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _readAndroidBuildData(AndroidDeviceInfo build) {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'version.securityPatch': build.version.securityPatch,
|
||||||
|
'version.sdkInt': build.version.sdkInt,
|
||||||
|
'version.release': build.version.release,
|
||||||
|
'version.previewSdkInt': build.version.previewSdkInt,
|
||||||
|
'version.incremental': build.version.incremental,
|
||||||
|
'version.codename': build.version.codename,
|
||||||
|
'version.baseOS': build.version.baseOS,
|
||||||
|
'board': build.board,
|
||||||
|
'bootloader': build.bootloader,
|
||||||
|
'brand': build.brand,
|
||||||
|
'device': build.device,
|
||||||
|
'display': build.display,
|
||||||
|
'fingerprint': build.fingerprint,
|
||||||
|
'hardware': build.hardware,
|
||||||
|
'host': build.host,
|
||||||
|
'id': build.id,
|
||||||
|
'manufacturer': build.manufacturer,
|
||||||
|
'model': build.model,
|
||||||
|
'product': build.product,
|
||||||
|
'supported32BitAbis': build.supported32BitAbis,
|
||||||
|
'supported64BitAbis': build.supported64BitAbis,
|
||||||
|
'supportedAbis': build.supportedAbis,
|
||||||
|
'tags': build.tags,
|
||||||
|
'type': build.type,
|
||||||
|
'isPhysicalDevice': build.isPhysicalDevice,
|
||||||
|
'systemFeatures': build.systemFeatures,
|
||||||
|
'displaySizeInches':
|
||||||
|
((build.displayMetrics.sizeInches * 10).roundToDouble() / 10),
|
||||||
|
'displayWidthPixels': build.displayMetrics.widthPx,
|
||||||
|
'displayWidthInches': build.displayMetrics.widthInches,
|
||||||
|
'displayHeightPixels': build.displayMetrics.heightPx,
|
||||||
|
'displayHeightInches': build.displayMetrics.heightInches,
|
||||||
|
'displayXDpi': build.displayMetrics.xDpi,
|
||||||
|
'displayYDpi': build.displayMetrics.yDpi,
|
||||||
|
'serialNumber': build.serialNumber,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _readIosDeviceInfo(IosDeviceInfo data) {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'name': data.name,
|
||||||
|
'systemName': data.systemName,
|
||||||
|
'systemVersion': data.systemVersion,
|
||||||
|
'model': data.model,
|
||||||
|
'localizedModel': data.localizedModel,
|
||||||
|
'identifierForVendor': data.identifierForVendor,
|
||||||
|
'isPhysicalDevice': data.isPhysicalDevice,
|
||||||
|
'utsname.sysname:': data.utsname.sysname,
|
||||||
|
'utsname.nodename:': data.utsname.nodename,
|
||||||
|
'utsname.release:': data.utsname.release,
|
||||||
|
'utsname.version:': data.utsname.version,
|
||||||
|
'utsname.machine:': data.utsname.machine,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _readLinuxDeviceInfo(LinuxDeviceInfo data) {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'name': data.name,
|
||||||
|
'version': data.version,
|
||||||
|
'id': data.id,
|
||||||
|
'idLike': data.idLike,
|
||||||
|
'versionCodename': data.versionCodename,
|
||||||
|
'versionId': data.versionId,
|
||||||
|
'prettyName': data.prettyName,
|
||||||
|
'buildId': data.buildId,
|
||||||
|
'variant': data.variant,
|
||||||
|
'variantId': data.variantId,
|
||||||
|
'machineId': data.machineId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _readWebBrowserInfo(WebBrowserInfo data) {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'browserName': describeEnum(data.browserName),
|
||||||
|
'appCodeName': data.appCodeName,
|
||||||
|
'appName': data.appName,
|
||||||
|
'appVersion': data.appVersion,
|
||||||
|
'deviceMemory': data.deviceMemory,
|
||||||
|
'language': data.language,
|
||||||
|
'languages': data.languages,
|
||||||
|
'platform': data.platform,
|
||||||
|
'product': data.product,
|
||||||
|
'productSub': data.productSub,
|
||||||
|
'userAgent': data.userAgent,
|
||||||
|
'vendor': data.vendor,
|
||||||
|
'vendorSub': data.vendorSub,
|
||||||
|
'hardwareConcurrency': data.hardwareConcurrency,
|
||||||
|
'maxTouchPoints': data.maxTouchPoints,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _readMacOsDeviceInfo(MacOsDeviceInfo data) {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'computerName': data.computerName,
|
||||||
|
'hostName': data.hostName,
|
||||||
|
'arch': data.arch,
|
||||||
|
'model': data.model,
|
||||||
|
'kernelVersion': data.kernelVersion,
|
||||||
|
'majorVersion': data.majorVersion,
|
||||||
|
'minorVersion': data.minorVersion,
|
||||||
|
'patchVersion': data.patchVersion,
|
||||||
|
'osRelease': data.osRelease,
|
||||||
|
'activeCPUs': data.activeCPUs,
|
||||||
|
'memorySize': data.memorySize,
|
||||||
|
'cpuFrequency': data.cpuFrequency,
|
||||||
|
'systemGUID': data.systemGUID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _readWindowsDeviceInfo(WindowsDeviceInfo data) {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'numberOfCores': data.numberOfCores,
|
||||||
|
'computerName': data.computerName,
|
||||||
|
'systemMemoryInMegabytes': data.systemMemoryInMegabytes,
|
||||||
|
'userName': data.userName,
|
||||||
|
'majorVersion': data.majorVersion,
|
||||||
|
'minorVersion': data.minorVersion,
|
||||||
|
'buildNumber': data.buildNumber,
|
||||||
|
'platformId': data.platformId,
|
||||||
|
'csdVersion': data.csdVersion,
|
||||||
|
'servicePackMajor': data.servicePackMajor,
|
||||||
|
'servicePackMinor': data.servicePackMinor,
|
||||||
|
'suitMask': data.suitMask,
|
||||||
|
'productType': data.productType,
|
||||||
|
'reserved': data.reserved,
|
||||||
|
'buildLab': data.buildLab,
|
||||||
|
'buildLabEx': data.buildLabEx,
|
||||||
|
'digitalProductId': data.digitalProductId,
|
||||||
|
'displayVersion': data.displayVersion,
|
||||||
|
'editionId': data.editionId,
|
||||||
|
'installDate': data.installDate,
|
||||||
|
'productId': data.productId,
|
||||||
|
'productName': data.productName,
|
||||||
|
'registeredOwner': data.registeredOwner,
|
||||||
|
'releaseId': data.releaseId,
|
||||||
|
'deviceId': data.deviceId,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,11 @@ class PhotoModel {
|
||||||
late int id;
|
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_name;
|
late String image_name;
|
||||||
|
|
||||||
PhotoModel(
|
PhotoModel(
|
||||||
{required this.id,
|
{required this.id,
|
||||||
required this.id_visite,
|
required this.id_visite,
|
||||||
required this.id_photo_typologie,
|
required this.id_photo_typologie,
|
||||||
required this.image,
|
|
||||||
required this.image_name});
|
required this.image_name});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,25 @@ import 'package:mobdr/main.dart';
|
||||||
|
|
||||||
class VisiteModel {
|
class VisiteModel {
|
||||||
late int id;
|
late int id;
|
||||||
|
late int id_distrib;
|
||||||
|
late int id_visite;
|
||||||
late String name;
|
late String name;
|
||||||
late int photo;
|
late int photoCount;
|
||||||
late String date;
|
late String date;
|
||||||
late String image;
|
late String image;
|
||||||
late String type_visite;
|
late String type_visite;
|
||||||
late double price;
|
late String langage;
|
||||||
late double rating;
|
|
||||||
late int review;
|
|
||||||
late int sale;
|
|
||||||
late int stock;
|
|
||||||
late String location;
|
|
||||||
|
|
||||||
VisiteModel({
|
VisiteModel(
|
||||||
required this.id,
|
{required this.id,
|
||||||
|
required this.id_distrib,
|
||||||
|
required this.id_visite,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.photo,
|
required this.photoCount,
|
||||||
required this.date,
|
required this.date,
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.type_visite,
|
required this.type_visite,
|
||||||
required this.price,
|
required this.langage});
|
||||||
required this.rating,
|
|
||||||
required this.review,
|
|
||||||
required this.sale,
|
|
||||||
required this.stock,
|
|
||||||
required this.location,
|
|
||||||
});
|
|
||||||
|
|
||||||
static Future<List<VisiteModel>> getAllVisites() async {
|
static Future<List<VisiteModel>> getAllVisites() async {
|
||||||
// Retrieve all visits from the database using the getAllVisites() method
|
// Retrieve all visits from the database using the getAllVisites() method
|
||||||
|
|
@ -36,18 +29,15 @@ class VisiteModel {
|
||||||
// Map each retrieved visit to VisiteModel
|
// Map each retrieved visit to VisiteModel
|
||||||
final visiteModels = visites
|
final visiteModels = visites
|
||||||
.map((visite) => VisiteModel(
|
.map((visite) => VisiteModel(
|
||||||
|
id_distrib: visite.id_distrib_visite,
|
||||||
id: visite.id,
|
id: visite.id,
|
||||||
|
id_visite: visite.id_visite,
|
||||||
name: visite.title,
|
name: visite.title,
|
||||||
photo: 1,
|
photoCount: objectbox.getVisitPhotoCount(visite.id_visite),
|
||||||
date: visite.date_visite.toString(),
|
date: visite.date_visite.toString(),
|
||||||
image: visite.url_photo_principale,
|
image: visite.url_photo_principale,
|
||||||
type_visite: visite.type_visite,
|
type_visite: visite.type_visite,
|
||||||
price: 0,
|
langage: visite.langage))
|
||||||
rating: 0,
|
|
||||||
review: 0,
|
|
||||||
sale: 0,
|
|
||||||
stock: 10,
|
|
||||||
location: ""))
|
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// Return the list of VisiteModel
|
// Return the list of VisiteModel
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "7:8290500625256822711",
|
"id": "7:8290500625256822711",
|
||||||
"lastPropertyId": "13:1900114397693432703",
|
"lastPropertyId": "14:5831680857919010234",
|
||||||
"name": "Visite",
|
"name": "Visite",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
|
|
@ -248,6 +248,11 @@
|
||||||
"id": "13:1900114397693432703",
|
"id": "13:1900114397693432703",
|
||||||
"name": "url_photo_principale",
|
"name": "url_photo_principale",
|
||||||
"type": 9
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "14:5831680857919010234",
|
||||||
|
"name": "langage",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
|
|
@ -332,11 +337,6 @@
|
||||||
"name": "uploaded",
|
"name": "uploaded",
|
||||||
"type": 6
|
"type": 6
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "15:1865824860595482227",
|
|
||||||
"name": "image",
|
|
||||||
"type": 9
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "16:539065583624712715",
|
"id": "16:539065583624712715",
|
||||||
"name": "image_name",
|
"name": "image_name",
|
||||||
|
|
@ -404,7 +404,8 @@
|
||||||
5293139139799032553,
|
5293139139799032553,
|
||||||
2141346538986140281,
|
2141346538986140281,
|
||||||
7877546811840884522,
|
7877546811840884522,
|
||||||
3784190804330297742
|
3784190804330297742,
|
||||||
|
1865824860595482227
|
||||||
],
|
],
|
||||||
"retiredRelationUids": [],
|
"retiredRelationUids": [],
|
||||||
"version": 1
|
"version": 1
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@ import 'package:mobdr/db/box_photo.dart';
|
||||||
import 'package:mobdr/db/box_photo_typology.dart';
|
import 'package:mobdr/db/box_photo_typology.dart';
|
||||||
|
|
||||||
import 'model.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`
|
import 'objectbox.g.dart'; // created by `flutter pub run build_runner build`
|
||||||
|
|
||||||
/// Provides access to the ObjectBox Store throughout the app.
|
/// Provides access to the ObjectBox Store throughout the app.
|
||||||
|
|
@ -66,6 +63,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();
|
||||||
|
|
@ -289,7 +287,8 @@ class ObjectBox {
|
||||||
int _id_etab,
|
int _id_etab,
|
||||||
int _abandon,
|
int _abandon,
|
||||||
String _end,
|
String _end,
|
||||||
String _url_photo_principale) =>
|
String _url_photo_principale,
|
||||||
|
String _langage) =>
|
||||||
store.runInTransactionAsync(
|
store.runInTransactionAsync(
|
||||||
TxMode.write,
|
TxMode.write,
|
||||||
_addVisiteInTx,
|
_addVisiteInTx,
|
||||||
|
|
@ -302,7 +301,8 @@ class ObjectBox {
|
||||||
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));
|
url_photo_principale: _url_photo_principale,
|
||||||
|
langage: _langage));
|
||||||
|
|
||||||
static void _addVisiteInTx(Store store, _Visite) {
|
static void _addVisiteInTx(Store store, _Visite) {
|
||||||
store.box<Visite>().put(_Visite);
|
store.box<Visite>().put(_Visite);
|
||||||
|
|
@ -367,15 +367,6 @@ class ObjectBox {
|
||||||
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 --------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|
@ -385,15 +376,14 @@ class ObjectBox {
|
||||||
return addedPhotos;
|
return addedPhotos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addPhoto(int id_visite, int id_photo_typologie, String image,
|
Future<void> addPhoto(
|
||||||
String image_name) =>
|
int id_visite, int id_photo_typologie, String image_name) =>
|
||||||
store.runInTransactionAsync(
|
store.runInTransactionAsync(
|
||||||
TxMode.write,
|
TxMode.write,
|
||||||
_addPhotoInTx,
|
_addPhotoInTx,
|
||||||
Photo(
|
Photo(
|
||||||
id_visite: id_visite,
|
id_visite: id_visite,
|
||||||
id_photo_typologie: id_photo_typologie,
|
id_photo_typologie: id_photo_typologie,
|
||||||
image: image,
|
|
||||||
image_name: image_name));
|
image_name: image_name));
|
||||||
|
|
||||||
static void _addPhotoInTx(Store store, _Photo) {
|
static void _addPhotoInTx(Store store, _Photo) {
|
||||||
|
|
@ -402,11 +392,13 @@ class ObjectBox {
|
||||||
store.box<Photo>().put(_Photo);
|
store.box<Photo>().put(_Photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Photo> getAllPhotos() {
|
List<Photo> getAllVisitTypologyPhotos(
|
||||||
|
int id_visite, int _id_photo_typologie) {
|
||||||
// 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
|
||||||
.query()
|
.query(Photo_.id_visite.equals(id_visite) &
|
||||||
|
Photo_.id_photo_typologie.equals(_id_photo_typologie))
|
||||||
.order(Photo_.date_photo, flags: Order.descending)
|
.order(Photo_.date_photo, flags: Order.descending)
|
||||||
.build();
|
.build();
|
||||||
return query.find();
|
return query.find();
|
||||||
|
|
@ -446,14 +438,58 @@ class ObjectBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getVisitPhotoCount(int _id_visite, int _id_Photo_typologie) {
|
int getVisitPhotoCount(int _id_visite) {
|
||||||
|
final builder = photoBox.query(Photo_.id_visite.equals(_id_visite)).build();
|
||||||
|
return builder.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getVisitTypologiePhotoCount(int _id_visite, int _id_photo_typologie) {
|
||||||
final builder = photoBox
|
final builder = photoBox
|
||||||
.query(Photo_.id_visite.equals(_id_visite) &
|
.query(Photo_.id_visite.equals(_id_visite) &
|
||||||
Photo_.id_photo_typologie.equals(_id_Photo_typologie))
|
Photo_.id_photo_typologie.equals(_id_photo_typologie))
|
||||||
.build();
|
.build();
|
||||||
return builder.count();
|
return builder.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> putPhotoTypologie(int photoId, int typologieId) async {
|
||||||
|
final photo = photoBox.get(photoId);
|
||||||
|
|
||||||
|
if (photo != null) {
|
||||||
|
final updatedPhoto = photo.copyWith(id_photo_typologie: typologieId);
|
||||||
|
await photoBox.putAsync(updatedPhoto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> putPhotoVisibilities(
|
||||||
|
int photoId, List<String> visibilities) async {
|
||||||
|
final photo = photoBox.get(photoId);
|
||||||
|
|
||||||
|
if (photo != null) {
|
||||||
|
final updatedPhoto = photo.copyWith(
|
||||||
|
photo_principale: visibilities.contains('principal') ? 1 : 0,
|
||||||
|
photo_privee: visibilities.contains('private') ? 1 : 0);
|
||||||
|
await photoBox.putAsync(updatedPhoto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remettre les principal à zero
|
||||||
|
final queryBuilder = box.query(Photo_.visite_id.equals(idVisite) & Photo_.photo_principale.equals(1));
|
||||||
|
final updatedPhotos = queryBuilder.build().find();
|
||||||
|
updatedPhotos.forEach((photo) {
|
||||||
|
photo.photo_principale = 0;
|
||||||
|
});
|
||||||
|
box.putMany(updatedPhotos);
|
||||||
|
*/
|
||||||
|
|
||||||
/// PHOTO TYPOLOGY -----------------------------------------------------------
|
/// PHOTO TYPOLOGY -----------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
@ -496,6 +532,13 @@ class ObjectBox {
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<PhotoTypology> getPhotoTypologiesList() {
|
||||||
|
final query = photoTypologyBox.query().order(PhotoTypology_.ordre).build();
|
||||||
|
final photoTypologies = query.find();
|
||||||
|
|
||||||
|
return photoTypologies.toList();
|
||||||
|
}
|
||||||
|
|
||||||
Stream<List<PhotoTypology>> getPhotoTypologies() {
|
Stream<List<PhotoTypology>> getPhotoTypologies() {
|
||||||
// Query for all Typologies, sorted by their order.
|
// Query for all Typologies, sorted by their order.
|
||||||
// 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(13, 1900114397693432703),
|
lastPropertyId: const IdUid(14, 5831680857919010234),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
|
|
@ -272,6 +272,11 @@ final _entities = <ModelEntity>[
|
||||||
id: const IdUid(13, 1900114397693432703),
|
id: const IdUid(13, 1900114397693432703),
|
||||||
name: 'url_photo_principale',
|
name: 'url_photo_principale',
|
||||||
type: 9,
|
type: 9,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(14, 5831680857919010234),
|
||||||
|
name: 'langage',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
|
|
@ -356,11 +361,6 @@ final _entities = <ModelEntity>[
|
||||||
name: 'uploaded',
|
name: 'uploaded',
|
||||||
type: 6,
|
type: 6,
|
||||||
flags: 0),
|
flags: 0),
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(15, 1865824860595482227),
|
|
||||||
name: 'image',
|
|
||||||
type: 9,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
id: const IdUid(16, 539065583624712715),
|
id: const IdUid(16, 539065583624712715),
|
||||||
name: 'image_name',
|
name: 'image_name',
|
||||||
|
|
@ -443,7 +443,8 @@ ModelDefinition getObjectBoxModel() {
|
||||||
5293139139799032553,
|
5293139139799032553,
|
||||||
2141346538986140281,
|
2141346538986140281,
|
||||||
7877546811840884522,
|
7877546811840884522,
|
||||||
3784190804330297742
|
3784190804330297742,
|
||||||
|
1865824860595482227
|
||||||
],
|
],
|
||||||
retiredRelationUids: const [],
|
retiredRelationUids: const [],
|
||||||
modelVersion: 5,
|
modelVersion: 5,
|
||||||
|
|
@ -669,7 +670,8 @@ ModelDefinition getObjectBoxModel() {
|
||||||
final titleOffset = fbb.writeString(object.title);
|
final titleOffset = fbb.writeString(object.title);
|
||||||
final url_photo_principaleOffset =
|
final url_photo_principaleOffset =
|
||||||
fbb.writeString(object.url_photo_principale);
|
fbb.writeString(object.url_photo_principale);
|
||||||
fbb.startTable(14);
|
final langageOffset = fbb.writeString(object.langage);
|
||||||
|
fbb.startTable(15);
|
||||||
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);
|
||||||
|
|
@ -680,6 +682,7 @@ ModelDefinition getObjectBoxModel() {
|
||||||
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.addOffset(12, url_photo_principaleOffset);
|
||||||
|
fbb.addOffset(13, langageOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
|
|
@ -705,9 +708,10 @@ ModelDefinition getObjectBoxModel() {
|
||||||
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:
|
url_photo_principale: const fb.StringReader(asciiOptimization: true)
|
||||||
const fb.StringReader(asciiOptimization: true)
|
.vTableGet(buffer, rootOffset, 28, ''),
|
||||||
.vTableGet(buffer, rootOffset, 28, ''));
|
langage:
|
||||||
|
const fb.StringReader(asciiOptimization: true).vTableGet(buffer, rootOffset, 30, ''));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
|
|
@ -757,7 +761,6 @@ ModelDefinition getObjectBoxModel() {
|
||||||
object.id = id;
|
object.id = id;
|
||||||
},
|
},
|
||||||
objectToFB: (Photo object, fb.Builder fbb) {
|
objectToFB: (Photo object, fb.Builder fbb) {
|
||||||
final imageOffset = fbb.writeString(object.image);
|
|
||||||
final image_nameOffset = fbb.writeString(object.image_name);
|
final image_nameOffset = fbb.writeString(object.image_name);
|
||||||
final tagsOffset = fbb.writeString(object.tags);
|
final tagsOffset = fbb.writeString(object.tags);
|
||||||
fbb.startTable(18);
|
fbb.startTable(18);
|
||||||
|
|
@ -769,7 +772,6 @@ ModelDefinition getObjectBoxModel() {
|
||||||
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.addInt64(13, object.uploaded);
|
fbb.addInt64(13, object.uploaded);
|
||||||
fbb.addOffset(14, imageOffset);
|
|
||||||
fbb.addOffset(15, image_nameOffset);
|
fbb.addOffset(15, image_nameOffset);
|
||||||
fbb.addOffset(16, tagsOffset);
|
fbb.addOffset(16, tagsOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
|
|
@ -785,8 +787,6 @@ ModelDefinition getObjectBoxModel() {
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0),
|
||||||
id_photo_typologie:
|
id_photo_typologie:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0),
|
||||||
image: const fb.StringReader(asciiOptimization: true)
|
|
||||||
.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_mp4:
|
id_photo_mp4:
|
||||||
|
|
@ -990,6 +990,10 @@ class Visite_ {
|
||||||
/// see [Visite.url_photo_principale]
|
/// see [Visite.url_photo_principale]
|
||||||
static final url_photo_principale =
|
static final url_photo_principale =
|
||||||
QueryStringProperty<Visite>(_entities[5].properties[9]);
|
QueryStringProperty<Visite>(_entities[5].properties[9]);
|
||||||
|
|
||||||
|
/// see [Visite.langage]
|
||||||
|
static final langage =
|
||||||
|
QueryStringProperty<Visite>(_entities[5].properties[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [VisiteTag] entity fields to define ObjectBox queries.
|
/// [VisiteTag] entity fields to define ObjectBox queries.
|
||||||
|
|
@ -1047,15 +1051,12 @@ class Photo_ {
|
||||||
static final uploaded =
|
static final uploaded =
|
||||||
QueryIntegerProperty<Photo>(_entities[7].properties[7]);
|
QueryIntegerProperty<Photo>(_entities[7].properties[7]);
|
||||||
|
|
||||||
/// see [Photo.image]
|
|
||||||
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[9]);
|
QueryStringProperty<Photo>(_entities[7].properties[8]);
|
||||||
|
|
||||||
/// see [Photo.tags]
|
/// see [Photo.tags]
|
||||||
static final tags = QueryStringProperty<Photo>(_entities[7].properties[10]);
|
static final tags = QueryStringProperty<Photo>(_entities[7].properties[9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [PhotoTypology] entity fields to define ObjectBox queries.
|
/// [PhotoTypology] entity fields to define ObjectBox queries.
|
||||||
|
|
|
||||||
|
|
@ -102,4 +102,25 @@ class SharedPrefs {
|
||||||
set id_visite(int value) {
|
set id_visite(int value) {
|
||||||
_sharedPrefs.setInt('key_id_visite', value);
|
_sharedPrefs.setInt('key_id_visite', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get/set isSimulator
|
||||||
|
bool get isSimulator => _sharedPrefs.getBool('key_issimulator') ?? false;
|
||||||
|
|
||||||
|
set isSimulator(bool value) {
|
||||||
|
_sharedPrefs.setBool('key_issimulator', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get/set application's document directory
|
||||||
|
String get documentsDir => _sharedPrefs.getString('documentsDir') ?? "";
|
||||||
|
|
||||||
|
set documentsDir(String value) {
|
||||||
|
_sharedPrefs.setString('documentsDir', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get/set application's photo directory
|
||||||
|
String get photosDir => _sharedPrefs.getString('photosDir') ?? "";
|
||||||
|
|
||||||
|
set photosDir(String value) {
|
||||||
|
_sharedPrefs.setString('photosDir', value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
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 ?? []))))
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,20 +3,20 @@ This is home page
|
||||||
we used AutomaticKeepAliveClientMixin to keep the state when moving from 1 navbar to another navbar, so the page is not refresh overtime
|
we used AutomaticKeepAliveClientMixin to keep the state when moving from 1 navbar to another navbar, so the page is not refresh overtime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
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/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';
|
||||||
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/photo_typology.dart';
|
import 'package:mobdr/ui/home/visit_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/reusable_widget.dart';
|
||||||
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
bool _isLoading = true;
|
bool _isLoading = true;
|
||||||
String _errorMessage = '';
|
String _errorMessage = '';
|
||||||
|
|
||||||
late List<VisiteModel> visiteData = [];
|
late List<VisiteModel> modelData = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -91,7 +91,7 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
|
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
|
||||||
if (_isLoading) {
|
if (_isLoading) {
|
||||||
return Center(child: CircularProgressIndicator());
|
return Center(child: CircularProgressIndicator());
|
||||||
} else if (visiteData.isEmpty) {
|
} else if (modelData.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text('Aucune visite trouvée.'),
|
child: Text('Aucune visite trouvée.'),
|
||||||
);
|
);
|
||||||
|
|
@ -127,11 +127,11 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
),
|
),
|
||||||
body: AnimatedList(
|
body: AnimatedList(
|
||||||
key: _listKey,
|
key: _listKey,
|
||||||
initialItemCount: visiteData.length,
|
initialItemCount: modelData.length,
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: AlwaysScrollableScrollPhysics(),
|
||||||
itemBuilder: (context, index, animation) {
|
itemBuilder: (context, index, animation) {
|
||||||
return _buildVisitelistCard(
|
return _buildVisitelistCard(
|
||||||
visiteData[index], boxImageSize, animation, index);
|
modelData[index], boxImageSize, animation, index);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +142,22 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
sizeFactor: animation,
|
sizeFactor: animation,
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.fromLTRB(12, 6, 12, 0),
|
margin: EdgeInsets.fromLTRB(12, 6, 12, 0),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Route route = MaterialPageRoute(
|
||||||
|
builder: (context) => VisitPhotoTypologyPage(
|
||||||
|
pp_id_distrib: visiteData.id_distrib,
|
||||||
|
pp_langage: visiteData.langage,
|
||||||
|
pp_id_visite: visiteData.id_visite,
|
||||||
|
pp_name: visiteData.name,
|
||||||
|
onRefreshVisit: (int photoCount) {
|
||||||
|
setState(() {
|
||||||
|
modelData[index].photoCount = photoCount;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
));
|
||||||
|
Navigator.push(context, route);
|
||||||
|
},
|
||||||
child: Card(
|
child: Card(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
|
@ -152,22 +168,7 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
margin: EdgeInsets.all(8),
|
margin: EdgeInsets.all(8),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
Row(
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => ProductDetailPage(
|
|
||||||
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,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|
@ -176,7 +177,9 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
child: buildCacheNetworkImage(
|
child: buildCacheNetworkImage(
|
||||||
width: boxImageSize,
|
width: boxImageSize,
|
||||||
height: boxImageSize,
|
height: boxImageSize,
|
||||||
url: visiteData.image)),
|
url: visiteData.image,
|
||||||
|
),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
|
|
@ -187,34 +190,45 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
Container(height: 8),
|
Container(height: 8),
|
||||||
Text(
|
Text(
|
||||||
visiteData.name,
|
visiteData.name,
|
||||||
style: GlobalStyle.productName
|
style: GlobalStyle.productName.copyWith(
|
||||||
.copyWith(fontSize: 13),
|
fontSize: 13,
|
||||||
|
),
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.only(top: 5),
|
margin: EdgeInsets.only(top: 5),
|
||||||
child: Text(visiteData.date,
|
child: Text(
|
||||||
style: GlobalStyle.productSale),
|
visiteData.date,
|
||||||
|
style: GlobalStyle.productSale,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Container(height: 5),
|
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.photoCount} Photo(s)',
|
||||||
style: GlobalStyle.productPrice),
|
style: GlobalStyle.productPrice,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Container(height: 5),
|
Container(height: 5),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.only(top: 5),
|
margin: EdgeInsets.only(top: 5),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.store, color: SOFT_GREY, size: 20),
|
Icon(
|
||||||
Text(' ' + visiteData.type_visite,
|
Icons.store,
|
||||||
style: GlobalStyle.productName
|
color: SOFT_GREY,
|
||||||
.copyWith(fontSize: 13),
|
size: 20,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
' ' + visiteData.type_visite,
|
||||||
|
style: GlobalStyle.productName.copyWith(
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis)
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -223,72 +237,8 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.only(top: 12),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: (visiteData.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: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) =>
|
|
||||||
PhotoTypologyPage()));
|
|
||||||
},
|
|
||||||
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(
|
|
||||||
AppLocalizations.of(context)!
|
|
||||||
.translate('i18n_take_pictures')!,
|
|
||||||
style: TextStyle(
|
|
||||||
color: SOFT_BLUE,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 13),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -296,11 +246,21 @@ class _TabHomePageState extends State<TabHomePage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// data initialization on loading.
|
/// Called when a visit is refreshed with new photo count.
|
||||||
|
///
|
||||||
|
/// [index]: The index of the visit being refreshed.
|
||||||
|
/// [newPhotoCount]: The new photo count for the visit.
|
||||||
|
void onRefreshVisit(int index, int newPhotoCount) {
|
||||||
|
setState(() {
|
||||||
|
modelData[index].photoCount = newPhotoCount;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initializes data when the page loads.
|
||||||
Future<void> loadData() async {
|
Future<void> loadData() async {
|
||||||
try {
|
try {
|
||||||
// visite initialisation
|
// visite model initialisation
|
||||||
visiteData = await VisiteModel.getAllVisites();
|
modelData = await VisiteModel.getAllVisites();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// set errorMessage for debug
|
// set errorMessage for debug
|
||||||
_errorMessage = 'Error loading visites : $e';
|
_errorMessage = 'Error loading visites : $e';
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,19 @@ import 'package:super_tag_editor/widgets/rich_text_widget.dart';
|
||||||
|
|
||||||
class PhotoTagPage extends StatefulWidget {
|
class PhotoTagPage extends StatefulWidget {
|
||||||
// variables corresponding to the data parameters
|
// variables corresponding to the data parameters
|
||||||
final int photoId;
|
final int pp_id_distrib;
|
||||||
final List<String> currentTags;
|
final String pp_langage;
|
||||||
|
final int pp_photoId;
|
||||||
|
final List<String> pp_currentTags;
|
||||||
|
|
||||||
// Requiring data parameters
|
// Requiring data parameters
|
||||||
const PhotoTagPage(
|
const PhotoTagPage({
|
||||||
{Key? key, required this.photoId, required this.currentTags})
|
Key? key,
|
||||||
: super(key: key);
|
required this.pp_id_distrib,
|
||||||
|
required this.pp_langage,
|
||||||
|
required this.pp_photoId,
|
||||||
|
required this.pp_currentTags,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PhotoTagPageState createState() => _PhotoTagPageState();
|
_PhotoTagPageState createState() => _PhotoTagPageState();
|
||||||
|
|
@ -187,8 +193,9 @@ class _PhotoTagPageState extends State<PhotoTagPage> {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
// Save the selected tags to the database //TODO 1,fr ===
|
// Save the selected tags to the database
|
||||||
await saveSelectedTags(_selectedTags, 1, 'fr');
|
await saveSelectedTags(
|
||||||
|
_selectedTags, widget.pp_id_distrib, widget.pp_langage);
|
||||||
|
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context, _selectedTags.map((tag) => tag).toList());
|
context, _selectedTags.map((tag) => tag).toList());
|
||||||
|
|
@ -203,9 +210,9 @@ class _PhotoTagPageState extends State<PhotoTagPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadData() async {
|
Future<void> loadData() async {
|
||||||
// TODO 1,fr
|
allTagsList = await objectbox.getVisiteTagsLabels(
|
||||||
allTagsList = await objectbox.getVisiteTagsLabels(1, 'fr');
|
widget.pp_id_distrib, widget.pp_langage);
|
||||||
_selectedTags = List<String>.from(widget.currentTags);
|
_selectedTags = List<String>.from(widget.pp_currentTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Saves the selected tags for a photo to the ObjectBox database.
|
/// Saves the selected tags for a photo to the ObjectBox database.
|
||||||
|
|
@ -223,10 +230,7 @@ class _PhotoTagPageState extends State<PhotoTagPage> {
|
||||||
/// Nothing.
|
/// Nothing.
|
||||||
Future<void> saveSelectedTags(
|
Future<void> saveSelectedTags(
|
||||||
List<String> tags, int distribId, String langage) async {
|
List<String> tags, int distribId, String langage) async {
|
||||||
if (tags.isEmpty) {
|
if (tags.isNotEmpty) {
|
||||||
return; // exit function without saving tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// determines if there are any new tags
|
// determines if there are any new tags
|
||||||
final newTags = tags.where((tag) => !allTagsList.contains(tag)).toList();
|
final newTags = tags.where((tag) => !allTagsList.contains(tag)).toList();
|
||||||
|
|
||||||
|
|
@ -234,9 +238,10 @@ class _PhotoTagPageState extends State<PhotoTagPage> {
|
||||||
// insert new tag in the database
|
// insert new tag in the database
|
||||||
objectbox.addVisiteTag(0, distribId, tag, langage);
|
objectbox.addVisiteTag(0, distribId, tag, langage);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// save photo tag in the database
|
// save photo tag in the database
|
||||||
objectbox.putPhotoTags(widget.photoId, tags);
|
objectbox.putPhotoTags(widget.pp_photoId, tags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:mobdr/main.dart';
|
||||||
|
import 'package:mobdr/config/global_style.dart';
|
||||||
|
import 'package:mobdr/config/constant.dart';
|
||||||
|
import 'package:mobdr/db/box_photo_typology.dart';
|
||||||
|
import 'package:mobdr/ui/home/visit_photo_typology_list.dart';
|
||||||
|
|
||||||
|
class VisitPhotoTypologyPage extends StatefulWidget {
|
||||||
|
final int pp_id_distrib;
|
||||||
|
final String pp_langage;
|
||||||
|
final int pp_id_visite;
|
||||||
|
final String pp_name;
|
||||||
|
final Function(int) onRefreshVisit;
|
||||||
|
|
||||||
|
VisitPhotoTypologyPage(
|
||||||
|
{Key? key,
|
||||||
|
required this.pp_id_distrib,
|
||||||
|
required this.pp_langage,
|
||||||
|
required this.pp_id_visite,
|
||||||
|
required this.pp_name,
|
||||||
|
required this.onRefreshVisit})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_VisitPhotoTypologyPageState createState() => _VisitPhotoTypologyPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VisitPhotoTypologyPageState extends State<VisitPhotoTypologyPage> {
|
||||||
|
GestureDetector Function(BuildContext, int) _itemBuilder(
|
||||||
|
List<PhotoTypology> PhotoTypology) =>
|
||||||
|
(BuildContext context, int index) => GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Route route = MaterialPageRoute(
|
||||||
|
builder: (context) => VisitPhotoTypologyListPage(
|
||||||
|
pp_id_distrib: widget.pp_id_distrib,
|
||||||
|
pp_langage: widget.pp_langage,
|
||||||
|
pp_id_visite: widget.pp_id_visite,
|
||||||
|
pp_id_typologie:
|
||||||
|
PhotoTypology[index].id_photo_typologie,
|
||||||
|
pp_libelle_typologie: PhotoTypology[index].libelle,
|
||||||
|
));
|
||||||
|
Navigator.push(context, route).then(onGoBack);
|
||||||
|
},
|
||||||
|
|
||||||
|
/// TODO objectbox.noteBox.remove(PhotoTypology[index].id),
|
||||||
|
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(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
_buildBadge(
|
||||||
|
widget.pp_id_visite,
|
||||||
|
PhotoTypology[index].id_photo_typologie,
|
||||||
|
PhotoTypology[index].libelle),
|
||||||
|
Icon(Icons.chevron_right, size: 20, color: SOFT_GREY),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildBadge(int visitId, int photoTypologyId, String libelle) {
|
||||||
|
int photoCount =
|
||||||
|
objectbox.getVisitTypologiePhotoCount(visitId, photoTypologyId);
|
||||||
|
if (photoCount > 0) {
|
||||||
|
return Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
libelle,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 15.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
photoCount.toString(),
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Text(
|
||||||
|
libelle,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 15.0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
FutureOr onGoBack(dynamic value) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> onBackPressed() async {
|
||||||
|
// Navigate back to the visits page and refresh the data
|
||||||
|
int newPhotoCount = objectbox.getVisitPhotoCount(widget.pp_id_visite);
|
||||||
|
widget.onRefreshVisit(newPhotoCount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WillPopScope(
|
||||||
|
onWillPop: () async {
|
||||||
|
return onBackPressed();
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
appBar: AppBar(
|
||||||
|
iconTheme: IconThemeData(
|
||||||
|
color: GlobalStyle.appBarIconThemeColor,
|
||||||
|
),
|
||||||
|
elevation: GlobalStyle.appBarElevation,
|
||||||
|
title: Text(
|
||||||
|
widget.pp_name,
|
||||||
|
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 ?? []))))
|
||||||
|
])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
import 'dart:developer' as developer;
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
|
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
|
import 'package:mobdr/service/shared_prefs.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/ui/home/visite_photo_typology_detail.dart';
|
||||||
import 'package:mobdr/db/box_photo.dart';
|
import 'package:mobdr/db/box_photo.dart';
|
||||||
import 'package:mobdr/ui/home/photo_detail.dart';
|
|
||||||
|
|
||||||
// TODO Il faut supprimer les possibles photos du répertoire cache !
|
// TODO Il faut supprimer les possibles photos du répertoire cache !
|
||||||
|
|
||||||
|
|
@ -26,17 +29,32 @@ extension FileNameExtension on File {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PhotoListPage extends StatefulWidget {
|
class VisitPhotoTypologyListPage extends StatefulWidget {
|
||||||
|
final int pp_id_distrib;
|
||||||
|
final String pp_langage;
|
||||||
|
final int pp_id_visite;
|
||||||
|
final int pp_id_typologie;
|
||||||
|
final String pp_libelle_typologie;
|
||||||
|
|
||||||
|
VisitPhotoTypologyListPage(
|
||||||
|
{required this.pp_id_distrib,
|
||||||
|
required this.pp_langage,
|
||||||
|
required this.pp_id_visite,
|
||||||
|
required this.pp_id_typologie,
|
||||||
|
required this.pp_libelle_typologie});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PhotoListPageState createState() => _PhotoListPageState();
|
_VisitPhotoTypologyListPageState createState() =>
|
||||||
|
_VisitPhotoTypologyListPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PhotoListPageState extends State<PhotoListPage> {
|
class _VisitPhotoTypologyListPageState
|
||||||
|
extends State<VisitPhotoTypologyListPage> {
|
||||||
final _globalWidget = GlobalWidget();
|
final _globalWidget = GlobalWidget();
|
||||||
|
|
||||||
// initialize photos files list
|
// initialize photos files list
|
||||||
final List<File> photoFiles = [];
|
final List<File> _visitPhotoFiles = [];
|
||||||
List<Photo> _photoData = [];
|
List<Photo> _visitPhotoData = [];
|
||||||
|
|
||||||
Color _color1 = Color(0xff777777);
|
Color _color1 = Color(0xff777777);
|
||||||
Color _color2 = Color(0xFF515151);
|
Color _color2 = Color(0xFF515151);
|
||||||
|
|
@ -47,7 +65,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -55,10 +73,6 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadData() {
|
|
||||||
_photoData = objectbox.getAllPhotos();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
|
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
|
||||||
|
|
@ -70,7 +84,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
systemOverlayStyle: SystemUiOverlayStyle.dark,
|
systemOverlayStyle: SystemUiOverlayStyle.dark,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
title: Text(
|
title: Text(
|
||||||
'Catégorie : A trier',
|
widget.pp_libelle_typologie,
|
||||||
style: TextStyle(fontSize: 18, color: Colors.black),
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
|
|
@ -95,16 +109,107 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: AnimatedList(
|
body: Column(children: [
|
||||||
|
Flexible(
|
||||||
|
child: AnimatedList(
|
||||||
key: _listKey,
|
key: _listKey,
|
||||||
initialItemCount: _photoData.length,
|
initialItemCount: _visitPhotoData.length,
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: AlwaysScrollableScrollPhysics(),
|
||||||
itemBuilder: (context, index, animation) {
|
itemBuilder: (context, index, animation) {
|
||||||
return _buildPhotolistCard(
|
return _buildPhotolistCard(
|
||||||
_photoData[index], boxImageSize, animation, index);
|
_visitPhotoData[index], boxImageSize, animation, index);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
floatingActionButton: fabCart(context));
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
offset: Offset(0.0, 1.0), //(x,y)
|
||||||
|
blurRadius: 2.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// TODO functionality to be implemented
|
||||||
|
/*`
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ChatUsPage()));
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
child: ClipOval(
|
||||||
|
child: Container(
|
||||||
|
color: SOFT_BLUE,
|
||||||
|
padding: EdgeInsets.all(9),
|
||||||
|
child:
|
||||||
|
Icon(Icons.chat, color: Colors.white, size: 16)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
// clear photoFiles list before taking photos
|
||||||
|
_visitPhotoFiles.clear();
|
||||||
|
|
||||||
|
// if we are not on a simulator
|
||||||
|
if (SharedPrefs().isSimulator == false) {
|
||||||
|
Route route = MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
CameraPage(photoFiles: _visitPhotoFiles));
|
||||||
|
Navigator.push(context, route).then((val) {
|
||||||
|
// Restore the constraint before navigating away
|
||||||
|
// DO await here to avoid any other screen in
|
||||||
|
// landscape mode
|
||||||
|
SystemChrome.setPreferredOrientations([
|
||||||
|
DeviceOrientation.portraitUp,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// if the user has validated photos
|
||||||
|
if (val == true) {
|
||||||
|
savePhotos();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// simulates the taking of a photo
|
||||||
|
final File imageFile =
|
||||||
|
await copyImageFromAssetsToTemporaryDirectory();
|
||||||
|
_visitPhotoFiles.add(imageFile);
|
||||||
|
savePhotos();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
||||||
|
margin: EdgeInsets.only(right: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(width: 1, color: SOFT_BLUE),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(
|
||||||
|
10) // <--- border radius here
|
||||||
|
)),
|
||||||
|
child: Text('Prendre des photos',
|
||||||
|
style: TextStyle(
|
||||||
|
color: SOFT_BLUE, fontWeight: FontWeight.bold)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPhotolistCard(Photo photoData, boxImageSize, animation, index) {
|
Widget _buildPhotolistCard(Photo photoData, boxImageSize, animation, index) {
|
||||||
|
|
@ -124,24 +229,31 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Route route = MaterialPageRoute(
|
||||||
context,
|
builder: (context) => VisitPhotoTypologyDetailPage(
|
||||||
MaterialPageRoute(
|
pp_id: _visitPhotoData[index].id,
|
||||||
builder: (context) => PhotoDetailPage(
|
pp_id_distrib: widget.pp_id_distrib,
|
||||||
id: _photoData[index].id,
|
pp_langage: widget.pp_langage,
|
||||||
name: 'visiteData.name',
|
pp_image: _visitPhotoData[index].getImage(),
|
||||||
image: _photoData[index].image,
|
pp_id_typologie: widget.pp_id_typologie,
|
||||||
price: 0,
|
));
|
||||||
photo: 1,
|
|
||||||
rating: 0,
|
|
||||||
review: 0,
|
|
||||||
sale: 0,
|
|
||||||
date: '')));
|
|
||||||
|
|
||||||
// todo if qq chose à changé
|
Navigator.push(context, route).then((result) {
|
||||||
// ne raffraichir que le widget en cours ==
|
if (result['change_typologie']) {
|
||||||
|
// the photo must be removed
|
||||||
setState(() {
|
setState(() {
|
||||||
_listKey = GlobalKey();
|
_visitPhotoData.removeAt(index);
|
||||||
|
_listKey = GlobalKey<AnimatedListState>();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_visitPhotoData[index].tags = result['tags'];
|
||||||
|
_visitPhotoData[index].photo_principale =
|
||||||
|
result['photo_principale'];
|
||||||
|
_visitPhotoData[index].photo_privee =
|
||||||
|
result['photo_privee'];
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -150,7 +262,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
child: Image.file(File(photoData.image),
|
child: Image.file(File(photoData.getImage()),
|
||||||
fit: BoxFit.cover, height: 100, width: 150),
|
fit: BoxFit.cover, height: 100, width: 150),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
|
@ -159,55 +271,35 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(top: 5),
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
photoData.id_photo_typologie.toString(),
|
DateFormat('dd/MM/yyyy HH:mm:ss')
|
||||||
|
.format(photoData.date_photo),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11, color: SOFT_GREY))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(height: 8),
|
||||||
|
Text(
|
||||||
|
"Private : ${photoData.photo_privee == 1 ? 'Yes' : 'No'}",
|
||||||
style: TextStyle(fontSize: 13, color: _color2),
|
style: TextStyle(fontSize: 13, color: _color2),
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.only(top: 5),
|
margin: EdgeInsets.only(top: 5),
|
||||||
child: Text((index + 1).toString(),
|
child: Text(
|
||||||
|
'${photoData.tags.isNotEmpty ? (photoData.tags.length > 53 ? '${photoData.tags.substring(0, 50)}...' : photoData.tags) : "notag"}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.bold)),
|
fontWeight: FontWeight.bold)),
|
||||||
),
|
),
|
||||||
Container(
|
Container(height: 8),
|
||||||
margin: EdgeInsets.only(top: 5),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.location_on,
|
|
||||||
color: SOFT_GREY, size: 12),
|
|
||||||
Text(' ' + photoData.image_name,
|
|
||||||
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)),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -279,12 +371,12 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
borderRadius: BorderRadius.circular(5.0),
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
)),
|
)),
|
||||||
side: MaterialStateProperty.all(
|
side: MaterialStateProperty.all(
|
||||||
BorderSide(color: SOFT_BLUE, width: 1.0),
|
BorderSide(color: SOFT_GREY, width: 1.0),
|
||||||
)),
|
)),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Copier dans galerie',
|
'Copier dans galerie',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: SOFT_BLUE,
|
color: SOFT_GREY,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 13),
|
fontSize: 13),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
|
|
@ -297,7 +389,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await rotateAndReplaceImage(
|
await rotateAndReplaceImage(
|
||||||
File(_photoData[index].image), 90);
|
File(_visitPhotoData[index].getImage()), 90);
|
||||||
setState(() {
|
setState(() {
|
||||||
_listKey = GlobalKey();
|
_listKey = GlobalKey();
|
||||||
});
|
});
|
||||||
|
|
@ -322,7 +414,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await rotateAndReplaceImage(
|
await rotateAndReplaceImage(
|
||||||
File(_photoData[index].image), -90);
|
File(_visitPhotoData[index].getImage()), -90);
|
||||||
setState(() {
|
setState(() {
|
||||||
_listKey = GlobalKey();
|
_listKey = GlobalKey();
|
||||||
});
|
});
|
||||||
|
|
@ -351,78 +443,33 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget fabCart(context) {
|
// TODO ƒuture void ?
|
||||||
return FloatingActionButton(
|
void loadData() {
|
||||||
onPressed: () {
|
_visitPhotoData = objectbox.getAllVisitTypologyPhotos(
|
||||||
photoFiles.clear();
|
widget.pp_id_visite, widget.pp_id_typologie);
|
||||||
Route route = MaterialPageRoute(
|
|
||||||
builder: (context) => CameraPage(photoFiles: photoFiles));
|
|
||||||
Navigator.push(context, route).then((val) {
|
|
||||||
// Restore the constraint before navigating away
|
|
||||||
// DO await here to avoid any other screen in
|
|
||||||
// landscape mode
|
|
||||||
SystemChrome.setPreferredOrientations([
|
|
||||||
DeviceOrientation.portraitUp,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// if the user has validated photos
|
|
||||||
if (val == true) {
|
|
||||||
savePhotos();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
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))),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes the image at the specified [imageURL] from the cache of the [NetworkImage] provider.
|
||||||
|
/// Returns a boolean indicating whether the image was successfully evicted.
|
||||||
Future<bool> evictImage(String imageURL) async {
|
Future<bool> evictImage(String imageURL) async {
|
||||||
final NetworkImage provider = NetworkImage(imageURL);
|
final NetworkImage provider = NetworkImage(imageURL);
|
||||||
return await provider.evict();
|
return await provider.evict();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Saves photos to the database and updates the widget with the new photos.
|
||||||
|
///
|
||||||
void savePhotos() async {
|
void savePhotos() async {
|
||||||
if (photoFiles.length > 0) {
|
if (_visitPhotoFiles.length > 0) {
|
||||||
final List<Photo> _listPhotos = [];
|
final List<Photo> _listPhotos = [];
|
||||||
|
|
||||||
for (var myTmpPhoto in photoFiles) {
|
for (var myTmpPhoto in _visitPhotoFiles) {
|
||||||
/// move jpg file to photo directory
|
/// move jpg file to photo directory
|
||||||
final myPhoto = await moveFileFromTempToPhotosDir(myTmpPhoto);
|
final myPhoto = await moveFileFromTempToPhotosDir(myTmpPhoto);
|
||||||
|
|
||||||
/// to insert into database
|
/// to insert into database
|
||||||
_listPhotos.add(Photo(
|
_listPhotos.add(Photo(
|
||||||
id_visite: 0,
|
id_visite: widget.pp_id_visite,
|
||||||
id_photo_typologie: 0,
|
id_photo_typologie: widget.pp_id_typologie,
|
||||||
image: myPhoto.path,
|
|
||||||
image_name: myPhoto.path.split('/').last));
|
image_name: myPhoto.path.split('/').last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -430,7 +477,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
final addedPhotos = await objectbox.addPhotos(_listPhotos);
|
final addedPhotos = await objectbox.addPhotos(_listPhotos);
|
||||||
|
|
||||||
/// insert photo(s) in widget at the beginning (0)
|
/// insert photo(s) in widget at the beginning (0)
|
||||||
_photoData.insertAll(0, addedPhotos);
|
_visitPhotoData.insertAll(0, addedPhotos);
|
||||||
|
|
||||||
/// refresh widget
|
/// refresh widget
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -439,6 +486,11 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deletes the given file if it exists.
|
||||||
|
///
|
||||||
|
/// Returns nothing.
|
||||||
|
///
|
||||||
|
/// Throws an error if there was an issue deleting the file.
|
||||||
Future<void> deleteFile(File file) async {
|
Future<void> deleteFile(File file) async {
|
||||||
try {
|
try {
|
||||||
if (await file.exists()) {
|
if (await file.exists()) {
|
||||||
|
|
@ -451,6 +503,13 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shows an alert dialog to confirm the deletion of a photo from the visit and
|
||||||
|
/// removes it from the list of photos. Also deletes the photo file from the
|
||||||
|
/// database and local storage.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// - index : index of the photo in the list to be deleted.
|
||||||
|
/// - boxImageSize : size of the image to be displayed in the list.
|
||||||
void showPopupDeletePhoto(index, boxImageSize) {
|
void showPopupDeletePhoto(index, boxImageSize) {
|
||||||
// set up the buttons
|
// set up the buttons
|
||||||
Widget cancelButton = TextButton(
|
Widget cancelButton = TextButton(
|
||||||
|
|
@ -461,13 +520,13 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
Widget continueButton = TextButton(
|
Widget continueButton = TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
int removeIndex = index;
|
int removeIndex = index;
|
||||||
var removedItem = _photoData.removeAt(removeIndex);
|
var removedItem = _visitPhotoData.removeAt(removeIndex);
|
||||||
|
|
||||||
// delete file on database
|
// delete file on database
|
||||||
objectbox.delPhoto(removedItem.image_name);
|
objectbox.delPhoto(removedItem.image_name);
|
||||||
|
|
||||||
// delete file on local storage
|
// delete file on local storage
|
||||||
deleteFile(new File(removedItem.image));
|
deleteFile(new File(removedItem.getImage()));
|
||||||
|
|
||||||
// This builder is just so that the animation has something
|
// This builder is just so that the animation has something
|
||||||
// to work with before it disappears from view since the original
|
// to work with before it disappears from view since the original
|
||||||
|
|
@ -512,13 +571,18 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Moves a temporary file to the photos directory in the app's document directory.
|
||||||
|
///
|
||||||
|
/// Returns a `File` object for the new file in the photos directory.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// * `tempFile`: The temporary `File` object to move to the photos directory.
|
||||||
|
///
|
||||||
|
/// Throws a `FileSystemException` if there is an error renaming the file.
|
||||||
Future<File> moveFileFromTempToPhotosDir(File tempFile) async {
|
Future<File> moveFileFromTempToPhotosDir(File tempFile) async {
|
||||||
// Get the application's document directory
|
|
||||||
final Directory documentsDir = await getApplicationDocumentsDirectory();
|
|
||||||
|
|
||||||
// Set the new file path with the original file name
|
// Set the new file path with the original file name
|
||||||
final String newPath =
|
final String newPath =
|
||||||
'${documentsDir.path}/photos/${tempFile.path.split('/').last}';
|
'${SharedPrefs().photosDir}/${tempFile.path.split('/').last}';
|
||||||
|
|
||||||
// Rename the file to move it to the documents directory
|
// Rename the file to move it to the documents directory
|
||||||
await tempFile.rename(newPath);
|
await tempFile.rename(newPath);
|
||||||
|
|
@ -527,6 +591,13 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
return File(newPath);
|
return File(newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rotates the image file clockwise by the specified angle (in degrees) and overwrites the original file with the rotated image.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// - `imageFile`: The image file to rotate and replace.
|
||||||
|
/// - `angle`: The angle (in degrees) by which to rotate the image. Valid values are 90, 180, and 270.
|
||||||
|
///
|
||||||
|
/// Throws an exception if there is an error in the rotation process.
|
||||||
Future<void> rotateAndReplaceImage(File imageFile, int angle) async {
|
Future<void> rotateAndReplaceImage(File imageFile, int angle) async {
|
||||||
// Read the image file into a Uint8List
|
// Read the image file into a Uint8List
|
||||||
Uint8List bytes = await imageFile.readAsBytes();
|
Uint8List bytes = await imageFile.readAsBytes();
|
||||||
|
|
@ -546,4 +617,19 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
// remove the flutter cache image
|
// remove the flutter cache image
|
||||||
FileImage(imageFile).evict();
|
FileImage(imageFile).evict();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copies the 'simulator.jpg' image file from the app's assets to a randomly named file in the app's temporary directory and returns the File object.
|
||||||
|
/// The temporary file name will start with 'sim_'.
|
||||||
|
Future<File> copyImageFromAssetsToTemporaryDirectory() async {
|
||||||
|
final String randomName = 'sim_${DateTime.now().microsecondsSinceEpoch}';
|
||||||
|
final Directory tempDir = await getTemporaryDirectory();
|
||||||
|
final String tempPath = tempDir.path;
|
||||||
|
final String assetPath = 'assets/images/simulator.jpeg';
|
||||||
|
|
||||||
|
final ByteData data = await rootBundle.load(assetPath);
|
||||||
|
final File tempFile = File('$tempPath/$randomName.jpeg');
|
||||||
|
await tempFile.writeAsBytes(data.buffer.asUint8List(), flush: true);
|
||||||
|
|
||||||
|
return tempFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,79 +5,59 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.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/main.dart';
|
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/home/visit_photo_tag.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/reusable/reusable_widget.dart';
|
|
||||||
import 'package:mobdr/ui/shopping_cart/tab_shopping_cart.dart';
|
|
||||||
import 'package:mobdr/ui/reusable/global_function.dart';
|
|
||||||
|
|
||||||
import 'package:mobdr/db/box_photo.dart';
|
import 'package:mobdr/db/box_photo.dart';
|
||||||
|
import 'package:mobdr/db/box_photo_typology.dart';
|
||||||
|
|
||||||
class PhotoDetailPage extends StatefulWidget {
|
//TODO : faire concurrents ===
|
||||||
|
|
||||||
|
class VisitPhotoTypologyDetailPage extends StatefulWidget {
|
||||||
// variables corresponding to the data parameters
|
// variables corresponding to the data parameters
|
||||||
final int id;
|
final int pp_id;
|
||||||
final String name;
|
final int pp_id_distrib;
|
||||||
final String image;
|
final String pp_langage;
|
||||||
final String tags;
|
final String pp_image;
|
||||||
final double price;
|
final int pp_id_typologie;
|
||||||
final int photo;
|
|
||||||
final double rating;
|
|
||||||
final int review;
|
|
||||||
final int sale;
|
|
||||||
final String date;
|
|
||||||
|
|
||||||
// Requiring data parameters
|
// Requiring data parameters
|
||||||
const PhotoDetailPage(
|
VisitPhotoTypologyDetailPage({
|
||||||
{Key? key,
|
Key? key,
|
||||||
this.id = 0,
|
required this.pp_id,
|
||||||
this.name = '',
|
required this.pp_id_distrib,
|
||||||
this.image = '',
|
required this.pp_langage,
|
||||||
this.tags = '',
|
required this.pp_image,
|
||||||
this.price = 24,
|
required this.pp_id_typologie,
|
||||||
this.photo = 1,
|
}) : super(key: key);
|
||||||
this.rating = 4,
|
|
||||||
this.review = 45,
|
|
||||||
this.sale = 63,
|
|
||||||
this.date = ''})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PhotoDetailPageState createState() => _PhotoDetailPageState();
|
_VisitPhotoTypologyDetailPageState createState() =>
|
||||||
|
_VisitPhotoTypologyDetailPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
class _VisitPhotoTypologyDetailPageState
|
||||||
// initialize global function and reusable widget
|
extends State<VisitPhotoTypologyDetailPage> {
|
||||||
final _globalFunction = GlobalFunction();
|
|
||||||
final _reusableWidget = ReusableWidget();
|
|
||||||
|
|
||||||
bool _isLoading = true;
|
bool _isLoading = true;
|
||||||
String _errorMessage = '';
|
String _errorMessage = '';
|
||||||
|
|
||||||
// Typology list
|
// Typology list
|
||||||
late List<String> _typologyList = [];
|
late List<PhotoTypology> _typologyList = [];
|
||||||
int _typologyIndex = 0;
|
int _typologyIndex = 0;
|
||||||
|
|
||||||
List<String> _chickenParts = [];
|
List<String> _visibilities = [];
|
||||||
int _maxChickenParts = 2;
|
|
||||||
|
|
||||||
// shopping cart count
|
|
||||||
int _shoppingCartCount = 3;
|
|
||||||
|
|
||||||
late String tags = "";
|
|
||||||
late List<String> tagList = [];
|
late List<String> tagList = [];
|
||||||
|
|
||||||
late Photo _photo;
|
late Photo _photo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
loadData(widget.id).then((_) {
|
loadData(widget.pp_id).then((_) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
|
|
@ -115,67 +95,27 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
color: GlobalStyle.appBarIconThemeColor,
|
color: GlobalStyle.appBarIconThemeColor,
|
||||||
),
|
),
|
||||||
elevation: GlobalStyle.appBarElevation,
|
elevation: GlobalStyle.appBarElevation,
|
||||||
titleSpacing: 0.0,
|
title: Text(
|
||||||
// create search text field in the app bar
|
'Photo',
|
||||||
title: Container(
|
style: GlobalStyle.appBarTitle,
|
||||||
margin: EdgeInsets.only(right: 16),
|
|
||||||
child: TextButton(
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: MaterialStateProperty.resolveWith<Color>(
|
|
||||||
(Set<MaterialState> states) => Colors.grey[100]!,
|
|
||||||
),
|
|
||||||
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
|
||||||
shape: MaterialStateProperty.all(RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(5.0),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(context,
|
|
||||||
MaterialPageRoute(builder: (context) => SearchPage()));
|
|
||||||
},
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 8),
|
|
||||||
Icon(Icons.search, color: Colors.grey[500], size: 18),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
'Search Product',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
fontWeight: FontWeight.normal),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
),
|
),
|
||||||
backgroundColor: GlobalStyle.appBarBackgroundColor,
|
backgroundColor: GlobalStyle.appBarBackgroundColor,
|
||||||
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle,
|
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle),
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
padding: EdgeInsets.all(0),
|
|
||||||
constraints: BoxConstraints(),
|
|
||||||
icon: _customShoppingCart(_shoppingCartCount),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => TabShoppingCartPage()));
|
|
||||||
}),
|
|
||||||
IconButton(
|
|
||||||
icon: _reusableWidget.customNotifIcon(
|
|
||||||
count: 8, notifColor: BLACK_GREY),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => NotificationPage()));
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
bottom: _reusableWidget.bottomAppBar(),
|
|
||||||
),
|
|
||||||
body: WillPopScope(
|
body: WillPopScope(
|
||||||
onWillPop: () {
|
onWillPop: () {
|
||||||
Navigator.pop(context);
|
// fred
|
||||||
|
Map<String, dynamic> result = {
|
||||||
|
'change_typologie': _typologyIndex !=
|
||||||
|
_typologyList.indexWhere((typology) =>
|
||||||
|
typology.id_photo_typologie == widget.pp_id_typologie),
|
||||||
|
'tags': tagList.join(","),
|
||||||
|
'photo_principale': _visibilities.contains('principal') ? 1 : 0,
|
||||||
|
'photo_privee': _visibilities.contains('private') ? 1 : 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// return to the parent page fred
|
||||||
|
Navigator.pop(context, result);
|
||||||
|
|
||||||
return Future.value(true);
|
return Future.value(true);
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -183,8 +123,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
Flexible(
|
Flexible(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
Image.file(File(widget.image), fit: BoxFit.cover),
|
Image.file(File(widget.pp_image), fit: BoxFit.cover),
|
||||||
//_createProductSlider(),
|
|
||||||
_buildPhotoTypology(),
|
_buildPhotoTypology(),
|
||||||
_buildPhotoVisibility(),
|
_buildPhotoVisibility(),
|
||||||
_buildPhotoTag(context),
|
_buildPhotoTag(context),
|
||||||
|
|
@ -230,7 +169,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_shoppingCartCount++;
|
//_shoppingCartCount++;
|
||||||
});
|
});
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
msg: 'Item has been added to Shopping Cart',
|
msg: 'Item has been added to Shopping Cart',
|
||||||
|
|
@ -246,7 +185,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
borderRadius: BorderRadius.all(Radius.circular(
|
borderRadius: BorderRadius.all(Radius.circular(
|
||||||
10) // <--- border radius here
|
10) // <--- border radius here
|
||||||
)),
|
)),
|
||||||
child: Text('Add to Shopping Cart',
|
child: Text('Copier dans galerie',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: SOFT_BLUE,
|
color: SOFT_BLUE,
|
||||||
fontWeight: FontWeight.bold)),
|
fontWeight: FontWeight.bold)),
|
||||||
|
|
@ -261,38 +200,6 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _customShoppingCart(int count) {
|
|
||||||
return Stack(
|
|
||||||
children: <Widget>[
|
|
||||||
Icon(Icons.shopping_cart, color: BLACK_GREY),
|
|
||||||
Positioned(
|
|
||||||
right: 0,
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.all(1),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: ASSENT_COLOR,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
minWidth: 14,
|
|
||||||
minHeight: 14,
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
count.toString(),
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 8,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildPhotoTypology() {
|
Widget _buildPhotoTypology() {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 12),
|
margin: EdgeInsets.only(top: 12),
|
||||||
|
|
@ -307,7 +214,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
),
|
),
|
||||||
Wrap(
|
Wrap(
|
||||||
children: List.generate(_typologyList.length, (index) {
|
children: List.generate(_typologyList.length, (index) {
|
||||||
return radioSize(_typologyList[index], index);
|
return radioSize(_typologyList[index].libelle, index);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -316,7 +223,11 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
|
|
||||||
Widget radioSize(String txt, int index) {
|
Widget radioSize(String txt, int index) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
|
// save photo typology in the database
|
||||||
|
objectbox.putPhotoTypologie(
|
||||||
|
widget.pp_id, _typologyList[index].id_photo_typologie);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_typologyIndex = index;
|
_typologyIndex = index;
|
||||||
});
|
});
|
||||||
|
|
@ -339,20 +250,20 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO changer chicken
|
Widget _checkboxVisibility({value, primaryText}) {
|
||||||
Widget _checboxChicken({value = 'breast', primaryText = 'Chicken Breast'}) {
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_chickenParts.contains(value)) {
|
if (_visibilities.contains(value)) {
|
||||||
_chickenParts.remove(value);
|
_visibilities.remove(value);
|
||||||
} else {
|
} else {
|
||||||
if (_chickenParts.length < _maxChickenParts) {
|
_visibilities.add(value);
|
||||||
_chickenParts.add(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// save photo visibilities in the database
|
||||||
|
objectbox.putPhotoVisibilities(widget.pp_id, _visibilities);
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -360,14 +271,14 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
width: 1,
|
width: 1,
|
||||||
color: (_chickenParts.contains(value))
|
color: (_visibilities.contains(value))
|
||||||
? PRIMARY_COLOR
|
? PRIMARY_COLOR
|
||||||
: BLACK77),
|
: BLACK77),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(4.0)),
|
borderRadius: BorderRadius.all(Radius.circular(4.0)),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(2),
|
padding: const EdgeInsets.all(2),
|
||||||
child: (_chickenParts.contains(value))
|
child: (_visibilities.contains(value))
|
||||||
? Icon(
|
? Icon(
|
||||||
Icons.check,
|
Icons.check,
|
||||||
size: 12.0,
|
size: 12.0,
|
||||||
|
|
@ -385,7 +296,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: BLACK77,
|
color: BLACK77,
|
||||||
fontWeight: (_chickenParts.contains(value))
|
fontWeight: (_visibilities.contains(value))
|
||||||
? FontWeight.bold
|
? FontWeight.bold
|
||||||
: FontWeight.normal)),
|
: FontWeight.normal)),
|
||||||
],
|
],
|
||||||
|
|
@ -406,12 +317,12 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
_checboxChicken(value: 'public', primaryText: 'Public'),
|
_checkboxVisibility(value: 'private', primaryText: 'Privée'),
|
||||||
Divider(
|
Divider(
|
||||||
height: 32,
|
height: 32,
|
||||||
color: Colors.grey[400],
|
color: Colors.grey[400],
|
||||||
),
|
),
|
||||||
_checboxChicken(value: 'principal', primaryText: 'Principal')
|
_checkboxVisibility(value: 'principal', primaryText: 'Principale')
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -424,8 +335,11 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
final newTags = await Navigator.push<List<String>>(
|
final newTags = await Navigator.push<List<String>>(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) => PhotoTagPage(
|
||||||
PhotoTagPage(photoId: this._photo.id, currentTags: tagList),
|
pp_langage: widget.pp_langage,
|
||||||
|
pp_id_distrib: widget.pp_id_distrib,
|
||||||
|
pp_photoId: this._photo.id,
|
||||||
|
pp_currentTags: tagList),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -465,18 +379,27 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// data initialization on loading.
|
/// Initializes data when the page loads.
|
||||||
Future<void> loadData(int photoId) async {
|
Future<void> loadData(int photoId) async {
|
||||||
|
String tags = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// photo typologies initialization
|
// photo typologies initialization
|
||||||
_typologyList = objectbox.getPhotoTypologiesLabels();
|
_typologyList = objectbox.getPhotoTypologiesList();
|
||||||
|
|
||||||
|
_typologyIndex = _typologyList.indexWhere(
|
||||||
|
(typology) => typology.id_photo_typologie == widget.pp_id_typologie);
|
||||||
|
|
||||||
// get photo object
|
// get photo object
|
||||||
_photo = objectbox.getPhotoById(photoId)!;
|
_photo = objectbox.getPhotoById(photoId)!;
|
||||||
|
|
||||||
|
// visibilities initialization
|
||||||
|
if (_photo.photo_privee == 1) _visibilities.add('private');
|
||||||
|
if (_photo.photo_principale == 1) _visibilities.add('principal');
|
||||||
|
|
||||||
// photo tag initialization
|
// photo tag initialization
|
||||||
tags = _photo.tags;
|
tags = _photo.tags;
|
||||||
tagList = tags.isEmpty ? [] : tags.split(",");
|
tagList = tags.isEmpty ? [] : _photo.tags.split(",");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// set errorMessage for debug
|
// set errorMessage for debug
|
||||||
_errorMessage = 'Error loading photo: $e';
|
_errorMessage = 'Error loading photo: $e';
|
||||||
|
|
@ -4,7 +4,6 @@ we used AutomaticKeepAliveClientMixin to keep the state when moving from 1 navba
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'package:mobdr/config/global_style.dart';
|
import 'package:mobdr/config/global_style.dart';
|
||||||
import 'package:mobdr/main.dart';
|
|
||||||
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
||||||
import 'package:mobdr/network/api_provider.dart';
|
import 'package:mobdr/network/api_provider.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import device_info_plus
|
||||||
import objectbox_flutter_libs
|
import objectbox_flutter_libs
|
||||||
import package_info_plus
|
import package_info_plus
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
|
|
@ -13,6 +14,7 @@ import sqflite
|
||||||
import wakelock_macos
|
import wakelock_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
|
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
|
||||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
|
|
||||||
20
pubspec.lock
20
pubspec.lock
|
|
@ -149,10 +149,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: camera
|
name: camera
|
||||||
sha256: ad1c53c554a2f3e5708f3b01eb738d60b902bb61f7f4ad420c65c715e65a7379
|
sha256: "7afc256902062cab191540c09908b98bc71e93d5e20b6486dbee51aa7731e9b2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.3+2"
|
version: "0.10.4"
|
||||||
camera_android:
|
camera_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -297,6 +297,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
device_info_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: device_info_plus
|
||||||
|
sha256: "435383ca05f212760b0a70426b5a90354fe6bd65992b3a5e27ab6ede74c02f5c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "8.2.0"
|
||||||
|
device_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_platform_interface
|
||||||
|
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.0"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,10 @@ dependencies:
|
||||||
shimmer: 2.0.0
|
shimmer: 2.0.0
|
||||||
|
|
||||||
image_picker: ^0.8.7
|
image_picker: ^0.8.7
|
||||||
camera: ^0.10.3+2
|
|
||||||
|
# https://pub.dev/packages/camera
|
||||||
|
camera: ^0.10.4
|
||||||
|
|
||||||
permission_handler: 10.2.0
|
permission_handler: 10.2.0
|
||||||
image: ^4.0.15
|
image: ^4.0.15
|
||||||
|
|
||||||
|
|
@ -75,6 +78,9 @@ dependencies:
|
||||||
universal_io: 2.2.0
|
universal_io: 2.2.0
|
||||||
xml: ^6.2.2
|
xml: ^6.2.2
|
||||||
|
|
||||||
|
# https://pub.dev/packages/device_info_plus/install
|
||||||
|
device_info_plus: ^8.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
@ -148,6 +154,7 @@ flutter:
|
||||||
- assets/images/process_timeline/status3.png
|
- assets/images/process_timeline/status3.png
|
||||||
- assets/images/process_timeline/status4.png
|
- assets/images/process_timeline/status4.png
|
||||||
- assets/images/process_timeline/status5.png
|
- assets/images/process_timeline/status5.png
|
||||||
|
- assets/images/simulator.jpeg
|
||||||
|
|
||||||
- assets/lang/fr.json
|
- assets/lang/fr.json
|
||||||
- assets/lang/en.json
|
- assets/lang/en.json
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue