Add orientation logic for quizz (and tablet then) + clean code + update meterToBeacon + store beaconSection locally

This commit is contained in:
Fransolet Thomas 2023-03-02 17:52:35 +01:00
parent c2c0293ace
commit f43d23fe44
7 changed files with 664 additions and 907 deletions

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:manager_api/api.dart'; import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Models/articleRead.dart'; import 'package:mymuseum_visitapp/Models/articleRead.dart';
import 'package:mymuseum_visitapp/Models/beaconSection.dart';
import 'package:mymuseum_visitapp/Models/resourceModel.dart'; import 'package:mymuseum_visitapp/Models/resourceModel.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart'; import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
@ -12,47 +13,54 @@ enum DatabaseTableType {
configurations, configurations,
sections, sections,
resources, resources,
articleRead articleRead,
beaconSection
} }
class DatabaseHelper { class DatabaseHelper {
static final _databaseName = "visit_database.db"; static const _databaseName = "visit_database.db";
static final _databaseVersion = 1; static const _databaseVersion = 1;
static final mainTable = 'visitAppContext'; static const mainTable = 'visitAppContext';
static final columnLanguage = 'language'; static const columnLanguage = 'language';
static final columnLabel = 'label'; static const columnLabel = 'label';
static final columnId = 'id'; static const columnId = 'id';
static final columnInstanceId = 'instanceId'; static const columnInstanceId = 'instanceId';
static final columnData = 'data'; static const columnData = 'data';
static final columnType = 'type'; static const columnType = 'type';
static final columnDateCreation = 'dateCreation'; static const columnDateCreation = 'dateCreation';
static final columnIsMobile = 'isMobile'; static const columnIsMobile = 'isMobile';
static final columnIsTablet = 'isTablet'; static const columnIsTablet = 'isTablet';
static final columnIsOffline = 'isOffline'; static const columnIsOffline = 'isOffline';
static final configurationsTable = 'configurations'; static const configurationsTable = 'configurations';
static final columnLanguages = 'languages'; static const columnLanguages = 'languages';
static final columnPrimaryColor = 'primaryColor'; static const columnPrimaryColor = 'primaryColor';
static final columnSecondaryColor = 'secondaryColor'; static const columnSecondaryColor = 'secondaryColor';
static final sectionsTable = 'sections'; static const sectionsTable = 'sections';
static final columnTitle = 'title'; static const columnTitle = 'title';
static final columnDescription = 'description'; static const columnDescription = 'description';
static final columnImageId = 'imageId'; static const columnImageId = 'imageId';
static final columnImageSource = 'imageSource'; static const columnImageSource = 'imageSource';
static final columnConfigurationId = 'configurationId'; static const columnConfigurationId = 'configurationId';
static final columnIsSubSection = 'isSubSection'; static const columnIsSubSection = 'isSubSection';
static final columnParentId = 'parentId'; static const columnParentId = 'parentId';
static final columnOrderOfElement = 'orderOfElement'; static const columnOrderOfElement = 'orderOfElement';
static final resourcesTable = 'resources'; static const resourcesTable = 'resources';
static final columnSource = 'source'; static const columnSource = 'source';
static final articleReadTable = 'articleRead'; static const articleReadTable = 'articleRead';
static final columnLastTimeOpen = 'readTime'; static const columnLastTimeOpen = 'readTime';
static const beaconSectionTable = 'beaconSection';
static const columnMinorBeaconId = 'minorBeaconId';
static const columnOrderInConfig = 'orderInConfig';
static const columnSectionId = 'sectionId';
static const columnSectionType = 'sectionType';
DatabaseHelper._privateConstructor(); DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor(); static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
@ -69,66 +77,12 @@ class DatabaseHelper {
// SQL code to create the database table // SQL code to create the database table
Future _onCreate(Database db, int version) async { Future _onCreate(Database db, int version) async {
await db.execute(''' await createTable(db, DatabaseTableType.main);
CREATE TABLE $mainTable ( await createTable(db, DatabaseTableType.configurations);
$columnId TEXT NOT NULL PRIMARY KEY, await createTable(db, DatabaseTableType.sections);
$columnLanguage TEXT NOT NULL, await createTable(db, DatabaseTableType.resources);
$columnInstanceId TEXT NOT NULL await createTable(db, DatabaseTableType.articleRead);
) await createTable(db, DatabaseTableType.beaconSection);
''');
await db.execute('''
CREATE TABLE $configurationsTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnInstanceId TEXT NOT NULL,
$columnLabel TEXT NOT NULL,
$columnTitle TEXT NOT NULL,
$columnImageId TEXT,
$columnImageSource TEXT,
$columnLanguages TEXT NOT NULL,
$columnDateCreation TEXT NOT NULL,
$columnPrimaryColor TEXT,
$columnSecondaryColor TEXT,
$columnIsMobile BOOLEAN NOT NULL CHECK ($columnIsMobile IN (0,1)),
$columnIsTablet BOOLEAN NOT NULL CHECK ($columnIsTablet IN (0,1)),
$columnIsOffline BOOLEAN NOT NULL CHECK ($columnIsOffline IN (0,1))
)
''');
await db.execute('''
CREATE TABLE $sectionsTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnInstanceId TEXT NOT NULL,
$columnLabel TEXT NOT NULL,
$columnTitle TEXT NOT NULL,
$columnDescription TEXT,
$columnImageId TEXT,
$columnImageSource TEXT,
$columnConfigurationId TEXT NOT NULL,
$columnIsSubSection BOOLEAN NOT NULL CHECK ($columnIsSubSection IN (0,1)),
$columnParentId TEXT,
$columnType INT NOT NULL,
$columnData TEXT NOT NULL,
$columnDateCreation TEXT NOT NULL,
$columnOrderOfElement TEXT NOT NULL
)
''');
await db.execute('''
CREATE TABLE $resourcesTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnData TEXT NOT NULL,
$columnSource TEXT NOT NULL,
$columnType INT NOT NULL
)
''');
await db.execute('''
CREATE TABLE $articleReadTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnLastTimeOpen INT NOT NULL
)
''');
} }
Future<int> insert(DatabaseTableType type, Map<String, Object?> info) async { Future<int> insert(DatabaseTableType type, Map<String, Object?> info) async {
@ -141,6 +95,14 @@ class DatabaseHelper {
} }
//var test = await instance.getData(type); //var test = await instance.getData(type);
// Test if table exist
var isExistResult = await isExist(type);
if(!isExistResult) {
print("TABLE DOESNT EXIST");
await createTable(db, type);
}
var test = await DatabaseHelper.instance.queryWithColumnId(type, info[columnId].toString()); var test = await DatabaseHelper.instance.queryWithColumnId(type, info[columnId].toString());
if((type == DatabaseTableType.main && test.isNotEmpty) || (type != DatabaseTableType.main && test.isNotEmpty)) { //test!.where((t) => info[columnId] == t.id).isNotEmpty if((type == DatabaseTableType.main && test.isNotEmpty) || (type != DatabaseTableType.main && test.isNotEmpty)) { //test!.where((t) => info[columnId] == t.id).isNotEmpty
@ -181,6 +143,97 @@ class DatabaseHelper {
); );
} }
Future<void> createTable(Database db, DatabaseTableType type) async {
print("CREATE TABLE $type");
switch(type) {
case DatabaseTableType.main :
db.execute('''
CREATE TABLE $mainTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnLanguage TEXT NOT NULL,
$columnInstanceId TEXT NOT NULL
)
''');
break;
case DatabaseTableType.configurations :
db.execute('''
CREATE TABLE $configurationsTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnInstanceId TEXT NOT NULL,
$columnLabel TEXT NOT NULL,
$columnTitle TEXT NOT NULL,
$columnImageId TEXT,
$columnImageSource TEXT,
$columnLanguages TEXT NOT NULL,
$columnDateCreation TEXT NOT NULL,
$columnPrimaryColor TEXT,
$columnSecondaryColor TEXT,
$columnIsMobile BOOLEAN NOT NULL CHECK ($columnIsMobile IN (0,1)),
$columnIsTablet BOOLEAN NOT NULL CHECK ($columnIsTablet IN (0,1)),
$columnIsOffline BOOLEAN NOT NULL CHECK ($columnIsOffline IN (0,1))
)
''');
break;
case DatabaseTableType.sections :
db.execute('''
CREATE TABLE $sectionsTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnInstanceId TEXT NOT NULL,
$columnLabel TEXT NOT NULL,
$columnTitle TEXT NOT NULL,
$columnDescription TEXT,
$columnImageId TEXT,
$columnImageSource TEXT,
$columnConfigurationId TEXT NOT NULL,
$columnIsSubSection BOOLEAN NOT NULL CHECK ($columnIsSubSection IN (0,1)),
$columnParentId TEXT,
$columnType INT NOT NULL,
$columnData TEXT NOT NULL,
$columnDateCreation TEXT NOT NULL,
$columnOrderOfElement TEXT NOT NULL
)
''');
break;
case DatabaseTableType.resources:
db.execute('''
CREATE TABLE $resourcesTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnData TEXT NOT NULL,
$columnSource TEXT NOT NULL,
$columnType INT NOT NULL
)
''');
break;
case DatabaseTableType.articleRead:
db.execute('''
CREATE TABLE $articleReadTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnLastTimeOpen INT NOT NULL
)
''');
break;
case DatabaseTableType.beaconSection:
db.execute('''
CREATE TABLE $beaconSectionTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnMinorBeaconId INT NOT NULL,
$columnOrderInConfig INT NOT NULL,
$columnConfigurationId TEXT NOT NULL,
$columnSectionId TEXT NOT NULL,
$columnSectionType INT NOT NULL
)
''');
break;
}
}
Future<bool> isExist(DatabaseTableType type) async {
Database db = await instance.database;
var nameOfTable = _getTableName(type);
var test = await db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='$nameOfTable'");
return test.isNotEmpty;
}
Future<List<Map<String, dynamic>>> queryAllRows(DatabaseTableType type) async { Future<List<Map<String, dynamic>>> queryAllRows(DatabaseTableType type) async {
Database db = await instance.database; Database db = await instance.database;
var res = await db.query(_getTableName(type), orderBy: "$columnId DESC"); var res = await db.query(_getTableName(type), orderBy: "$columnId DESC");
@ -249,6 +302,10 @@ class DatabaseHelper {
dataToReturn.add(getArticleReadFromDB(element)); dataToReturn.add(getArticleReadFromDB(element));
//print("DB - dataToReturn --- $test --> "); //print("DB - dataToReturn --- $test --> ");
break; break;
case DatabaseTableType.beaconSection:
dataToReturn.add(getBeaconSectionFromDB(element));
//print("DB - dataToReturn --- $test --> ");
break;
} }
}); });
}).catchError((error) { }).catchError((error) {
@ -269,6 +326,8 @@ class DatabaseHelper {
return resourcesTable; return resourcesTable;
case DatabaseTableType.articleRead: case DatabaseTableType.articleRead:
return articleReadTable; return articleReadTable;
case DatabaseTableType.beaconSection:
return beaconSectionTable;
} }
} }
@ -325,4 +384,14 @@ class DatabaseHelper {
readTime: element["readTime"] readTime: element["readTime"]
); );
} }
BeaconSection getBeaconSectionFromDB(dynamic element) {
return BeaconSection(
minorBeaconId: element["minorBeaconId"],
orderInConfig: element["orderInConfig"],
configurationId: element["configurationId"],
sectionId: element["sectionId"],
sectionType: SectionType.values[element["sectionType"]]
);
}
} }

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:manager_api/api.dart'; import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Models/beaconSection.dart';
class ModelsHelper { class ModelsHelper {
static Map<String, dynamic> configurationToMap(ConfigurationDTO configuration) { static Map<String, dynamic> configurationToMap(ConfigurationDTO configuration) {
@ -39,4 +40,15 @@ class ModelsHelper {
'orderOfElement': section.order, 'orderOfElement': section.order,
}; };
} }
static Map<String, dynamic> beaconSectionToMap(BeaconSection beaconSection) {
return {
'Id': '${beaconSection.minorBeaconId}-${beaconSection.sectionId}',
'minorBeaconId': beaconSection.minorBeaconId,
'orderInConfig': beaconSection.orderInConfig,
'configurationId': beaconSection.configurationId,
'sectionId': beaconSection.sectionId,
'sectionType': beaconSection.sectionType!.value,
};
}
} }

View File

@ -23,7 +23,7 @@ class BeaconSection {
/*'rssi': rssi, /*'rssi': rssi,
'accuracy': accuracy, 'accuracy': accuracy,
'proximityUUID': proximityUUID,*/ 'proximityUUID': proximityUUID,*/
'found': found //'found': found
}; };
} }

View File

@ -8,6 +8,7 @@ import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
import 'package:mymuseum_visitapp/Components/Loading.dart'; import 'package:mymuseum_visitapp/Components/Loading.dart';
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart'; import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
import 'package:mymuseum_visitapp/Helpers/modelsHelper.dart';
import 'package:mymuseum_visitapp/Helpers/networkCheck.dart'; import 'package:mymuseum_visitapp/Helpers/networkCheck.dart';
import 'package:mymuseum_visitapp/Helpers/requirement_state_controller.dart'; import 'package:mymuseum_visitapp/Helpers/requirement_state_controller.dart';
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart'; import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
@ -128,7 +129,13 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
SnackBar(content: Text(TranslationHelper.getFromLocale("noInternet", appContext.getContext())), backgroundColor: kBlue2), SnackBar(content: Text(TranslationHelper.getFromLocale("noInternet", appContext.getContext())), backgroundColor: kBlue2),
); );
// TODO HANDLE BEACON IN LOCAL (CREATE TABLE) // GET BEACONS FROM LOCAL
List<BeaconSection> beaconSections = List<BeaconSection>.from(await DatabaseHelper.instance.getData(DatabaseTableType.beaconSection));
print("GOT beaconSection from LOCAL");
print(beaconSections);
visitAppContext.beaconSections = beaconSections;
//appContext.setContext(visitAppContext);
return configurations; return configurations;
} }
@ -138,9 +145,23 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
if(sections != null && sections.isNotEmpty) { if(sections != null && sections.isNotEmpty) {
List<BeaconSection> beaconSections = sections.map((e) => BeaconSection(minorBeaconId: e.beaconId, orderInConfig: e.order, configurationId: e.configurationId, sectionId: e.id, sectionType: e.type)).toList(); List<BeaconSection> beaconSections = sections.map((e) => BeaconSection(minorBeaconId: e.beaconId, orderInConfig: e.order, configurationId: e.configurationId, sectionId: e.id, sectionType: e.type)).toList();
visitAppContext.beaconSections = beaconSections; visitAppContext.beaconSections = beaconSections;
try {
// Clear all before
await DatabaseHelper.instance.clearTable(DatabaseTableType.beaconSection);
// Store it locally for offline mode
for(var beaconSection in beaconSections) {
await DatabaseHelper.instance.insert(DatabaseTableType.beaconSection, ModelsHelper.beaconSectionToMap(beaconSection));
}
print("STORE beaconSection DONE");
} catch(e) {
print("Issue during beaconSection insertion");
print(e);
}
print("Got some Beacons for you"); print("Got some Beacons for you");
print(beaconSections); print(beaconSections);
appContext.setContext(visitAppContext); // STORE IT, TODO Store it locally appContext.setContext(visitAppContext);
} }
} }

View File

@ -13,7 +13,8 @@ class QuestionsListWidget extends StatefulWidget {
List<QuestionSubDTO>? questionsSubDTO; List<QuestionSubDTO>? questionsSubDTO;
bool isShowResponse = false; bool isShowResponse = false;
final Function onShowResponse; final Function onShowResponse;
QuestionsListWidget({Key? key, this.questionsSubDTO, required this.isShowResponse, required this.onShowResponse}) : super(key: key); Orientation orientation;
QuestionsListWidget({Key? key, this.questionsSubDTO, required this.isShowResponse, required this.onShowResponse, required this.orientation}) : super(key: key);
@override @override
_QuestionsListWidget createState() => _QuestionsListWidget(); _QuestionsListWidget createState() => _QuestionsListWidget();
@ -47,231 +48,235 @@ class _QuestionsListWidget extends State<QuestionsListWidget> {
//Size size = Size(sizeAll.width * 0.65, kIsWeb ? sizeAll.height * 0.5 : sizeAll.height * 0.32); //Size size = Size(sizeAll.width * 0.65, kIsWeb ? sizeAll.height * 0.5 : sizeAll.height * 0.32);
final appContext = Provider.of<AppContext>(context); final appContext = Provider.of<AppContext>(context);
return SizedBox( /*return OrientationBuilder(
height: widget.isShowResponse ? MediaQuery.of(context).size.height * 0.825 : MediaQuery.of(context).size.height, builder: (context, orientation) {*/
width: double.infinity, return SizedBox(
//color: Colors.orange, height: widget.isShowResponse ? widget.orientation == Orientation.portrait ? MediaQuery.of(context).size.height * 0.825 : MediaQuery.of(context).size.height * 0.625 : MediaQuery.of(context).size.height,
child: Stack( width: double.infinity,
children: [ //color: Colors.orange,
Column( child: Stack(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: widget.isShowResponse ? MainAxisAlignment.start : MainAxisAlignment.start,
children: [ children: [
if(_questionsSubDTO.isNotEmpty) Column(
CarouselSlider( crossAxisAlignment: CrossAxisAlignment.center,
carouselController: sliderController, mainAxisAlignment: widget.isShowResponse ? MainAxisAlignment.start : MainAxisAlignment.start,
options: CarouselOptions( children: [
onPageChanged: (int index, CarouselPageChangedReason reason) { if(_questionsSubDTO.isNotEmpty)
setState(() { CarouselSlider(
currentIndex = index + 1; carouselController: sliderController,
}); options: CarouselOptions(
}, onPageChanged: (int index, CarouselPageChangedReason reason) {
height: widget.isShowResponse ? MediaQuery.of(context).size.height * 0.79 : MediaQuery.of(context).size.height * 0.85, setState(() {
enlargeCenterPage: true, currentIndex = index + 1;
scrollPhysics: const NeverScrollableScrollPhysics(), });
reverse: false, },
), height: widget.isShowResponse ? widget.orientation == Orientation.portrait ? MediaQuery.of(context).size.height * 0.79 : MediaQuery.of(context).size.height * 0.6 : MediaQuery.of(context).size.height * 0.78,
items: _questionsSubDTO.map<Widget>((i) { enlargeCenterPage: true,
return Builder( scrollPhysics: const NeverScrollableScrollPhysics(),
builder: (BuildContext context) { reverse: false,
return Padding( ),
padding: const EdgeInsets.only(left: 7.5, right: 7.5, bottom: 10.0, top: 8.0), items: _questionsSubDTO.map<Widget>((i) {
child: Container( return Builder(
width: MediaQuery.of(context).size.width, builder: (BuildContext context) {
// height: widget.isShowResponse ? MediaQuery.of(context).size.height *0.55 : MediaQuery.of(context).size.height, return Padding(
margin: const EdgeInsets.symmetric(horizontal: 1.5), padding: const EdgeInsets.only(left: 7.5, right: 7.5, bottom: 10.0, top: 8.0),
decoration: BoxDecoration( child: Container(
//color: Colors.orange, //kBackgroundLight width: MediaQuery.of(context).size.width,
shape: BoxShape.rectangle, // height: widget.isShowResponse ? MediaQuery.of(context).size.height *0.55 : MediaQuery.of(context).size.height,
borderRadius: BorderRadius.circular(20.0), margin: const EdgeInsets.symmetric(horizontal: 1.5),
image: i.source_ != null ? DecorationImage( decoration: BoxDecoration(
fit: BoxFit.cover, //color: Colors.orange, //kBackgroundLight
opacity: 0.35, shape: BoxShape.rectangle,
image: NetworkImage( borderRadius: BorderRadius.circular(20.0),
i.source_!, image: i.source_ != null ? DecorationImage(
fit: BoxFit.cover,
opacity: 0.35,
image: NetworkImage(
i.source_!,
),
): null,
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.5,
blurRadius: 5,
offset: Offset(0, 1.5), // changes position of shadow
),
],
), ),
): null, child: Column(
boxShadow: const [ //crossAxisAlignment: CrossAxisAlignment.center,
BoxShadow( //mainAxisAlignment: MainAxisAlignment.spaceEvenly,
color: kBackgroundSecondGrey, children: [
spreadRadius: 0.5, Container(
blurRadius: 5, //color: Colors.red,
offset: Offset(0, 1.5), // changes position of shadow //width: MediaQuery.of(context).size.width *0.65,
), height: MediaQuery.of(context).size.height *0.25,
], child: Stack(
), children: [
child: Column( Center(
//crossAxisAlignment: CrossAxisAlignment.center, child: Container(
//mainAxisAlignment: MainAxisAlignment.spaceEvenly, decoration: BoxDecoration(
children: [ color: kBackgroundLight, //kBackgroundLight
Container( shape: BoxShape.rectangle,
//color: Colors.red, borderRadius: BorderRadius.circular(10.0),
//width: MediaQuery.of(context).size.width *0.65, boxShadow: const [
height: MediaQuery.of(context).size.height *0.25, BoxShadow(
child: Stack( color: kBackgroundSecondGrey,
children: [ spreadRadius: 0.3,
Center( blurRadius: 4,
child: Container( offset: Offset(0, 2), // changes position of shadow
decoration: BoxDecoration( ),
color: kBackgroundLight, //kBackgroundLight ],
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
), ),
], width: MediaQuery.of(context).size.width *0.7,
), height: MediaQuery.of(context).size.height *0.2,
width: MediaQuery.of(context).size.width *0.7, child: Center(
height: MediaQuery.of(context).size.height *0.2, child: SingleChildScrollView(
child: Center( child: Padding(
child: SingleChildScrollView( padding: const EdgeInsets.all(2.5),
child: Padding( child: Text(TranslationHelper.get(i.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: const TextStyle(fontSize: kDescriptionSize)),
padding: const EdgeInsets.all(2.5), ),
child: Text(TranslationHelper.get(i.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: const TextStyle(fontSize: kDescriptionSize)),
),
),
),
)
),
]
),
),
/*SizedBox(
height: MediaQuery.of(context).size.height * 0.01,
),*/
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
//height: MediaQuery.of(context).size.height * 0.75,
width: MediaQuery.of(context).size.width * 0.72,
//color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1, // TODO HERE IS TABLET
mainAxisExtent: widget.isShowResponse ? 70 : 75, // TODO depends on percentage
mainAxisSpacing: widget.isShowResponse ? 35 : 42.5, // TODO depends on percentage
crossAxisSpacing: widget.isShowResponse ? 0 : 0, // TODO depends on percentage
),
itemCount: i.responsesSubDTO!.length,
itemBuilder: (BuildContext ctx, index) {
return InkWell(
onTap: () {
if(!widget.isShowResponse) {
setState(() {
i.chosen = index;
if(currentIndex == _questionsSubDTO.length && i.chosen == index)
{
widget.onShowResponse();
//showResult = true;
//_controllerCenter!.play(); // TODO Maybe show only confetti on super score ..
} else {
sliderController!.nextPage(duration: const Duration(milliseconds: 650), curve: Curves.fastOutSlowIn);
}
});
}
},
child: Padding(
padding: const EdgeInsets.all(2.5),
child: Container(
alignment: Alignment.center,
child: Text(TranslationHelper.get(i.responsesSubDTO![index].label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black)),
decoration: BoxDecoration(
color: !widget.isShowResponse ? i.chosen == index ? kTestSecondColor : kBackgroundLight : i.responsesSubDTO![index].isGood! ? kGreen : i.chosen == index ? kTextRed : kBackgroundLight,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
),
],
), ),
), ),
), )
); ),
}), ]
), ),
), ),
), /*SizedBox(
), height: MediaQuery.of(context).size.height * 0.01,
], ),*/
) Expanded(
), child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
//height: MediaQuery.of(context).size.height * 0.75,
width: MediaQuery.of(context).size.width * 0.72,
//color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: widget.orientation == Orientation.portrait ? 1 : 2, // TODO HERE IS TABLET
mainAxisExtent: widget.isShowResponse ? widget.orientation == Orientation.portrait ? 70 : 50 : 65, // TODO depends on percentage
mainAxisSpacing: widget.isShowResponse ? widget.orientation == Orientation.portrait ? 35 : 10 : 42.5, // TODO depends on percentage
crossAxisSpacing: widget.isShowResponse ? 0 : 0, // TODO depends on percentage
),
itemCount: i.responsesSubDTO!.length,
itemBuilder: (BuildContext ctx, index) {
return InkWell(
onTap: () {
if(!widget.isShowResponse) {
setState(() {
i.chosen = index;
if(currentIndex == _questionsSubDTO.length && i.chosen == index)
{
widget.onShowResponse();
//showResult = true;
//_controllerCenter!.play(); // TODO Maybe show only confetti on super score ..
} else {
sliderController!.nextPage(duration: const Duration(milliseconds: 650), curve: Curves.fastOutSlowIn);
}
});
}
},
child: Padding(
padding: const EdgeInsets.all(2.5),
child: Container(
alignment: Alignment.center,
child: Text(TranslationHelper.get(i.responsesSubDTO![index].label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black)),
decoration: BoxDecoration(
color: !widget.isShowResponse ? i.chosen == index ? kTestSecondColor : kBackgroundLight : i.responsesSubDTO![index].isGood! ? kGreen : i.chosen == index ? kTextRed : kBackgroundLight,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
),
],
),
),
),
);
}),
),
),
),
),
],
)
),
);
},
); );
}, }).toList(),
); ),
}).toList(), ],
), ),
], if(widget.questionsSubDTO!.isNotEmpty && _questionsSubDTO.length > 1 && currentIndex != _questionsSubDTO.length && _questionsSubDTO[currentIndex-1].chosen != null)
), Positioned(
if(widget.questionsSubDTO!.isNotEmpty && _questionsSubDTO.length > 1 && currentIndex != _questionsSubDTO.length && _questionsSubDTO[currentIndex-1].chosen != null) top: widget.orientation == Orientation.portrait ? MediaQuery.of(context).size.height * 0.38 : MediaQuery.of(context).size.height * 0.325,
Positioned( right: widget.orientation == Orientation.portrait ? -9 : 25,
top: MediaQuery.of(context).size.height * 0.38,
right: -9,
child: InkWell(
onTap: () {
if( _questionsSubDTO.isNotEmpty && _questionsSubDTO[currentIndex-1].chosen != null) {
sliderController!.nextPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
}
},
child: const Icon(
Icons.chevron_right,
size: 75,
color: kMainColor,
),
)
),
if(_questionsSubDTO.length > 1 && currentIndex != 1)
Positioned(
top: MediaQuery.of(context).size.height * 0.38,
left: -9,
child: InkWell(
onTap: () {
if(currentIndex > 1) {
sliderController!.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
}
},
child: const Icon(
Icons.chevron_left,
size: 75,
color: kMainColor,
),
)
),
if(_questionsSubDTO.isNotEmpty)
Positioned.fill(
child: Padding(
padding: EdgeInsets.only(bottom: widget.isShowResponse ? 0 : 0),
child: Align(
alignment: Alignment.bottomCenter,
child: InkWell( child: InkWell(
child: Text( onTap: () {
currentIndex.toString()+'/'+widget.questionsSubDTO!.length.toString(), if( _questionsSubDTO.isNotEmpty && _questionsSubDTO[currentIndex-1].chosen != null) {
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w500), sliderController!.nextPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
}
},
child: const Icon(
Icons.chevron_right,
size: 75,
color: kMainColor,
), ),
) )
), ),
), if(_questionsSubDTO.length > 1 && currentIndex != 1)
), Positioned(
if(_questionsSubDTO.isEmpty) top: widget.orientation == Orientation.portrait ? MediaQuery.of(context).size.height * 0.38 : MediaQuery.of(context).size.height * 0.325,
const Center( left: widget.orientation == Orientation.portrait ? -9 : 25,
child: Text( child: InkWell(
"Aucune question à afficher", onTap: () {
style: TextStyle(fontSize: kNoneInfoOrIncorrect), if(currentIndex > 1) {
textAlign: TextAlign.center sliderController!.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
), }
) },
] child: const Icon(
), Icons.chevron_left,
); size: 75,
color: kMainColor,
),
)
),
if(_questionsSubDTO.isNotEmpty)
Positioned.fill(
child: Padding(
padding: EdgeInsets.only(bottom: widget.isShowResponse ? 0 : 0),
child: Align(
alignment: Alignment.bottomCenter,
child: InkWell(
child: Text(
currentIndex.toString()+'/'+widget.questionsSubDTO!.length.toString(),
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
),
)
),
),
),
if(_questionsSubDTO.isEmpty)
const Center(
child: Text(
"Aucune question à afficher",
style: TextStyle(fontSize: kNoneInfoOrIncorrect),
textAlign: TextAlign.center
),
)
]
),
);
/*}
)*/;
} }
} }

View File

@ -3,7 +3,7 @@ import 'dart:developer';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:carousel_slider/carousel_slider.dart'; import 'package:carousel_slider/carousel_slider.dart';
import 'package:confetti/confetti.dart'; //import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_api/api.dart'; import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
@ -15,9 +15,9 @@ import 'package:mymuseum_visitapp/Models/ResponseSubDTO.dart';
import 'package:mymuseum_visitapp/Models/articleRead.dart'; import 'package:mymuseum_visitapp/Models/articleRead.dart';
import 'package:mymuseum_visitapp/Models/resourceModel.dart'; import 'package:mymuseum_visitapp/Models/resourceModel.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart'; import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/Screens/Quizz/drawPath.dart'; //import 'package:mymuseum_visitapp/Screens/Quizz/drawPath.dart';
import 'package:mymuseum_visitapp/Screens/Quizz/questions_list.dart'; import 'package:mymuseum_visitapp/Screens/Quizz/questions_list.dart';
import 'package:mymuseum_visitapp/Screens/Quizz/showResponses.dart'; //import 'package:mymuseum_visitapp/Screens/Quizz/showResponses.dart';
import 'package:mymuseum_visitapp/app_context.dart'; import 'package:mymuseum_visitapp/app_context.dart';
import 'package:mymuseum_visitapp/client.dart'; import 'package:mymuseum_visitapp/client.dart';
import 'package:mymuseum_visitapp/constants.dart'; import 'package:mymuseum_visitapp/constants.dart';
@ -89,590 +89,141 @@ class _QuizzPageState extends State<QuizzPage> {
title: sectionDTO != null ? TranslationHelper.get(sectionDTO!.title, visitAppContext!) : "", title: sectionDTO != null ? TranslationHelper.get(sectionDTO!.title, visitAppContext!) : "",
isHomeButton: false, isHomeButton: false,
), ),
body: FutureBuilder( body: OrientationBuilder(
future: getQuizz(appContext, appContext.clientAPI, widget.sectionId), // MAYBE MOVE THAT TO PARENT .. builder: (context, orientation) {
builder: (context, AsyncSnapshot<dynamic> snapshot) { return FutureBuilder(
if(quizzDTO != null && sectionDTO != null) { future: getQuizz(appContext, appContext.clientAPI, widget.sectionId), // MAYBE MOVE THAT TO PARENT ..
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if(quizzDTO != null && sectionDTO != null) {
if(showResult) { if(showResult) {
var goodResponses = 0; var goodResponses = 0;
for (var question in _questionsSubDTO) { for (var question in _questionsSubDTO) {
if(question.chosen == question.responsesSubDTO!.indexWhere((response) => response.isGood!)) { if(question.chosen == question.responsesSubDTO!.indexWhere((response) => response.isGood!)) {
goodResponses +=1; goodResponses +=1;
} }
} }
log("goodResponses =" + goodResponses.toString()); log("goodResponses =" + goodResponses.toString());
QuizzDTOBadLevel levelToShow = QuizzDTOBadLevel(); QuizzDTOBadLevel levelToShow = QuizzDTOBadLevel();
var test = goodResponses/quizzDTO!.questions!.length; var test = goodResponses/quizzDTO!.questions!.length;
if((0 == test || test < 0.25) && quizzDTO!.badLevel != null) { if((0 == test || test < 0.25) && quizzDTO!.badLevel != null) {
levelToShow = quizzDTO!.badLevel!; levelToShow = quizzDTO!.badLevel!;
} }
if((test>=0.25 && test < 0.5) && quizzDTO!.mediumLevel != null) { if((test>=0.25 && test < 0.5) && quizzDTO!.mediumLevel != null) {
levelToShow = quizzDTO!.mediumLevel!; levelToShow = quizzDTO!.mediumLevel!;
} }
if((test>=0.5 && test < 0.75) && quizzDTO!.goodLevel != null) { if((test>=0.5 && test < 0.75) && quizzDTO!.goodLevel != null) {
levelToShow = quizzDTO!.goodLevel!; levelToShow = quizzDTO!.goodLevel!;
} }
if((test>=0.75 && test <= 1) && quizzDTO!.greatLevel != null) { if((test>=0.75 && test <= 1) && quizzDTO!.greatLevel != null) {
levelToShow = quizzDTO!.greatLevel!; levelToShow = quizzDTO!.greatLevel!;
} }
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
/*Center( /*Center(
child: SizedBox( child: SizedBox(
width: 5, width: 5,
height: 5, height: 5,
child: ConfettiWidget( child: ConfettiWidget(
confettiController: _controllerCenter!, confettiController: _controllerCenter!,
blastDirectionality: BlastDirectionality.explosive, blastDirectionality: BlastDirectionality.explosive,
shouldLoop: false, // start again as soon as the animation is finished shouldLoop: false, // start again as soon as the animation is finished
colors: const [ colors: const [
kMainColor, kMainColor,
kSecondColor, kSecondColor,
kConfigurationColor, kConfigurationColor,
kTestSecondColor kTestSecondColor
//Colors.pink, //Colors.pink,
//Colors.orange, //Colors.orange,
//Colors.purple //Colors.purple
], // manually specify the colors to be used ], // manually specify the colors to be used
createParticlePath: drawPath, // define a custom shape/path. createParticlePath: drawPath, // define a custom shape/path.
),
),
),*/
if (!showResponses && levelToShow.source_ != null)
Container(
//height: size.height * 0.2,
//width: size.width * 0.25,
constraints: BoxConstraints(
maxHeight: size.height * 0.25,
maxWidth: kIsWeb ? size.width * 0.20 : size.width * 0.85,
),
alignment: Alignment.center,
decoration: BoxDecoration(
image: levelToShow.source_ != null ? DecorationImage(
fit: BoxFit.contain,
opacity: 0.85,
image: NetworkImage(
levelToShow.source_!,
),
): null,
borderRadius: const BorderRadius.all( Radius.circular(50.0)),
border: Border.all(
color: kBackgroundGrey,
width: 1.0,
),
),
child: Container(
//borderRadius: BorderRadius.all(Radius.circular(25.0)),
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
image: DecorationImage(
image: NetworkImage(
levelToShow.source_!,
),
fit: BoxFit.cover,
),
borderRadius: const BorderRadius.all( Radius.circular(50.0)),
border: Border.all(
color: kBackgroundGrey,
width: 1.0,
), ),
), ),
), ),*/
), if (orientation == Orientation.portrait)
if(!showResponses) Column(
// TEXT BOX WITH MAIN SCORE children: [
Text('$goodResponses/${quizzDTO!.questions!.length}', textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? (showResponses ? 60 : 100) : 75, color: kBackgroundSecondGrey)), if (!showResponses && levelToShow.source_ != null)
if(!showResponses) resultImage(size, levelToShow, orientation),
// TEXT BOX WITH LEVEL TEXT RESULT if(!showResponses)
Padding( // TEXT BOX WITH MAIN SCORE
padding: const EdgeInsets.only(bottom: 10), Text('$goodResponses/${quizzDTO!.questions!.length}', textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? (showResponses ? 60 : 100) : 75, color: kBackgroundSecondGrey)),
child: Container(
width: MediaQuery.of(context).size.width *0.75,
height: kIsWeb ? (showResponses ? MediaQuery.of(context).size.height *0.10 : MediaQuery.of(context).size.height *0.20) : MediaQuery.of(context).size.height *0.25,
decoration: BoxDecoration(
color: kBackgroundLight, //kBackgroundLight
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
),
], ],
), ),
child: Center(
child: SizedBox( if (orientation == Orientation.landscape)
width: double.infinity, Row(
child: SingleChildScrollView( crossAxisAlignment: CrossAxisAlignment.center,
child: Padding( mainAxisAlignment: MainAxisAlignment.spaceEvenly,
padding: const EdgeInsets.all(15.0), children: [
child: Text(TranslationHelper.get(levelToShow.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? kDescriptionSize : kDescriptionSize)), if(!showResponses)
), // TEXT BOX WITH MAIN SCORE
), Text('$goodResponses/${quizzDTO!.questions!.length}', textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? (showResponses ? 60 : 100) : 75, color: kBackgroundSecondGrey)),
), if (!showResponses && levelToShow.source_ != null)
resultImage(size, levelToShow, orientation),
],
), ),
),
),
if(showResponses)
QuestionsListWidget(
questionsSubDTO: _questionsSubDTO,
isShowResponse: true,
onShowResponse: () {}
),
// RESPONSE BOX
//ShowReponsesWidget(questionsSubDTO: _questionsSubDTO),
// Buttons
Column( // TABLET IS ROW
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(4),
child: SizedBox(
height: kIsWeb ? 50 : 50,
width: size.width * 0.6,
child: RoundedButton(
text: "Recommencer",
color: kBackgroundSecondGrey,
textColor: kBackgroundLight,
icon: Icons.undo,
press: () {
setState(() {
showResult = false;
showResponses = false;
currentIndex = 1;
_questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!);
});
},
fontSize: 18,
horizontal: 20,
vertical: 5
),
),
),
if(!showResponses) if(!showResponses)
Padding( // TEXT BOX WITH LEVEL TEXT RESULT
padding: const EdgeInsets.all(4.0), resultText(size, levelToShow, appContext),
child: SizedBox( if(showResponses)
height: kIsWeb ? 50 : 50, QuestionsListWidget(
width: size.width * 0.6, questionsSubDTO: _questionsSubDTO,
child: RoundedButton( isShowResponse: true,
text: "Voir les réponses", onShowResponse: () {},
color: kBackgroundSecondGrey, orientation: orientation,
textColor: kBackgroundLight, ),
icon: Icons.assignment_turned_in, // RESPONSE BOX
press: () { //ShowReponsesWidget(questionsSubDTO: _questionsSubDTO),
setState(() {
showResponses = true;
});
},
fontSize: 18,
horizontal: 20,
vertical: 5
),
),
)
],
),
],
),
);
} else { if(orientation == Orientation.portrait)
return QuestionsListWidget( // Buttons
isShowResponse: false, Column(
questionsSubDTO: _questionsSubDTO, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
onShowResponse: () { crossAxisAlignment: CrossAxisAlignment.center,
setState(() { children: resultButtons(size, orientation),
showResult = true; ),
}); if(orientation == Orientation.landscape)
} // Buttons
); Row(
/*return Stack( mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ crossAxisAlignment: CrossAxisAlignment.center,
Column( children: resultButtons(size, orientation),
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if(_questionsSubDTO.isNotEmpty)
CarouselSlider(
carouselController: sliderController,
options: CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) {
setState(() {
currentIndex = index + 1;
});
},
height: MediaQuery.of(context).size.height * 0.85,
enlargeCenterPage: true,
scrollPhysics: const NeverScrollableScrollPhysics(),
reverse: false,
),
items: _questionsSubDTO.map<Widget>((i) {
return Builder(
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 1.0, right: 1.0, bottom: 15.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
margin: const EdgeInsets.symmetric(horizontal: 1.5),
decoration: BoxDecoration(
//color: Colors.orange, //kBackgroundLight
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(20.0),
image: i.source_ != null ? DecorationImage(
fit: BoxFit.cover,
opacity: 0.35,
image: NetworkImage(
i.source_!,
),
): null,
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.5,
blurRadius: 5,
offset: Offset(0, 1.5), // changes position of shadow
),
],
),
child: Column(
//crossAxisAlignment: CrossAxisAlignment.center,
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(
//color: Colors.red,
//width: MediaQuery.of(context).size.width *0.65,
height: MediaQuery.of(context).size.height *0.25,
child: Stack(
children: [
Center(
child: Container(
decoration: BoxDecoration(
color: kBackgroundLight, //kBackgroundLight
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
),
],
),
width: MediaQuery.of(context).size.width *0.7,
height: MediaQuery.of(context).size.height *0.2,
child: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(2.5),
child: Text(TranslationHelper.get(i.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: const TextStyle(fontSize: kDescriptionSize)),
),
),
),
)
),
]
),
),
/*SizedBox(
height: MediaQuery.of(context).size.height * 0.01,
),*/
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
//height: MediaQuery.of(context).size.height * 0.75,
width: MediaQuery.of(context).size.width * 0.72,
//color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1, // TODO HERE IS TABLET
mainAxisExtent: kIsWeb ? 75 : 75, // TODO depends on percentage
mainAxisSpacing: kIsWeb ? 75 : 42.5, // TODO depends on percentage
crossAxisSpacing: kIsWeb ? 75 : 0, // TODO depends on percentage
),
itemCount: i.responsesSubDTO!.length,
itemBuilder: (BuildContext ctx, index) {
return InkWell(
onTap: () {
print("COUCOU");
setState(() {
i.chosen = index;
if(currentIndex == _questionsSubDTO.length && i.chosen == index)
{
showResult = true;
//_controllerCenter!.play(); // TODO Maybe show only confetti on super score ..
} else {
sliderController!.nextPage(duration: const Duration(milliseconds: 650), curve: Curves.fastOutSlowIn);
}
});
},
child: Padding(
padding: const EdgeInsets.all(2.5),
child: Container(
alignment: Alignment.center,
child: Text(TranslationHelper.get(i.responsesSubDTO![index].label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black)),
decoration: BoxDecoration(
color: i.chosen == index ? kTestSecondColor : kBackgroundLight,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
),
],
),
),
),
);
}),
),
),
),
),
],
)
),
);
},
);
}).toList(),
), ),
], ],
), ),
if(_questionsSubDTO.length > 1 && currentIndex != _questionsSubDTO.length && _questionsSubDTO[currentIndex-1].chosen != null && quizzDTO!.questions!.isNotEmpty) );
Positioned(
top: MediaQuery.of(context).size.height * 0.35,
right: 60,
child: InkWell(
onTap: () {
if(_questionsSubDTO[currentIndex-1].chosen != null && quizzDTO!.questions!.isNotEmpty) {
sliderController!.nextPage(duration: Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
/*Fluttertoast.showToast(
msg: "Vous n'avez pas répondu à cette question",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: kMainRed,
textColor: Colors.white,
fontSize: 35.0
);*/
}
},
child: Icon(
Icons.chevron_right,
size: kIsWeb ? 100 : 150,
color: kMainColor,
),
)
),
if(_questionsSubDTO.length > 1 && currentIndex != 1)
Positioned(
top: MediaQuery.of(context).size.height * 0.35,
left: 60,
child: InkWell(
onTap: () {
if(currentIndex > 1) {
sliderController!.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
}
},
child: Icon(
Icons.chevron_left,
size: kIsWeb ? 100 : 150,
color: kMainColor,
),
)
),
if(_questionsSubDTO.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 0),
child: Align(
alignment: Alignment.bottomCenter,
child: InkWell(
child: Text(
currentIndex.toString()+'/'+quizzDTO!.questions!.length.toString(),
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
),
)
),
),
if(_questionsSubDTO.isEmpty)
const Center(
child:
Text("Aucune question à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect), textAlign: TextAlign.center),
)
]
);*/
}
/*if(size.height > size.width) { } else {
return Column( return QuestionsListWidget(
children: [ isShowResponse: false,
Text("TODO show QUESTION THEN COLUMN WITH ALL RESPONSE") questionsSubDTO: _questionsSubDTO,
], onShowResponse: () {
); setState(() {
} else { showResult = true;
return Container( });
height: size.height, },
width: size.width, orientation: orientation,
child: Column( );
children: [ }
Text("TODO show QUESTION THEN GRID LIKE IN TABLET") } else {
], return const Loading();
), }
); }
}*/ );
} else {
return const Loading();
}
} }
), ),
//floatingActionButton: const ScannerBouton(isReplacement: true),
); );
} }
/*Widget getImages(Size size, bool isContentTop) {
if(size.width > size.height) {
return SizedBox(
width: size.width *0.5,
height: size.height * 0.75,
child: Padding(
padding: isContentTop ? const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0): const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: kBlue2,
width: 0.5,
),
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
boxShadow: const [kDefaultShadow],
),
child: SliderImagesWidget(
resources: resourcesModel,
height: size.height * 0.29,
imagesDTO: quizzDTO!.images!,
)
)
)
);
} else {
return SizedBox(
width: size.width,
height: size.height * 0.3,
child: Padding(
padding: isContentTop ? const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0): const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: kBlue2,
width: 0.5,
),
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
boxShadow: const [kDefaultShadow],
),
child: SliderImagesWidget(
resources: resourcesModel,
height: size.height * 0.29,
imagesDTO: articleDTO!.images!,
)
)
)
);
}
}
*/
/*Widget getContent(Size size, AppContext appContext) {
if(size.width > size.height) {
return SingleChildScrollView(
child: Container(
width: size.width *0.5,
height: size.height * 0.76,
//color: Colors.blueAccent,
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0, bottom: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: kBlue2,
width: 0.5,
),
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
boxShadow: const [kDefaultShadow],
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
TranslationHelper.get(articleDTO!.content, appContext.getContext()),
textAlign: TextAlign.left,
style: const TextStyle(fontSize: kArticleContentSize)
),
),
)
)
)
),
);
} else {
return Expanded(
child: Container(
width: size.width,
//height: size.height * 0.65,
//color: Colors.blueAccent,
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0, bottom: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: kBlue2,
width: 0.5,
),
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
boxShadow: const [kDefaultShadow],
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
TranslationHelper.get(articleDTO!.content, appContext.getContext()),
textAlign: TextAlign.left,
style: const TextStyle(fontSize: kArticleContentSize)
),
),
)
)
)
),
);
}
}*/
Future<QuizzDTO?> getQuizz(AppContext appContext, Client client, String sectionId) async { Future<QuizzDTO?> getQuizz(AppContext appContext, Client client, String sectionId) async {
try { try {
if(sectionDTO == null || quizzDTO == null) { if(sectionDTO == null || quizzDTO == null) {
@ -715,35 +266,6 @@ class _QuizzPageState extends State<QuizzPage> {
_questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!); _questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!);
if(quizzDTO!.questions != null && quizzDTO!.questions!.isNotEmpty) { if(quizzDTO!.questions != null && quizzDTO!.questions!.isNotEmpty) {
quizzDTO!.questions!.sort((a, b) => a.order!.compareTo(b.order!)); quizzDTO!.questions!.sort((a, b) => a.order!.compareTo(b.order!));
/*var audioIdArticle = articleDTO!.audioIds!.where((audioId) => audioId.language == (appContext.getContext() as VisitAppContext).language);
if(audioIdArticle.isNotEmpty && audioIdArticle.first.value != null) {
if(isConfigOffline)
{
// OFFLINE
List<Map<String, dynamic>> ressourceTest = await DatabaseHelper
.instance.queryWithColumnId(
DatabaseTableType.resources, audioIdArticle.first.value!);
if (ressourceTest.isNotEmpty) {
audioResourceModel = DatabaseHelper.instance.getResourceFromDB(ressourceTest.first);
Uint8List base64String = base64Decode(audioResourceModel!.data!);
audiobytes = base64String;
} else {
print("EMPTY resourcesModel - first");
}
}
else
{
// ONLINE
ResourceModel? resourceAudioOnline = await ApiService.downloadAudio(client, audioIdArticle.first.value!);
if(resourceAudioOnline != null) {
audioResourceModel = resourceAudioOnline;
Uint8List base64String = base64Decode(resourceAudioOnline.data!);
audiobytes = base64String;
} else {
print("EMPTY resourcesModel online - audio");
}
}
}*/
for (var question in quizzDTO!.questions!) { for (var question in quizzDTO!.questions!) {
if(isConfigOffline) if(isConfigOffline)
{ {
@ -780,4 +302,132 @@ class _QuizzPageState extends State<QuizzPage> {
return null; return null;
} }
} }
resultImage(Size size, QuizzDTOBadLevel levelToShow, Orientation orientation) {
return Container(
//height: size.height * 0.2,
//width: size.width * 0.25,
constraints: BoxConstraints(
maxHeight: size.height * 0.25,
maxWidth: kIsWeb ? size.width * 0.20 : orientation == Orientation.portrait ? size.width * 0.85 : size.width * 0.4,
),
alignment: Alignment.center,
decoration: BoxDecoration(
image: levelToShow.source_ != null ? DecorationImage(
fit: BoxFit.contain,
opacity: 0.85,
image: NetworkImage(
levelToShow.source_!,
),
): null,
borderRadius: const BorderRadius.all( Radius.circular(50.0)),
border: Border.all(
color: kBackgroundGrey,
width: 1.0,
),
),
child: Container(
//borderRadius: BorderRadius.all(Radius.circular(25.0)),
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
image: DecorationImage(
image: NetworkImage(
levelToShow.source_!,
),
fit: BoxFit.cover,
),
borderRadius: const BorderRadius.all( Radius.circular(50.0)),
border: Border.all(
color: kBackgroundGrey,
width: 1.0,
),
),
),
);
}
resultText(Size size, QuizzDTOBadLevel levelToShow, AppContext appContext) {
return Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
width: size.width *0.75,
height: kIsWeb ? (showResponses ? size.height *0.10 : size.height *0.20) : size.height *0.25,
decoration: BoxDecoration(
color: kBackgroundLight, //kBackgroundLight
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
boxShadow: const [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.3,
blurRadius: 4,
offset: Offset(0, 2), // changes position of shadow
),
],
),
child: Center(
child: SizedBox(
width: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Text(TranslationHelper.get(levelToShow.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? kDescriptionSize : kDescriptionSize)),
),
),
),
),
),
);
}
resultButtons(Size size, Orientation orientation) {
return [
Padding(
padding: const EdgeInsets.all(4),
child: SizedBox(
height: kIsWeb ? 50 : 50,
width: orientation == Orientation.portrait ? size.width * 0.6 : size.width * 0.3,
child: RoundedButton(
text: "Recommencer",
color: kBackgroundSecondGrey,
textColor: kBackgroundLight,
icon: Icons.undo,
press: () {
setState(() {
showResult = false;
showResponses = false;
currentIndex = 1;
_questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!);
});
},
fontSize: 18,
horizontal: 20,
vertical: 5
),
),
),
if(!showResponses)
Padding(
padding: const EdgeInsets.all(4.0),
child: SizedBox(
height: kIsWeb ? 50 : 50,
width: orientation == Orientation.portrait ? size.width * 0.6 : size.width * 0.3,
child: RoundedButton(
text: "Voir les réponses",
color: kBackgroundSecondGrey,
textColor: kBackgroundLight,
icon: Icons.assignment_turned_in,
press: () {
setState(() {
showResponses = true;
});
},
fontSize: 18,
horizontal: 20,
vertical: 5
),
),
)
];
}
} }

View File

@ -35,7 +35,7 @@ class _VisitPageState extends State<VisitPage> with WidgetsBindingObserver {
ConfigurationDTO? configuration; ConfigurationDTO? configuration;
int timeBetweenBeaconPopUp = 20000; // 20 sec int timeBetweenBeaconPopUp = 20000; // 20 sec
int meterToBeacon = 15; // 15 meters int meterToBeacon = 100; // 15 meters
bool modeDebugBeacon = true; bool modeDebugBeacon = true;
// Beacon specific // Beacon specific