Compare commits

..

6 Commits

Author SHA1 Message Date
Thomas Fransolet
9b08b27afc version 2.0.3 2025-07-09 14:28:19 +02:00
Thomas Fransolet
562091ca67 Fix for support SDK Android 35 2025-07-09 14:03:51 +02:00
Thomas Fransolet
6950daca27 Merge branch 'master' into MDLF-2.0.1
# Conflicts:
#	README.md
#	ios/Runner.xcodeproj/project.pbxproj
#	ios/Runner/Info.plist
#	linux/CMakeLists.txt
2025-07-09 13:27:16 +02:00
Thomas Fransolet
df1165d5a0 update readme 2025-07-09 13:26:10 +02:00
Thomas Fransolet
4839b4da61 instance id and colors 2024-10-17 11:37:01 +02:00
Thomas Fransolet
c14d03cd72 update appId + icons 2024-10-17 11:18:45 +02:00
63 changed files with 152 additions and 415 deletions

View File

@ -61,5 +61,5 @@ Faut pas oublier d'aller changer la version avant chaque upload de version (Puis
-> https://easyappicon.com/ -> https://easyappicon.com/
3) Mettre à jour android manifest et info.plist (faire un CTRL MAJ F et replace..) 3) Mettre à jour android manifest et info.plist (faire un CTRL MAJ F et replace..)
- be.unov.myinfomate.mdlf - be.unov.myinfomate.mdlf
- android : be.unov.mymuseum.fortsaintheribert - iod: be.unov.myvisit.mymuseumVisitapp - android : be.unov.mymuseum.fortsaintheribert - ios: be.unov.myvisit.mymuseumVisitapp
4) Mettre à jour les couleurs de l'app 4) Mettre à jour les couleurs de l'app

View File

@ -39,7 +39,8 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"*/ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"*/
android { android {
compileSdkVersion 34 namespace = "be.unov.myinfomate.mdlf"
compileSdkVersion 35
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -56,7 +57,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "be.unov.mymuseum.fortsaintheribert" // Update for mdlf and other clients -- "be.unov.mymuseum.fortsaintheribert" // be.unov.myinfomate.mdlf applicationId "be.unov.myinfomate.mdlf" // Update for mdlf and other clients -- "be.unov.mymuseum.fortsaintheribert" // be.unov.myinfomate.mdlf
minSdkVersion flutter.minSdkVersion minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.unov.mymuseum.fortsaintheribert"> package="be.unov.myinfomate.mdlf">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.unov.mymuseum.fortsaintheribert"> package="be.unov.myinfomate.mdlf">
<!-- package="be.unov.myinfomate.mdlf"> --> <!-- package="be.unov.myinfomate.mdlf"> -->
<!-- be.unov.mymuseum.fortsaintheribert -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
@ -20,7 +21,7 @@
<uses-feature android:name="android.hardware.camera" />--> <uses-feature android:name="android.hardware.camera" />-->
<!-- android:label="Fort Saint Héribert" "Musée de la fraise" --> <!-- android:label="Fort Saint Héribert" "Musée de la fraise" -->
<application <application
android:label="Fort Saint Héribert" android:label="Musée de la fraise"
android:name="${applicationName}" android:name="${applicationName}"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">

View File

@ -1,4 +1,4 @@
package be.unov.mymuseum.fortsaintheribert package be.unov.myinfomate.mdlf
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 KiB

After

Width:  |  Height:  |  Size: 206 KiB

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="ic_launcher_background">#7f845b</color> <color name="ic_launcher_background">#e92f30</color>
</resources> </resources>

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.unov.mymuseum.fortsaintheribert"> package="be.unov.myinfomate.mdlf">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip

View File

@ -31,7 +31,7 @@ pluginManagement {
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.2.0" apply false id "com.android.application" version "8.1.0" apply false
id "org.jetbrains.kotlin.android" version "1.9.0" apply false id "org.jetbrains.kotlin.android" version "1.9.0" apply false
} }

View File

@ -391,7 +391,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = be.unov.myvisit.mymuseumVisitapp; PRODUCT_BUNDLE_IDENTIFIER = be.unov.myinfomate.mdlf;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -527,7 +527,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = be.unov.myvisit.mymuseumVisitapp; PRODUCT_BUNDLE_IDENTIFIER = be.unov.myinfomate.mdlf;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -555,7 +555,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = be.unov.myvisit.mymuseumVisitapp; PRODUCT_BUNDLE_IDENTIFIER = be.unov.myinfomate.mdlf;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 948 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 625 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 625 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -15,7 +15,7 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>be.unov.myvisit.mymuseumVisitapp</string> <string>be.unov.myinfomate.mdlf</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>

View File

@ -9,8 +9,7 @@ import 'package:mymuseum_visitapp/Screens/Quizz/quizz_page.dart';
import 'package:mymuseum_visitapp/app_context.dart'; import 'package:mymuseum_visitapp/app_context.dart';
import 'package:mymuseum_visitapp/constants.dart'; import 'package:mymuseum_visitapp/constants.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart'; import 'package:mobile_scanner/mobile_scanner.dart';
class ScannerDialog extends StatefulWidget { class ScannerDialog extends StatefulWidget {
const ScannerDialog({Key? key, required this.appContext}) : super(key: key); const ScannerDialog({Key? key, required this.appContext}) : super(key: key);
@ -22,19 +21,16 @@ class ScannerDialog extends StatefulWidget {
} }
class _ScannerDialogState extends State<ScannerDialog> { class _ScannerDialogState extends State<ScannerDialog> {
Barcode? result; final MobileScannerController controller = MobileScannerController();
QRViewController? controller; bool isProcessing = false;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
@override @override
void reassemble() { void reassemble() {
super.reassemble(); super.reassemble();
if (Platform.isAndroid) { if (Platform.isAndroid) {
controller!.pauseCamera(); controller.stop();
} }
controller!.resumeCamera(); controller.start();
} }
@override @override
@ -42,208 +38,150 @@ class _ScannerDialogState extends State<ScannerDialog> {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
return Container( return Container(
height: size.height *0.5, height: size.height * 0.5,
width: size.width *0.9, width: size.width * 0.9,
child: Stack( child: Stack(
children: [ children: [
Center( Center(
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(10.0), borderRadius: BorderRadius.circular(10.0),
child: _buildQrView(context), child: MobileScanner(
) controller: controller,
), //allowDuplicates: false,
Positioned( onDetect: (barcodes) => _onDetect(barcodes),
top: 0,
right: 0,
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: kMainColor1,
borderRadius: BorderRadius.circular(20.0),
), ),
margin: const EdgeInsets.all(8),
child: InkWell(
onTap: () async {
await controller?.toggleFlash();
setState(() {});
},
child: FutureBuilder(
future: controller?.getFlashStatus(),
builder: (context, snapshot) {
return const Icon(Icons.flash_on, color: Colors.white);
},
)),
), ),
), ),
Positioned( _buildControlButton(
bottom: 0, icon: Icons.flash_on,
right: 0, onTap: () => controller.toggleTorch(),
child: Container( alignment: Alignment.topRight,
width: 45, ),
height: 45, _buildControlButton(
decoration: BoxDecoration( icon: Icons.flip_camera_android,
shape: BoxShape.rectangle, onTap: () => controller.switchCamera(),
color: kMainColor1, alignment: Alignment.bottomRight,
borderRadius: BorderRadius.circular(20.0),
),
margin: const EdgeInsets.all(8),
child: InkWell(
onTap: () async {
await controller?.flipCamera();
setState(() {});
},
child: FutureBuilder(
future: controller?.getCameraInfo(),
builder: (context, snapshot) {
return const Icon(Icons.flip_camera_android, color: Colors.white);
},
)),
),
), ),
], ],
), ),
); );
} }
Widget _buildQrView(BuildContext context) { Widget _buildControlButton({
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly. required IconData icon,
var scanArea = (MediaQuery.of(context).size.width < 400 || required VoidCallback onTap,
MediaQuery.of(context).size.height < 400) required Alignment alignment,
? 225.0 }) {
: 300.0; return Align(
alignment: alignment,
// To ensure the Scanner view is properly sizes after rotation child: Container(
// we need to listen for Flutter SizeChanged notification and update controller width: 45,
return QRView( height: 45,
key: qrKey, margin: const EdgeInsets.all(8),
onQRViewCreated: _onQRViewCreated, decoration: BoxDecoration(
overlay: QrScannerOverlayShape( shape: BoxShape.rectangle,
borderColor: kMainColor1, color: kMainColor1,
borderRadius: 10, borderRadius: BorderRadius.circular(20.0),
borderLength: 25, ),
borderWidth: 5, child: InkWell(
overlayColor: Colors.black.withValues(alpha: 0.55), onTap: onTap,
cutOutSize: 225.0), child: Icon(icon, color: Colors.white),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p), ),
),
); );
} }
_onQRViewCreated(QRViewController controller) { void _onDetect(BarcodeCapture capture) {
setState(() { if (isProcessing) return;
this.controller = controller;
});
if (Platform.isAndroid) {
controller.pauseCamera();
}
controller.resumeCamera();
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
var code = result == null ? "" : result!.code.toString(); final barcode = capture.barcodes.first;
if(result!.format == BarcodeFormat.qrcode) { final code = barcode.rawValue ?? "";
controller.pauseCamera();
RegExp regExp = RegExp(r'^(?:https:\/\/web\.myinfomate\.be\/([^\/]+)\/([^\/]+)\/([^\/]+)|([^\/]+))$'); if (barcode.format == BarcodeFormat.qrCode && code.isNotEmpty) {
var match = regExp.firstMatch(code); isProcessing = true;
String? instanceId;
String? configurationId;
String? sectionId;
if (match != null) { // also support simple code (Fort saint heribert!)
instanceId = match.group(1);
configurationId = match.group(2);
sectionId = match.group(3) ?? match.group(4);
print('InstanceId: $instanceId'); RegExp regExp = RegExp(r'^(?:https:\/\/web\.myinfomate\.be\/([^\/]+)\/([^\/]+)\/([^\/]+)|([^\/]+))$'); // myinfomate
print('ConfigurationId: $configurationId'); RegExp regExp2 = RegExp(r'^(?:https:\/\/web\.mymuseum\.be\/([^\/]+)\/([^\/]+)\/([^\/]+)|([^\/]+))$'); // myinfomate
print('SectionId: $sectionId'); var match = regExp.firstMatch(code);
} else { var match2 = regExp2.firstMatch(code);
print('L\'URL ne correspond pas au format attendu.'); String? instanceId;
} String? configurationId;
String? sectionId;
if(match == null) {
instanceId = match2?.group(1);
configurationId = match2?.group(2);
sectionId = match2?.group(3) ?? match2?.group(4);
} else {
instanceId = match.group(1);
configurationId = match.group(2);
sectionId = match.group(3) ?? match.group(4);
}
//print("QR CODE FOUND"); if ((match == null && match2 == null) || sectionId == null) {
/*ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('QR CODE FOUND - ${code.toString()}')),
);*/
VisitAppContext visitAppContext = widget.appContext!.getContext();
if(!visitAppContext.sectionIds!.contains(sectionId) || sectionId == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(TranslationHelper.getFromLocale('invalidQRCode', widget.appContext!.getContext())), backgroundColor: kMainColor2),
);
Navigator.of(context).pop();
} else {
SectionDTO section = visitAppContext.currentSections!.firstWhere((cs) => cs!.id == sectionId)!;
switch(section.type) {
case SectionType.Article:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return ArticlePage(visitAppContextIn: visitAppContext, articleId: section.id!);
},
),
);
break;
case SectionType.Quizz:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return QuizzPage(visitAppContextIn: visitAppContext, sectionId: section.id!);
},
),
);
break;
}
}
}
});
});
}
Future<void> _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) async {
//log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
var status = await Permission.camera.status;
if(!status.isGranted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')), SnackBar(content: Text("L'URL ne correspond pas au format attendu."), backgroundColor: kMainColor2),
); );
Navigator.of(context).pop();
return;
}
// You can request multiple permissions at once. VisitAppContext visitAppContext = widget.appContext!.getContext();
Map<Permission, PermissionStatus> statuses = await [
Permission.camera, if (visitAppContext.sectionIds == null || !visitAppContext.sectionIds!.contains(sectionId)) {
].request(); ScaffoldMessenger.of(context).showSnackBar(
print(statuses[Permission.camera]); SnackBar(content: Text(TranslationHelper.getFromLocale('invalidQRCode', visitAppContext)), backgroundColor: kMainColor2),
print(status); );
Navigator.of(context).pop();
} else {
SectionDTO section = visitAppContext.currentSections!.firstWhere((
cs) => cs!.id == sectionId)!;
switch (section.type) {
case SectionType.Article:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return ArticlePage(visitAppContextIn: visitAppContext,
articleId: section.id!);
},
),
);
break;
case SectionType.Quizz:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return QuizzPage(visitAppContextIn: visitAppContext,
sectionId: section.id!);
},
),
);
break;
}
} }
} }
} }
@override @override
void dispose() { void dispose() {
controller?.dispose(); controller.dispose();
super.dispose(); super.dispose();
} }
} }
showScannerDialog (BuildContext context, AppContext appContext) { showScannerDialog(BuildContext context, AppContext appContext) {
showDialog( showDialog(
builder: (BuildContext context) => AlertDialog( context: context,
shape: const RoundedRectangleBorder( builder: (BuildContext context) => AlertDialog(
borderRadius: BorderRadius.all(Radius.circular(10.0)) shape: const RoundedRectangleBorder(
), borderRadius: BorderRadius.all(Radius.circular(10.0)),
content: ScannerDialog(appContext: appContext), ),
contentPadding: EdgeInsets.zero, content: ScannerDialog(appContext: appContext),
), context: context contentPadding: EdgeInsets.zero,
),
); );
} }

View File

@ -10,7 +10,7 @@ class VisitAppContext with ChangeNotifier {
String? id = ""; String? id = "";
String? language = ""; String? language = "";
String? instanceId = "633ee379d9405f32f166f047"; // 63514fd67ed8c735aaa4b8f2 MyInfoMate test instance -- Fort de Saint-Héribert Mymuseum instance id : 633ee379d9405f32f166f047 // 63514fd67ed8c735aaa4b8f1 Mymuseum test // MDLF instance 65ccc67265373befd15be511 String? instanceId = "65ccc67265373befd15be511"; // 63514fd67ed8c735aaa4b8f2 MyInfoMate test instance -- Fort de Saint-Héribert Mymuseum instance id : 633ee379d9405f32f166f047 // 63514fd67ed8c735aaa4b8f1 Mymuseum test // MDLF instance 65ccc67265373befd15be511
List<ConfigurationDTO>? configurations; List<ConfigurationDTO>? configurations;
ConfigurationDTO? configuration; ConfigurationDTO? configuration;

View File

@ -1,206 +0,0 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
import 'package:mymuseum_visitapp/app_context.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
// NOT USED ANYMORE
class ScannerPage extends StatefulWidget {
const ScannerPage({Key? key}) : super(key: key);
@override
State<ScannerPage> createState() => _ScannerPageState();
}
class _ScannerPageState extends State<ScannerPage> {
Barcode? result;
QRViewController? controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
@override
void reassemble() {
print("reassemble ");
super.reassemble();
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "QR Code scan",
isHomeButton: false,
),
body: Column(
children: <Widget>[
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (result != null)
Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
else
const Text('Scan a code'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.toggleFlash();
setState(() {});
},
child: FutureBuilder(
future: controller?.getFlashStatus(),
builder: (context, snapshot) {
return Icon(Icons.flash_on);
},
)),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.flipCamera();
setState(() {});
},
child: FutureBuilder(
future: controller?.getCameraInfo(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Text(
'Camera facing ${describeEnum(snapshot.data!)}');
} else {
return const Text('loading');
}
},
)),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.pauseCamera();
},
child: const Text('pause',
style: TextStyle(fontSize: 20)),
),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
//print(controller);
await controller?.resumeCamera();
},
child: const Text('resume',
style: TextStyle(fontSize: 20)),
),
)
],
),
],
),
),
)
],
),
);
}
Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 225.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 25,
borderWidth: 5,
cutOutSize: 225.0),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
print(result);
print(result!.code.toString());
var code = result == null ? "" : result!.code.toString();
if(result!.format == BarcodeFormat.qrcode) {
controller.pauseCamera();
print("QR CODE FOUND");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('QR CODE FOUND - ${code.toString()}')),
);
// TODO search in local if data == Id of Article
// If so, navigate to article view
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return ArticlePage(articleId: code, visitAppContextIn: VisitAppContext()); // will not work..
},
),
);
}
});
});
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
//log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')),
);
}
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}

View File

@ -30,9 +30,9 @@ const kTextRed = Color(0xFFba0505);
const kBackgroundGrey = Color(0xFFb5b7b9); const kBackgroundGrey = Color(0xFFb5b7b9);
const kBackgroundSecondGrey = Color(0xFF5b5b63); const kBackgroundSecondGrey = Color(0xFF5b5b63);
const kMainColor0 = Color(0xFF306bac); // const kBlue0 = Color(0xFF306bac); const kMainColor0 = Color(0xFFe52122); // const kBlue0 = Color(0xFF306bac) // mdlf 0xFFe52122;
const kMainColor1 = Color(0xFF308aae); // const kBlue1 = Color(0xFF308aae); const kMainColor1 = Color(0xFFed7082); // const kBlue1 = Color(0xFF308aae) // mdlf 0xFFed7082;
const kMainColor2 = Color(0xFF309cb0); // const kBlue2 = Color(0xFF309cb0); const kMainColor2 = Color(0xFFed7082); // const kBlue2 = Color(0xFF309cb0) // mdlf 0xFFed7082;
const kBackgroundLight = Color(0xfff3f3f3); const kBackgroundLight = Color(0xfff3f3f3);

View File

@ -32,7 +32,7 @@ void main() async {
List<SectionRead> articleReadTest = List<SectionRead>.from(await DatabaseHelper.instance.getData(DatabaseTableType.articleRead)); List<SectionRead> articleReadTest = List<SectionRead>.from(await DatabaseHelper.instance.getData(DatabaseTableType.articleRead));
localContext.readSections = articleReadTest; localContext.readSections = articleReadTest;
} else { } else {
localContext = VisitAppContext(language: "FR", id: "UserId_Init", instanceId: "633ee379d9405f32f166f047", isAdmin: false, isAllLanguages: false); // 63514fd67ed8c735aaa4b8f2 MyInfoMate test instance -- 633ee379d9405f32f166f047 MyMuseum Fort Saint-Héribert - MyMuseum instance 63514fd67ed8c735aaa4b8f1 // MDLF instance 65ccc67265373befd15be511 localContext = VisitAppContext(language: "FR", id: "UserId_Init", instanceId: "65ccc67265373befd15be511", isAdmin: false, isAllLanguages: false); // 63514fd67ed8c735aaa4b8f2 MyInfoMate test instance -- 633ee379d9405f32f166f047 MyMuseum Fort Saint-Héribert - MyMuseum instance 63514fd67ed8c735aaa4b8f1 // MDLF instance 65ccc67265373befd15be511
DatabaseHelper.instance.insert(DatabaseTableType.main, localContext.toMap()); DatabaseHelper.instance.insert(DatabaseTableType.main, localContext.toMap());
List<SectionRead> articleReadTest = List<SectionRead>.from(await DatabaseHelper.instance.getData(DatabaseTableType.articleRead)); List<SectionRead> articleReadTest = List<SectionRead>.from(await DatabaseHelper.instance.getData(DatabaseTableType.articleRead));
@ -93,7 +93,7 @@ class _MyAppState extends State<MyApp> {
create: (_) => AppContext(widget.visitAppContext), create: (_) => AppContext(widget.visitAppContext),
child: MaterialApp( child: MaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Fort Saint Héribert', //'Musée de la fraise' title: 'Musée de la fraise', //'Musée de la fraise' 'Fort Saint Héribert'
initialRoute: widget.initialRoute, initialRoute: widget.initialRoute,
localizationsDelegates: const [ localizationsDelegates: const [
AppLocalizations.delegate, AppLocalizations.delegate,

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX) project(runner LANGUAGES CXX)
set(BINARY_NAME "mymuseum_visitapp") set(BINARY_NAME "mymuseum_visitapp")
set(APPLICATION_ID "be.unov.myvisit.mymuseumVisitapp") set(APPLICATION_ID "be.unov.myinfomate.mdlf")
cmake_policy(SET CMP0063 NEW) cmake_policy(SET CMP0063 NEW)

View File

@ -612,6 +612,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.5" version: "1.0.5"
mobile_scanner:
dependency: "direct main"
description:
name: mobile_scanner
sha256: "827765afbd4792ff3fd105ad593821ac0f6d8a7d352689013b07ee85be336312"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -852,14 +860,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
qr_code_scanner:
dependency: "direct main"
description:
name: qr_code_scanner
sha256: f23b68d893505a424f0bd2e324ebea71ed88465d572d26bb8d2e78a4749591fd
url: "https://pub.dev"
source: hosted
version: "1.0.1"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@ -1210,7 +1210,7 @@ packages:
source: hosted source: hosted
version: "14.3.0" version: "14.3.0"
wakelock_plus: wakelock_plus:
dependency: transitive dependency: "direct main"
description: description:
name: wakelock_plus name: wakelock_plus
sha256: "14758533319a462ffb5aa3b7ddb198e59b29ac3b02da14173a1715d65d4e6e68" sha256: "14758533319a462ffb5aa3b7ddb198e59b29ac3b02da14173a1715d65d4e6e68"

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 2.0.2+21 version: 2.0.3+22
environment: environment:
sdk: ">=3.1.0 <4.0.0" sdk: ">=3.1.0 <4.0.0"
@ -31,7 +31,8 @@ dependencies:
sdk: flutter sdk: flutter
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
qr_code_scanner: ^1.0.1 #qr_code_scanner: ^1.0.1
mobile_scanner: ^4.0.0 # that replace qr_code_scanner..
auto_size_text: ^3.0.0 auto_size_text: ^3.0.0
openapi_generator_cli: ^5.0.2 openapi_generator_cli: ^5.0.2
openapi_generator: ^5.0.2 openapi_generator: ^5.0.2
@ -52,6 +53,8 @@ dependencies:
diacritic: ^0.1.3 diacritic: ^0.1.3
flutter_widget_from_html: ^0.15.2 flutter_widget_from_html: ^0.15.2
wakelock_plus: ^1.1.1
manager_api: manager_api:
path: manager_api path: manager_api
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.

BIN
release/mdlf_2_0_3.aab Normal file

Binary file not shown.