Lot K : tablet-app reconstruit et rebranché sur le contrat Postgres v3
Premier vrai build depuis avril. Le diagnostic des docs — « un seul défaut, purement Gradle, peut-être réglé par 5a6701d » — tenait parce que personne n'avait lancé la commande. K1 — dix crans d'outillage, chacun dicté par l'erreur du précédent : Gradle 7.5 → 8.11.1, AGP 7.2.0 → 8.9.1, Kotlin 1.9.0 → 2.3.10, enableUncompressedNativeLibs retirée (supprimée en AGP 8.1), jcenter → mavenCentral, heap 1536M → 4096M, Jetifier coupé, et retrait du resolutionStrategy qui forçait androidx.lifecycle à 2.4.0 « to fix mapbox issue » : il réglait un problème d'il y a trois ans et causait celui d'aujourd'hui, mapbox_maps_flutter 2.21.1 appelant setViewTreeLifecycleOwner. Les trois derniers crans étaient de simples alignements sur mymuseum-visitapp, qui utilise le même plugin sans ces problèmes. Le bloc buildscript commenté de android/build.gradle est supprimé : il déclarait une config qui n'était pas celle appliquée et a fait conclure deux fois à tort. K2 — les 132 erreurs Dart que le Gradle masquait. Trois causes : roundedValue, isDate, isHour, isSectionImageBackground et screenPercentageSectionsMainPage ont migré vers AppConfigurationLink ; GeoPointDTO.latitude/longitude sont devenus geometry ; le reste en découlait. Deux bugs latents trouvés au passage : - applicationInstanceDTO n'était assigné que si l'instance avait l'IA — il servait de drapeau d'assistant. Ce DTO portant désormais les AppConfigurationLink, les cinq réglages seraient retombés sur leurs défauts sur MDLF et le Fort, sans erreur ni log. Drapeau rendu explicite, en préservant le ET instance × canal. - ConfigurationDTO.isTablet ayant disparu, le filtre des configurations tablette n'avait plus de source : il porte sur les liens du canal AppType.Tablet. La formule de clé par coordonnées de geo_point_filter, dupliquée à quatre endroits alors que les deux côtés de l'appariement doivent produire la même valeur, ne vit plus qu'à un seul (Helpers/geo.dart). Ce fichier documente aussi les deux conventions de coordonnées du projet : [lng, lat] pour les GeoPoint, [lat, lng] pour les géométries de GuidedStep. K4 — l'écran Game repris de mymuseum-visitapp, Screens/Puzzle supprimé. La tablette gagne le puzzle glissant, le bouton d'indice et un dimensionnement au ratio de l'image. Les couleurs, codées en dur par flavor client chez mymuseum, sont dérivées de configuration.primaryColor : tablet-app n'a pas de flavor, un seul APK sert tous les clients. Reste à vérifier sur device : le rendu de l'écran Game, et l'écran de sélection de configuration, qui sera vide si les configurations ne sont pas rattachées au canal tablette. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6a23c6ab6d
commit
9f582dd8a7
3
.gitignore
vendored
3
.gitignore
vendored
@ -45,3 +45,6 @@ app.*.map.json
|
|||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
pubspec.lock
|
pubspec.lock
|
||||||
|
|
||||||
|
# AGP 8 écrit ses rapports ici malgré rootProject.buildDir = ../build
|
||||||
|
/android/build/
|
||||||
|
|||||||
@ -1,21 +1,11 @@
|
|||||||
/*buildscript {
|
// Les versions d'AGP et du plugin Kotlin sont déclarées dans settings.gradle.
|
||||||
ext.kotlin_version = '2.0.10'
|
// Un buildscript commenté les redéclarait ici : il a fait conclure deux fois à
|
||||||
repositories {
|
// une config qui n'était pas celle appliquée. Supprimé plutôt que laissé mort.
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:8.5.0'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
classpath 'com.google.gms:google-services:4.3.15'
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,16 +13,10 @@ rootProject.buildDir = '../build'
|
|||||||
subprojects {
|
subprojects {
|
||||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||||
}
|
}
|
||||||
subprojects {
|
// Un resolutionStrategy forçait ici androidx.lifecycle à 2.4.0, commenté
|
||||||
//project.evaluationDependsOn(':app')
|
// « To fix mapbox issue ». C'est devenu la cause du problème inverse : mapbox_maps_flutter
|
||||||
project.configurations.all {
|
// 2.21.1 appelle setViewTreeLifecycleOwner, absent de 2.4.0, et sa compilation Kotlin
|
||||||
resolutionStrategy.eachDependency { details ->
|
// échouait. mymuseum-visitapp utilise le même plugin sans ce forçage. Retiré le 2026-08-12.
|
||||||
if (details.requested.group == 'androidx.lifecycle') {
|
|
||||||
details.useVersion '2.4.0' // To fix mapbox issue..
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register("clean", Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx4096M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=false
|
||||||
android.enableR8=true
|
android.enableR8=true
|
||||||
SDK_REGISTRY_TOKEN=sk.eyJ1IjoidGZyYW5zb2xldCIsImEiOiJjbHRpcTF1d28wYmxmMmxwNjRleXpodGY0In0.qr-jo1vAb08bL3WRDEB4pw
|
SDK_REGISTRY_TOKEN=sk.eyJ1IjoidGZyYW5zb2xldCIsImEiOiJjbHRpcTF1d28wYmxmMmxwNjRleXpodGY0In0.qr-jo1vAb08bL3WRDEB4pw
|
||||||
android.bundle.enableUncompressedNativeLibs=false
|
|
||||||
android.experimental.enable16kApk=true
|
android.experimental.enable16kApk=true
|
||||||
android.useNewNativePlugin=true
|
android.useNewNativePlugin=true
|
||||||
# This builtInKotlin flag was added automatically by Flutter migrator
|
# This builtInKotlin flag was added automatically by Flutter migrator
|
||||||
|
|||||||
@ -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.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||||
|
|||||||
@ -18,9 +18,9 @@ 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.9.1' apply false
|
||||||
id 'com.android.library' version '7.2.0' apply false
|
id 'com.android.library' version '8.9.1' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
|
id 'org.jetbrains.kotlin.android' version '2.3.10' apply false
|
||||||
id "com.google.gms.google-services" version "4.3.15" apply false
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
id "com.google.firebase.crashlytics" version "2.9.9" apply false
|
id "com.google.firebase.crashlytics" version "2.9.9" apply false
|
||||||
/*id "com.google.firebase:firebase-bom" version "32.7.0"
|
/*id "com.google.firebase:firebase-bom" version "32.7.0"
|
||||||
|
|||||||
@ -37,7 +37,7 @@ class RoundedButton extends StatelessWidget {
|
|||||||
backgroundColor: MaterialStateColor.resolveWith((states) => color!),
|
backgroundColor: MaterialStateColor.resolveWith((states) => color!),
|
||||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration?.roundedValue?.toDouble() ?? 20.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|||||||
46
lib/Helpers/geo.dart
Normal file
46
lib/Helpers/geo.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:manager_api_new/api.dart';
|
||||||
|
|
||||||
|
/// GeoPointDTO ne porte plus `latitude`/`longitude` depuis le passage à PostGIS :
|
||||||
|
/// la position vit dans `geometry.coordinates`, que `GeometryMapper` sérialise
|
||||||
|
/// côté serveur sous la forme `[X, Y]` — donc **[longitude, latitude]**, l'ordre
|
||||||
|
/// GeoJSON. C'est aussi ce que lit mymuseum-visitapp (`Models/agenda.dart`).
|
||||||
|
///
|
||||||
|
/// ⚠️ Ne pas généraliser aux géométries de GuidedStep : celles-là sont écrites
|
||||||
|
/// par manager-app dans l'ordre inverse, `[lat, lng]` (cf. `visitapp-web/src/lib/geo.ts`).
|
||||||
|
extension GeoPointPosition on GeoPointDTO {
|
||||||
|
double? get lat => _coordinate(1);
|
||||||
|
|
||||||
|
double? get lng => _coordinate(0);
|
||||||
|
|
||||||
|
/// Clé numérique dérivée des coordonnées, utilisée par `geo_point_filter` pour
|
||||||
|
/// apparier un `TreeNode` et son GeoPoint (l'`id` du DTO ne convient pas : il est
|
||||||
|
/// réattribué à la volée à l'affichage).
|
||||||
|
///
|
||||||
|
/// Formule reprise telle quelle de l'ancien code — représentation textuelle
|
||||||
|
/// tronquée à 10 caractères, points et signes retirés. Elle n'est pas persistée,
|
||||||
|
/// mais **les deux côtés de l'appariement doivent produire la même valeur** : elle
|
||||||
|
/// était dupliquée à quatre endroits, elle ne vit plus qu'ici.
|
||||||
|
int get coordinateKey {
|
||||||
|
String part(double? value) {
|
||||||
|
if (value == null) return '0';
|
||||||
|
final text = value.toString();
|
||||||
|
return text
|
||||||
|
.substring(0, min(text.length, 10))
|
||||||
|
.replaceAll('.', '')
|
||||||
|
.replaceAll('-', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return int.parse(part(lat) + part(lng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `coordinates` est typé `Object?` dans le client généré : sans ce narrowing,
|
||||||
|
/// tout calcul dessus part en `dynamic` et casse à la compilation.
|
||||||
|
double? _coordinate(int index) {
|
||||||
|
final coordinates = geometry?.coordinates;
|
||||||
|
if (coordinates is! List || coordinates.length <= index) return null;
|
||||||
|
final value = coordinates[index];
|
||||||
|
return value is num ? value.toDouble() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,24 @@ class TabletAppContext with ChangeNotifier{
|
|||||||
ApplicationInstanceDTO? applicationInstanceDTO;
|
ApplicationInstanceDTO? applicationInstanceDTO;
|
||||||
StatisticsService? statisticsService;
|
StatisticsService? statisticsService;
|
||||||
|
|
||||||
|
/// L'assistant demande deux feux verts : l'instance et le canal tablette.
|
||||||
|
/// Avant Postgres v3, `applicationInstanceDTO != null` en tenait lieu — il n'était
|
||||||
|
/// assigné que si l'instance avait l'IA. Ce DTO portant désormais aussi les
|
||||||
|
/// réglages d'affichage, il est toujours assigné : le drapeau est explicite.
|
||||||
|
bool isAssistantEnabled = false;
|
||||||
|
|
||||||
|
/// Retourne l'AppConfigurationLink de l'instance pour la configuration courante.
|
||||||
|
/// Contient roundedValue, isSectionImageBackground, isDate, isHour,
|
||||||
|
/// screenPercentageSectionsMainPage — ces réglages ont quitté ConfigurationDTO
|
||||||
|
/// avec Postgres v3, ils sont désormais portés par le lien instance ↔ configuration.
|
||||||
|
/// Même getter que VisitAppContext dans mymuseum-visitapp.
|
||||||
|
AppConfigurationLink? get currentAppConfigurationLink {
|
||||||
|
if (applicationInstanceDTO == null || configuration == null) return null;
|
||||||
|
return applicationInstanceDTO!.configurations
|
||||||
|
?.where((c) => c.configurationId == configuration!.id)
|
||||||
|
.firstOrNull;
|
||||||
|
}
|
||||||
|
|
||||||
TabletAppContext({this.id, this.deviceId, this.host, this.configuration, this.language, this.instanceId, this.apiKey, this.clientAPI});
|
TabletAppContext({this.id, this.deviceId, this.host, this.configuration, this.language, this.instanceId, this.apiKey, this.clientAPI});
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
|||||||
@ -52,7 +52,7 @@ class _AgendaView extends State<AgendaView> {
|
|||||||
if (dtos == null) return null;
|
if (dtos == null) return null;
|
||||||
|
|
||||||
final events = dtos
|
final events = dtos
|
||||||
.map((dto) => EventAgenda.fromDto(dto, tabletAppContext.language))
|
.map((dto) => EventAgenda.fromDto(dto, tabletAppContext.language ?? 'FR'))
|
||||||
.toList();
|
.toList();
|
||||||
events.sort((a, b) {
|
events.sort((a, b) {
|
||||||
if (a.dateFrom == null) return 1;
|
if (a.dateFrom == null) return 1;
|
||||||
@ -110,7 +110,7 @@ class _AgendaView extends State<AgendaView> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30.0)),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class EventListItem extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(10.0),
|
margin: const EdgeInsets.all(10.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0),
|
||||||
//color: Colors.red,
|
//color: Colors.red,
|
||||||
boxShadow: const [
|
boxShadow: const [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
@ -53,7 +53,7 @@ class EventListItem extends StatelessWidget {
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
eventAgenda.image != null ? ClipRRect(
|
eventAgenda.image != null ? ClipRRect(
|
||||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), topRight: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0), topRight: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
child: Container(
|
child: Container(
|
||||||
//color: Colors.green,
|
//color: Colors.green,
|
||||||
//constraints: const BoxConstraints(maxHeight: 175),
|
//constraints: const BoxConstraints(maxHeight: 175),
|
||||||
@ -82,7 +82,7 @@ class EventListItem extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0),
|
topLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@ -127,7 +127,7 @@ class EventListItem extends StatelessWidget {
|
|||||||
width: size.width,
|
width: size.width,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), bottomRight: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0), bottomRight: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
border: Border(top: BorderSide(width: 0.1, color: kMainGrey))
|
border: Border(top: BorderSide(width: 0.1, color: kMainGrey))
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|||||||
@ -106,13 +106,13 @@ class _EventPopupState extends State<EventPopup> {
|
|||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
// title: Text(eventAgenda.name!),
|
// title: Text(eventAgenda.name!),
|
||||||
content: Container(
|
content: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
),
|
),
|
||||||
height: size.height * 0.85,
|
height: size.height * 0.85,
|
||||||
@ -151,7 +151,7 @@ class _EventPopupState extends State<EventPopup> {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
widget.eventAgenda.image != null ? ClipRRect(
|
widget.eventAgenda.image != null ? ClipRRect(
|
||||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), bottomLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0), bottomLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -229,7 +229,7 @@ class _EventPopupState extends State<EventPopup> {
|
|||||||
width: size.width * 0.38,
|
width: size.width * 0.38,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
|
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
|
||||||
|
|||||||
@ -381,5 +381,22 @@ Future<List<ConfigurationDTO>?> getConfigurations(dynamic appContext) async {
|
|||||||
//print(element);
|
//print(element);
|
||||||
});
|
});
|
||||||
|
|
||||||
return configurations.where((config) => config.isTablet!).toList();
|
// `ConfigurationDTO.isTablet` a disparu avec Postgres v3 : le canal n'est plus une
|
||||||
|
// propriété de la configuration, il est porté par l'ApplicationInstance, et le
|
||||||
|
// rattachement vit dans ses AppConfigurationLink. Même source que main_view.
|
||||||
|
if (tabletAppContext.instanceId == null) return configurations;
|
||||||
|
|
||||||
|
final instanceDTO = await tabletAppContext.clientAPI!.instanceApi!
|
||||||
|
.instanceGetDetail(tabletAppContext.instanceId!);
|
||||||
|
|
||||||
|
final tabletConfigurationIds = instanceDTO?.applicationInstanceDTOs
|
||||||
|
?.where((a) => a.appType == AppType.Tablet)
|
||||||
|
.expand((a) => a.configurations ?? const <AppConfigurationLink>[])
|
||||||
|
.map((link) => link.configurationId)
|
||||||
|
.toSet() ??
|
||||||
|
const <String>{};
|
||||||
|
|
||||||
|
return configurations
|
||||||
|
.where((config) => tabletConfigurationIds.contains(config.id))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
517
lib/Screens/Game/game_page.dart
Normal file
517
lib/Screens/Game/game_page.dart
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||||
|
import 'package:manager_api_new/api.dart';
|
||||||
|
import 'package:tablet_app/Components/loading_common.dart';
|
||||||
|
import 'package:tablet_app/Helpers/translationHelper.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/Screens/Game/message_dialog.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tablet_app/Screens/Game/sliding_puzzle_piece.dart';
|
||||||
|
import 'puzzle_piece.dart';
|
||||||
|
|
||||||
|
const IMAGE_PATH = 'image_path';
|
||||||
|
|
||||||
|
class GamePage extends StatefulWidget {
|
||||||
|
final GameDTO section;
|
||||||
|
GamePage({required this.section});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_GamePage createState() => _GamePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GamePage extends State<GamePage> {
|
||||||
|
GameDTO gameDTO = GameDTO();
|
||||||
|
|
||||||
|
int allInPlaceCount = 0;
|
||||||
|
bool isFinished = false;
|
||||||
|
DateTime? _gameStartTime;
|
||||||
|
GlobalKey _widgetKey = GlobalKey();
|
||||||
|
Size? realWidgetSize;
|
||||||
|
List<Widget> pieces = [];
|
||||||
|
|
||||||
|
bool isSplittingImage = true;
|
||||||
|
bool showHint = false;
|
||||||
|
List<int> slidingTileIndices = []; // Maps current slot index to original tile index. -1 for empty.
|
||||||
|
int emptySlotIndex = -1;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
//puzzleDTO = PuzzleDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
gameDTO = widget.section;
|
||||||
|
gameDTO.rows = gameDTO.rows ?? 3;
|
||||||
|
gameDTO.cols = gameDTO.cols ?? 3;
|
||||||
|
_gameStartTime = DateTime.now();
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
print(gameDTO.messageDebut);
|
||||||
|
TranslationAndResourceDTO? messageDebut = gameDTO.messageDebut != null && gameDTO.messageDebut!.isNotEmpty ? gameDTO.messageDebut!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null;
|
||||||
|
|
||||||
|
//await Future.delayed(const Duration(milliseconds: 50));
|
||||||
|
|
||||||
|
await WidgetsBinding.instance.endOfFrame;
|
||||||
|
getRealWidgetSize();
|
||||||
|
|
||||||
|
if(gameDTO.puzzleImage != null && gameDTO.puzzleImage!.url != null) {
|
||||||
|
//splitImage(Image.network(puzzleDTO.image!.resourceUrl!));
|
||||||
|
splitImage(CachedNetworkImage(
|
||||||
|
imageUrl: gameDTO.puzzleImage!.url!,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
isSplittingImage = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(messageDebut != null) {
|
||||||
|
showMessage(messageDebut, appContext, context, size);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getRealWidgetSize() async {
|
||||||
|
RenderBox renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox;
|
||||||
|
Size size = renderBox.size;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
realWidgetSize = size;
|
||||||
|
});
|
||||||
|
print("Taille réelle du widget : $size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// here we will split the image into small pieces
|
||||||
|
// using the rows and columns defined above; each piece will be added to a stack
|
||||||
|
void splitImage(CachedNetworkImage image) async {
|
||||||
|
final Completer<Size> completer = Completer<Size>();
|
||||||
|
final ImageProvider provider = CachedNetworkImageProvider(gameDTO.puzzleImage!.url!);
|
||||||
|
|
||||||
|
provider.resolve(const ImageConfiguration()).addListener(
|
||||||
|
ImageStreamListener((ImageInfo info, bool _) {
|
||||||
|
if (!completer.isCompleted) {
|
||||||
|
completer.complete(Size(info.image.width.toDouble(), info.image.height.toDouble()));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
Size imageOriginalSize = await completer.future;
|
||||||
|
double imageAspectRatio = imageOriginalSize.width / imageOriginalSize.height;
|
||||||
|
|
||||||
|
// Calculate best fit for the puzzle inside the available area
|
||||||
|
double containerWidth = realWidgetSize!.width * 0.9; // 90% of available width
|
||||||
|
double containerHeight = realWidgetSize!.height * 0.8; // 80% of available height
|
||||||
|
double containerAspectRatio = containerWidth / containerHeight;
|
||||||
|
|
||||||
|
double puzzleWidth, puzzleHeight;
|
||||||
|
if (imageAspectRatio > containerAspectRatio) {
|
||||||
|
puzzleWidth = containerWidth;
|
||||||
|
puzzleHeight = containerWidth / imageAspectRatio;
|
||||||
|
} else {
|
||||||
|
puzzleHeight = containerHeight;
|
||||||
|
puzzleWidth = containerHeight * imageAspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
setState(() {
|
||||||
|
tabletAppContext.puzzleSize = Size(puzzleWidth, puzzleHeight);
|
||||||
|
appContext.setContext(tabletAppContext);
|
||||||
|
});
|
||||||
|
|
||||||
|
final pieceWidth = puzzleWidth / gameDTO.cols!;
|
||||||
|
final pieceHeight = puzzleHeight / gameDTO.rows!;
|
||||||
|
|
||||||
|
if (gameDTO.gameType == GameTypes.SlidingPuzzle) {
|
||||||
|
// Initialize sliding puzzle slots: 0 to N-2 are tiles, last one is empty (-1)
|
||||||
|
int totalTiles = gameDTO.rows! * gameDTO.cols!;
|
||||||
|
slidingTileIndices = List.generate(totalTiles, (i) => i);
|
||||||
|
|
||||||
|
// Shuffle by making random valid moves to ensure solvability
|
||||||
|
emptySlotIndex = totalTiles - 1;
|
||||||
|
slidingTileIndices[emptySlotIndex] = -1; // -1 represents the empty slot
|
||||||
|
|
||||||
|
// Perform enough random moves to shuffle decently
|
||||||
|
int shuffleMoves = 100;
|
||||||
|
Random random = Random();
|
||||||
|
for (int i = 0; i < shuffleMoves; i++) {
|
||||||
|
List<int> adjacent = _getAdjacentIndices(emptySlotIndex, gameDTO.rows!, gameDTO.cols!);
|
||||||
|
int moveIndex = adjacent[random.nextInt(adjacent.length)];
|
||||||
|
// Swap empty slot with the adjacent tile
|
||||||
|
slidingTileIndices[emptySlotIndex] = slidingTileIndices[moveIndex];
|
||||||
|
slidingTileIndices[moveIndex] = -1;
|
||||||
|
emptySlotIndex = moveIndex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int x = 0; x < gameDTO.rows!; x++) {
|
||||||
|
for (int y = 0; y < gameDTO.cols!; y++) {
|
||||||
|
// Target position in the puzzle grid
|
||||||
|
double targetLeft = y * pieceWidth;
|
||||||
|
double targetTop = x * pieceHeight;
|
||||||
|
|
||||||
|
// Scatter logic: Randomly place within the container.
|
||||||
|
double initialLeft = Random().nextDouble() * (containerWidth - pieceWidth);
|
||||||
|
double initialTop = Random().nextDouble() * (containerHeight - pieceHeight);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
pieces.add(
|
||||||
|
PuzzlePiece(
|
||||||
|
key: GlobalKey(),
|
||||||
|
image: image,
|
||||||
|
imageSize: Size(puzzleWidth, puzzleHeight),
|
||||||
|
row: x,
|
||||||
|
col: y,
|
||||||
|
maxRow: gameDTO.rows!,
|
||||||
|
maxCol: gameDTO.cols!,
|
||||||
|
bringToTop: bringToTop,
|
||||||
|
sendToBack: sendToBack,
|
||||||
|
initialLeft: initialLeft - targetLeft,
|
||||||
|
initialTop: initialTop - targetTop,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
isSplittingImage = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> _getAdjacentIndices(int index, int rows, int cols) {
|
||||||
|
List<int> adjacent = [];
|
||||||
|
int r = index ~/ cols;
|
||||||
|
int c = index % cols;
|
||||||
|
|
||||||
|
if (r > 0) adjacent.add(index - cols); // Top
|
||||||
|
if (r < rows - 1) adjacent.add(index + cols); // Bottom
|
||||||
|
if (c > 0) adjacent.add(index - 1); // Left
|
||||||
|
if (c < cols - 1) adjacent.add(index + 1); // Right
|
||||||
|
|
||||||
|
return adjacent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSlidingTileTapped(int currentSlot) {
|
||||||
|
if (isFinished) return;
|
||||||
|
|
||||||
|
// Check if empty slot is adjacent
|
||||||
|
List<int> adjacent = _getAdjacentIndices(currentSlot, gameDTO.rows!, gameDTO.cols!);
|
||||||
|
if (adjacent.contains(emptySlotIndex)) {
|
||||||
|
setState(() {
|
||||||
|
// Swap
|
||||||
|
slidingTileIndices[emptySlotIndex] = slidingTileIndices[currentSlot];
|
||||||
|
slidingTileIndices[currentSlot] = -1;
|
||||||
|
emptySlotIndex = currentSlot;
|
||||||
|
|
||||||
|
// Check win condition
|
||||||
|
bool won = true;
|
||||||
|
for (int i = 0; i < slidingTileIndices.length; i++) {
|
||||||
|
// In a solved puzzle, index i should contain tile i (or -1 at the very last slot)
|
||||||
|
if (i == slidingTileIndices.length - 1) {
|
||||||
|
if (slidingTileIndices[i] != -1) won = false;
|
||||||
|
} else {
|
||||||
|
if (slidingTileIndices[i] != i) won = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (won) {
|
||||||
|
isFinished = true;
|
||||||
|
_onGameFinished('SlidingPuzzle');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the pan of a piece starts, we need to bring it to the front of the stack
|
||||||
|
void bringToTop(Widget widget) {
|
||||||
|
setState(() {
|
||||||
|
pieces.remove(widget);
|
||||||
|
pieces.add(widget);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// when a piece reaches its final position,
|
||||||
|
// it will be sent to the back of the stack to not get in the way of other, still movable, pieces
|
||||||
|
void sendToBack(Widget widget) {
|
||||||
|
setState(() {
|
||||||
|
allInPlaceCount++;
|
||||||
|
isFinished = allInPlaceCount == gameDTO.rows! * gameDTO.cols!;
|
||||||
|
pieces.remove(widget);
|
||||||
|
pieces.insert(0, widget);
|
||||||
|
|
||||||
|
if (isFinished) {
|
||||||
|
_onGameFinished('Puzzle');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onGameFinished(String gameType) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
final duration = _gameStartTime != null ? DateTime.now().difference(_gameStartTime!).inSeconds : 0;
|
||||||
|
|
||||||
|
tabletAppContext.statisticsService?.track(
|
||||||
|
VisitEventType.gameComplete,
|
||||||
|
metadata: {'gameType': gameType, 'durationSeconds': duration},
|
||||||
|
);
|
||||||
|
|
||||||
|
TranslationAndResourceDTO? messageFin = gameDTO.messageFin != null && gameDTO.messageFin!.isNotEmpty ? gameDTO.messageFin!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null;
|
||||||
|
|
||||||
|
if(messageFin != null) {
|
||||||
|
showMessage(messageFin, appContext, context, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// mymuseum code ces couleurs en dur par flavor client (rouge MDLF, bleu Fort).
|
||||||
|
/// tablet-app n'a pas de flavor : un seul APK sert tous les clients et la charte
|
||||||
|
/// vient de la configuration choisie au pincode. Le dégradé en est donc dérivé,
|
||||||
|
/// sinon l'écran s'afficherait en bleu chez un client dont la charte est rouge.
|
||||||
|
Color _primaryColor(TabletAppContext tabletAppContext) {
|
||||||
|
final raw = tabletAppContext.configuration?.primaryColor;
|
||||||
|
if (raw == null) return kTestSecondColor;
|
||||||
|
return Color(int.parse(raw.split('(0x')[1].split(')')[0], radix: 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Color> _gradientColors(TabletAppContext tabletAppContext) {
|
||||||
|
final base = _primaryColor(tabletAppContext);
|
||||||
|
return [
|
||||||
|
base,
|
||||||
|
Color.lerp(base, Colors.white, 0.15)!,
|
||||||
|
Color.lerp(base, Colors.white, 0.30)!,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildContent(TabletAppContext tabletAppContext) {
|
||||||
|
if (gameDTO.gameType == GameTypes.SlidingPuzzle) {
|
||||||
|
if (slidingTileIndices.isEmpty) return Center(child: LoadingCommon());
|
||||||
|
|
||||||
|
final puzzleSize = tabletAppContext.puzzleSize ?? Size(realWidgetSize!.width * 0.8, realWidgetSize!.height * 0.6);
|
||||||
|
final tileWidth = puzzleSize.width / gameDTO.cols!;
|
||||||
|
final tileHeight = puzzleSize.height / gameDTO.rows!;
|
||||||
|
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
width: puzzleSize.width,
|
||||||
|
height: puzzleSize.height,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
// Hint Background
|
||||||
|
if (showHint)
|
||||||
|
Opacity(
|
||||||
|
opacity: 0.25,
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: gameDTO.puzzleImage!.url!,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Tiles
|
||||||
|
for (int i = 0; i < slidingTileIndices.length; i++)
|
||||||
|
if (slidingTileIndices[i] != -1) // Don't draw the empty slot
|
||||||
|
AnimatedPositioned(
|
||||||
|
key: ValueKey('tile_${slidingTileIndices[i]}'),
|
||||||
|
duration: const Duration(milliseconds: 250),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
left: (i % gameDTO.cols!) * tileWidth,
|
||||||
|
top: (i ~/ gameDTO.cols!) * tileHeight,
|
||||||
|
child: SlidingPuzzlePiece(
|
||||||
|
image: CachedNetworkImage(imageUrl: gameDTO.puzzleImage!.url!, fit: BoxFit.fill),
|
||||||
|
imageSize: puzzleSize,
|
||||||
|
originalRow: slidingTileIndices[i] ~/ gameDTO.cols!,
|
||||||
|
originalCol: slidingTileIndices[i] % gameDTO.cols!,
|
||||||
|
maxRows: gameDTO.rows!,
|
||||||
|
maxCols: gameDTO.cols!,
|
||||||
|
width: tileWidth,
|
||||||
|
height: tileHeight,
|
||||||
|
showNumberHint: showHint,
|
||||||
|
onTap: () => _onSlidingTileTapped(i),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default: Puzzle
|
||||||
|
if (gameDTO.puzzleImage == null || gameDTO.puzzleImage!.url == null || realWidgetSize == null) {
|
||||||
|
return Center(child: Text("Aucune image à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect)));
|
||||||
|
}
|
||||||
|
|
||||||
|
final puzzleSize = tabletAppContext.puzzleSize ?? Size(realWidgetSize!.width * 0.8, realWidgetSize!.height * 0.6);
|
||||||
|
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
width: puzzleSize.width,
|
||||||
|
height: puzzleSize.height,
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
// Hint Background
|
||||||
|
if (showHint)
|
||||||
|
Opacity(
|
||||||
|
opacity: 0.2, // Unified opacity for both
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: gameDTO.puzzleImage!.url!,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
...pieces,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
var title = TranslationHelper.get(widget.section.title, appContext.getContext());
|
||||||
|
String cleanedTitle = title.replaceAll('\n', ' ').replaceAll('<br>', ' ');
|
||||||
|
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: size.height * 0.28,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kMainGrey,
|
||||||
|
spreadRadius: 0.5,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: Offset(0, 1), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.centerRight,
|
||||||
|
end: Alignment.centerLeft,
|
||||||
|
colors: _gradientColors(tabletAppContext),
|
||||||
|
),
|
||||||
|
image: widget.section.imageSource != null ? DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.65,
|
||||||
|
image: NetworkImage(
|
||||||
|
widget.section.imageSource!,
|
||||||
|
),
|
||||||
|
): null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
height: size.height * 0.11,
|
||||||
|
width: size.width,
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 22.0),
|
||||||
|
child: SizedBox(
|
||||||
|
width: size.width *0.7,
|
||||||
|
child: HtmlWidget(
|
||||||
|
cleanedTitle,
|
||||||
|
textStyle: const TextStyle(color: Colors.white, fontFamily: 'Roboto', fontSize: 20),
|
||||||
|
customStylesBuilder: (element)
|
||||||
|
{
|
||||||
|
return {'text-align': 'center', 'font-family': "Roboto", '-webkit-line-clamp': "2"};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 35,
|
||||||
|
left: 10,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _primaryColor(tabletAppContext),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: const Icon(Icons.arrow_back, size: 23, color: Colors.white)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.only(top: 0),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: kMainGrey,
|
||||||
|
spreadRadius: 0.5,
|
||||||
|
blurRadius: 2,
|
||||||
|
offset: Offset(0, 1), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
color: kBackgroundColor,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(30),
|
||||||
|
topRight: Radius.circular(30),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(30),
|
||||||
|
topRight: Radius.circular(30),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
//color: Colors.green,
|
||||||
|
child: Container(
|
||||||
|
//color: Colors.green,
|
||||||
|
child: Padding(
|
||||||
|
key: _widgetKey,
|
||||||
|
padding: const EdgeInsets.all(0.0),
|
||||||
|
child: isSplittingImage ? Center(child: LoadingCommon()) : _buildContent(tabletAppContext),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (gameDTO.gameType == null || gameDTO.gameType == GameTypes.Puzzle || gameDTO.gameType == GameTypes.SlidingPuzzle)
|
||||||
|
Positioned(
|
||||||
|
bottom: 25,
|
||||||
|
right: 20,
|
||||||
|
child: FloatingActionButton(
|
||||||
|
heroTag: 'hint_button',
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
showHint = !showHint;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
backgroundColor: showHint ? _primaryColor(tabletAppContext) : Colors.grey[400],
|
||||||
|
child: const Icon(Icons.help_outline, color: Colors.white, size: 28),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ void showMessage(TranslationAndResourceDTO translationAndResourceDTO, AppContext
|
|||||||
showDialog(
|
showDialog(
|
||||||
builder: (BuildContext context) => AlertDialog(
|
builder: (BuildContext context) => AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -24,13 +24,14 @@ void showMessage(TranslationAndResourceDTO translationAndResourceDTO, AppContext
|
|||||||
children: [
|
children: [
|
||||||
if(translationAndResourceDTO.resourceId != null)
|
if(translationAndResourceDTO.resourceId != null)
|
||||||
Container(
|
Container(
|
||||||
|
constraints: BoxConstraints(maxHeight: 250),
|
||||||
//color: Colors.cyan,
|
//color: Colors.cyan,
|
||||||
height: size.height *0.45,
|
height: size.height *0.45,
|
||||||
width: size.width *0.5,
|
width: size.width *0.5,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30),
|
||||||
//border: Border.all(width: 3, color: Colors.black)
|
//border: Border.all(width: 3, color: Colors.black)
|
||||||
),
|
),
|
||||||
child: showElementForResource(ResourceDTO(id: translationAndResourceDTO.resourceId, type: translationAndResourceDTO.resource!.type, url: translationAndResourceDTO.resource!.url), appContext, true, false),
|
child: showElementForResource(ResourceDTO(id: translationAndResourceDTO.resourceId, type: translationAndResourceDTO.resource!.type, url: translationAndResourceDTO.resource!.url), appContext, true, false),
|
||||||
@ -38,6 +39,7 @@ void showMessage(TranslationAndResourceDTO translationAndResourceDTO, AppContext
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
constraints: BoxConstraints(maxHeight: 350),
|
||||||
//color: Colors.green,
|
//color: Colors.green,
|
||||||
height: size.height *0.3,
|
height: size.height *0.3,
|
||||||
width: size.width *0.5,
|
width: size.width *0.5,
|
||||||
@ -51,7 +53,7 @@ void showMessage(TranslationAndResourceDTO translationAndResourceDTO, AppContext
|
|||||||
customStylesBuilder: (element) {
|
customStylesBuilder: (element) {
|
||||||
return {'text-align': 'center', 'font-family': "Roboto"};
|
return {'text-align': 'center', 'font-family': "Roboto"};
|
||||||
},
|
},
|
||||||
textStyle: TextStyle(fontSize: kDescriptionSize),
|
textStyle: const TextStyle(fontSize: kDescriptionSize),
|
||||||
),/*Text(
|
),/*Text(
|
||||||
resourceDTO.label == null ? "" : resourceDTO.label,
|
resourceDTO.label == null ? "" : resourceDTO.label,
|
||||||
style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)),*/
|
style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)),*/
|
||||||
@ -1,10 +1,5 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
|
||||||
import 'package:tablet_app/app_context.dart';
|
|
||||||
|
|
||||||
class PuzzlePiece extends StatefulWidget {
|
class PuzzlePiece extends StatefulWidget {
|
||||||
final CachedNetworkImage image;
|
final CachedNetworkImage image;
|
||||||
@ -15,22 +10,11 @@ class PuzzlePiece extends StatefulWidget {
|
|||||||
final int maxCol;
|
final int maxCol;
|
||||||
final Function bringToTop;
|
final Function bringToTop;
|
||||||
final Function sendToBack;
|
final Function sendToBack;
|
||||||
|
final double initialTop;
|
||||||
|
final double initialLeft;
|
||||||
|
|
||||||
static PuzzlePiece fromMap(Map<String, dynamic> map) {
|
PuzzlePiece({
|
||||||
return PuzzlePiece(
|
Key? key,
|
||||||
image: map['image'],
|
|
||||||
imageSize: map['imageSize'],
|
|
||||||
row: map['row'],
|
|
||||||
col: map['col'],
|
|
||||||
maxRow: map['maxRow'],
|
|
||||||
maxCol: map['maxCol'],
|
|
||||||
bringToTop: map['bringToTop'],
|
|
||||||
sendToBack: map['SendToBack'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
PuzzlePiece(
|
|
||||||
{Key? key,
|
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.imageSize,
|
required this.imageSize,
|
||||||
required this.row,
|
required this.row,
|
||||||
@ -38,8 +22,10 @@ class PuzzlePiece extends StatefulWidget {
|
|||||||
required this.maxRow,
|
required this.maxRow,
|
||||||
required this.maxCol,
|
required this.maxCol,
|
||||||
required this.bringToTop,
|
required this.bringToTop,
|
||||||
required this.sendToBack})
|
required this.sendToBack,
|
||||||
: super(key: key);
|
required this.initialTop,
|
||||||
|
required this.initialLeft,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PuzzlePieceState createState() => _PuzzlePieceState();
|
_PuzzlePieceState createState() => _PuzzlePieceState();
|
||||||
@ -58,65 +44,32 @@ class _PuzzlePieceState extends State<PuzzlePiece> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
top = widget.initialTop;
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
left = widget.initialLeft;
|
||||||
setState(() {
|
|
||||||
|
|
||||||
RenderBox renderBox = _widgetPieceKey.currentContext?.findRenderObject() as RenderBox;
|
|
||||||
Size size = renderBox.size;
|
|
||||||
|
|
||||||
final appContext = Provider.of<AppContext>(context, listen: false);
|
|
||||||
TabletAppContext tabletAppContext = appContext.getContext();
|
|
||||||
tabletAppContext.puzzleSize = size;
|
|
||||||
appContext.setContext(tabletAppContext);
|
|
||||||
|
|
||||||
if (widget.row == 0 && widget.col == 0) {
|
if (widget.row == 0 && widget.col == 0) {
|
||||||
widget.sendToBack(widget);
|
isMovable = false;
|
||||||
|
top = 0;
|
||||||
|
left = 0;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return AnimatedPositioned(
|
||||||
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
duration: isMovable ? Duration.zero : const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeOutBack,
|
||||||
var imageHeight = isPortrait ? widget.imageSize.width/1.55 : widget.imageSize.width;
|
|
||||||
var imageWidth = isPortrait ? widget.imageSize.width/1.55 : widget.imageSize.height;
|
|
||||||
|
|
||||||
final pieceWidth = imageWidth / widget.maxCol;
|
|
||||||
final pieceHeight = imageHeight / widget.maxRow;
|
|
||||||
|
|
||||||
if (top == null) {
|
|
||||||
top = Random().nextInt((imageHeight - pieceHeight).ceil()).toDouble();
|
|
||||||
var test = top!;
|
|
||||||
test -= widget.row * pieceHeight;
|
|
||||||
top = test /7; // TODO change ?
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left == null) {
|
|
||||||
left = Random().nextInt((imageWidth - pieceWidth).ceil()).toDouble();
|
|
||||||
var test = left!;
|
|
||||||
test -= widget.col * pieceWidth;
|
|
||||||
left = test /7; // TODO change ?
|
|
||||||
}
|
|
||||||
|
|
||||||
if(widget.row == 0 && widget.col == 0) {
|
|
||||||
top = 0;
|
|
||||||
left = 0;
|
|
||||||
isMovable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Positioned(
|
|
||||||
top: top,
|
top: top,
|
||||||
left: left,
|
left: left,
|
||||||
width: imageWidth,
|
width: widget.imageSize.width,
|
||||||
|
child: AnimatedScale(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
scale: isMovable ? 1.05 : 1.0,
|
||||||
child: Container(
|
child: Container(
|
||||||
key: _widgetPieceKey,
|
key: _widgetPieceKey,
|
||||||
decoration: widget.col == 0 && widget.row == 0 ? BoxDecoration(
|
decoration: widget.col == 0 && widget.row == 0 ? BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.black,
|
color: Colors.black.withOpacity(0.3),
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
) : null,
|
) : null,
|
||||||
@ -134,24 +87,27 @@ class _PuzzlePieceState extends State<PuzzlePiece> {
|
|||||||
onPanUpdate: (dragUpdateDetails) {
|
onPanUpdate: (dragUpdateDetails) {
|
||||||
if (isMovable) {
|
if (isMovable) {
|
||||||
setState(() {
|
setState(() {
|
||||||
var testTop = top!;
|
top = top! + dragUpdateDetails.delta.dy;
|
||||||
var testLeft = left!;
|
left = left! + dragUpdateDetails.delta.dx;
|
||||||
testTop = top!;
|
|
||||||
testLeft = left!;
|
|
||||||
testTop += dragUpdateDetails.delta.dy;
|
|
||||||
testLeft += dragUpdateDetails.delta.dx;
|
|
||||||
top = testTop;
|
|
||||||
left = testLeft;
|
|
||||||
|
|
||||||
if (-10 < top! && top! < 10 && -10 < left! && left! < 10) {
|
// Target position is (0,0) relative to its original offset in the image
|
||||||
|
if (top!.abs() < 15 && left!.abs() < 15) {
|
||||||
|
setState(() {
|
||||||
top = 0;
|
top = 0;
|
||||||
left = 0;
|
left = 0;
|
||||||
isMovable = false;
|
isMovable = false;
|
||||||
|
});
|
||||||
widget.sendToBack(widget);
|
widget.sendToBack(widget);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
child: PhysicalShape(
|
||||||
|
clipper: PuzzlePieceClipper(
|
||||||
|
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
||||||
|
elevation: isMovable ? 4.0 : 0.0,
|
||||||
|
color: Colors.transparent,
|
||||||
|
shadowColor: Colors.black.withOpacity(0.5),
|
||||||
child: ClipPath(
|
child: ClipPath(
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
foregroundPainter: PuzzlePiecePainter(
|
foregroundPainter: PuzzlePiecePainter(
|
||||||
@ -161,7 +117,10 @@ class _PuzzlePieceState extends State<PuzzlePiece> {
|
|||||||
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,9 +154,9 @@ class PuzzlePiecePainter extends CustomPainter {
|
|||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
final Paint paint = Paint()
|
final Paint paint = Paint()
|
||||||
..color = Colors.black//Color(0x80FFFFFF)
|
..color = Colors.black.withOpacity(0.2)
|
||||||
..style = PaintingStyle.stroke
|
..style = PaintingStyle.stroke
|
||||||
..strokeWidth = 2.5;
|
..strokeWidth = 1.0;
|
||||||
|
|
||||||
canvas.drawPath(getPiecePath(size, row, col, maxRow, maxCol), paint);
|
canvas.drawPath(getPiecePath(size, row, col, maxRow, maxCol), paint);
|
||||||
}
|
}
|
||||||
88
lib/Screens/Game/sliding_puzzle_piece.dart
Normal file
88
lib/Screens/Game/sliding_puzzle_piece.dart
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SlidingPuzzlePiece extends StatelessWidget {
|
||||||
|
final CachedNetworkImage image;
|
||||||
|
final Size imageSize;
|
||||||
|
final int originalRow;
|
||||||
|
final int originalCol;
|
||||||
|
final int maxRows;
|
||||||
|
final int maxCols;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
final double width;
|
||||||
|
final double height;
|
||||||
|
final bool showNumberHint;
|
||||||
|
|
||||||
|
const SlidingPuzzlePiece({
|
||||||
|
Key? key,
|
||||||
|
required this.image,
|
||||||
|
required this.imageSize,
|
||||||
|
required this.originalRow,
|
||||||
|
required this.originalCol,
|
||||||
|
required this.maxRows,
|
||||||
|
required this.maxCols,
|
||||||
|
required this.onTap,
|
||||||
|
required this.width,
|
||||||
|
required this.height,
|
||||||
|
this.showNumberHint = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
margin: const EdgeInsets.all(2), // Subtle gap
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withOpacity(0.2),
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
OverflowBox(
|
||||||
|
maxWidth: imageSize.width,
|
||||||
|
maxHeight: imageSize.height,
|
||||||
|
alignment: Alignment(
|
||||||
|
maxCols == 1 ? 0.0 : -1.0 + (originalCol * 2 / (maxCols - 1)),
|
||||||
|
maxRows == 1 ? 0.0 : -1.0 + (originalRow * 2 / (maxRows - 1)),
|
||||||
|
),
|
||||||
|
child: image,
|
||||||
|
),
|
||||||
|
if (showNumberHint)
|
||||||
|
Container(
|
||||||
|
color: Colors.black.withOpacity(0.3),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'${originalRow * maxCols + originalCol + 1}',
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
shadows: [
|
||||||
|
Shadow(
|
||||||
|
blurRadius: 4.0,
|
||||||
|
color: Colors.black,
|
||||||
|
offset: Offset(0, 0),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -31,7 +31,7 @@ import 'package:tablet_app/Screens/Map/map_view.dart';
|
|||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
import 'package:tablet_app/Screens/Menu/menu_view.dart';
|
import 'package:tablet_app/Screens/Menu/menu_view.dart';
|
||||||
import 'package:tablet_app/Screens/PDF/pdf_view.dart';
|
import 'package:tablet_app/Screens/PDF/pdf_view.dart';
|
||||||
import 'package:tablet_app/Screens/Puzzle/puzzle_view.dart';
|
import 'package:tablet_app/Screens/Game/game_page.dart';
|
||||||
import 'package:tablet_app/Screens/Slider/slider_view.dart';
|
import 'package:tablet_app/Screens/Slider/slider_view.dart';
|
||||||
import 'package:tablet_app/Screens/Video/video_view.dart';
|
import 'package:tablet_app/Screens/Video/video_view.dart';
|
||||||
import 'package:tablet_app/Screens/Web/web_view.dart';
|
import 'package:tablet_app/Screens/Web/web_view.dart';
|
||||||
@ -58,6 +58,11 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
Size sizeScreen = new Size(1080.0, 1920.0); // Tablet resolution
|
Size sizeScreen = new Size(1080.0, 1920.0); // Tablet resolution
|
||||||
SectionDTO? sectionSelected;
|
SectionDTO? sectionSelected;
|
||||||
late ConfigurationDTO configurationDTO;
|
late ConfigurationDTO configurationDTO;
|
||||||
|
|
||||||
|
/// isDate, isHour, isSectionImageBackground et screenPercentageSectionsMainPage
|
||||||
|
/// ont quitté ConfigurationDTO avec Postgres v3 : ils vivent sur le lien
|
||||||
|
/// instance ↔ configuration.
|
||||||
|
AppConfigurationLink? appConfigurationLink;
|
||||||
ValueNotifier<DateTime?> currentHourDate = ValueNotifier<DateTime?>((DateTime.now().toUtc()).add(Duration(hours: 1)));
|
ValueNotifier<DateTime?> currentHourDate = ValueNotifier<DateTime?>((DateTime.now().toUtc()).add(Duration(hours: 1)));
|
||||||
late Color backgroundColor;
|
late Color backgroundColor;
|
||||||
int rowCount = 4;
|
int rowCount = 4;
|
||||||
@ -77,11 +82,12 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
|
|
||||||
|
|
||||||
configurationDTO = appContext.getContext().configuration;
|
configurationDTO = appContext.getContext().configuration;
|
||||||
if(configurationDTO.isHour != null && configurationDTO.isHour!) {
|
appConfigurationLink = appContext.getContext().currentAppConfigurationLink;
|
||||||
|
if(appConfigurationLink?.isHour == true) {
|
||||||
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime(currentHourDate));
|
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime(currentHourDate));
|
||||||
}
|
}
|
||||||
|
|
||||||
isImageBackground = configurationDTO.isSectionImageBackground ?? true;
|
isImageBackground = appConfigurationLink?.isSectionImageBackground ?? true;
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@ -138,12 +144,12 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if(value != null && configurationDTO.isHour!)
|
if(value != null && appConfigurationLink?.isHour == true)
|
||||||
Text(DateFormat('HH:mm').format(value), style: TextStyle(fontSize: 20, color: textColor)),
|
Text(DateFormat('HH:mm').format(value), style: TextStyle(fontSize: 20, color: textColor)),
|
||||||
if(value != null && configurationDTO.isDate!)
|
if(value != null && appConfigurationLink?.isDate == true)
|
||||||
if(appContext.getContext().language.toString().toUpperCase() == "EN")
|
if(appContext.getContext().language.toString().toUpperCase() == "EN")
|
||||||
Text(DateFormat('MM/dd').format(value), style: TextStyle(fontSize: 15, color: textColor)),
|
Text(DateFormat('MM/dd').format(value), style: TextStyle(fontSize: 15, color: textColor)),
|
||||||
if(value != null && configurationDTO.isDate!)
|
if(value != null && appConfigurationLink?.isDate == true)
|
||||||
if(appContext.getContext().language.toString().toUpperCase() != "EN")
|
if(appContext.getContext().language.toString().toUpperCase() != "EN")
|
||||||
Text(DateFormat('dd/MM').format(value), style: TextStyle(fontSize: 15, color: textColor)),
|
Text(DateFormat('dd/MM').format(value), style: TextStyle(fontSize: 15, color: textColor)),
|
||||||
],
|
],
|
||||||
@ -155,7 +161,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
LanguageSelection(size: size),
|
LanguageSelection(size: size),
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: configurationDTO.screenPercentageSectionsMainPage != null ? size.height * (configurationDTO.screenPercentageSectionsMainPage! / 100) : size.height * 0.85,
|
height: appConfigurationLink?.screenPercentageSectionsMainPage != null ? size.height * (appConfigurationLink!.screenPercentageSectionsMainPage! / 100) : size.height * 0.85,
|
||||||
width: size.width * 0.9,
|
width: size.width * 0.9,
|
||||||
child: isInit ? FutureBuilder(
|
child: isInit ? FutureBuilder(
|
||||||
future: getSections(size, appContext),
|
future: getSections(size, appContext),
|
||||||
@ -197,7 +203,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
if (tabletAppContext.applicationInstanceDTO?.isAssistant == true)
|
if (tabletAppContext.isAssistantEnabled)
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 24,
|
bottom: 24,
|
||||||
right: 24,
|
right: 24,
|
||||||
@ -304,7 +310,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
var result = await showDialog(
|
var result = await showDialog(
|
||||||
builder: (BuildContext dialogContext) => AlertDialog(
|
builder: (BuildContext dialogContext) => AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
content: Container(
|
content: Container(
|
||||||
width: 400,
|
width: 400,
|
||||||
@ -330,9 +336,15 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
.where((a) => a.appType == AppType.Tablet)
|
.where((a) => a.appType == AppType.Tablet)
|
||||||
.firstOrNull;
|
.firstOrNull;
|
||||||
if (tabletInstance != null) {
|
if (tabletInstance != null) {
|
||||||
if (instanceDTO.isAssistant == true) {
|
// Assigné inconditionnellement : ce DTO ne sert plus seulement de drapeau
|
||||||
|
// d'assistant, il porte aussi les AppConfigurationLink d'où viennent
|
||||||
|
// roundedValue, isDate, isHour, isSectionImageBackground et
|
||||||
|
// screenPercentageSectionsMainPage depuis Postgres v3. Le laisser null
|
||||||
|
// sur une instance sans IA renverrait tous ces réglages à leurs valeurs
|
||||||
|
// par défaut, sans erreur visible.
|
||||||
tabletAppContext.applicationInstanceDTO = tabletInstance;
|
tabletAppContext.applicationInstanceDTO = tabletInstance;
|
||||||
}
|
tabletAppContext.isAssistantEnabled =
|
||||||
|
instanceDTO.isAssistant == true && tabletInstance.isAssistant == true;
|
||||||
if (tabletInstance.hasStats == true) {
|
if (tabletInstance.hasStats == true) {
|
||||||
tabletAppContext.statisticsService = StatisticsService(
|
tabletAppContext.statisticsService = StatisticsService(
|
||||||
clientAPI: tabletAppContext.clientAPI!,
|
clientAPI: tabletAppContext.clientAPI!,
|
||||||
@ -485,7 +497,7 @@ boxDecoration(AppContext appContext, SectionDTO section, bool isSelected, Object
|
|||||||
return BoxDecoration(
|
return BoxDecoration(
|
||||||
color: !isSelected ? kBackgroundLight : section.imageSource == null ? kBackgroundLight : null,
|
color: !isSelected ? kBackgroundLight : section.imageSource == null ? kBackgroundLight : null,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30.0),
|
||||||
image: section.imageSource != null || section.type == SectionType.Video ? new DecorationImage(
|
image: section.imageSource != null || section.type == SectionType.Video ? new DecorationImage(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withValues(alpha: 0.2), BlendMode.dstATop) : null,
|
colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withValues(alpha: 0.2), BlendMode.dstATop) : null,
|
||||||
@ -632,9 +644,9 @@ Widget getContent(TabletAppContext tabletAppContext, SectionDTO sectionSelected,
|
|||||||
case SectionType.Pdf :
|
case SectionType.Pdf :
|
||||||
PdfDTO pdfDTO = PdfDTO.fromJson(rawSectionData)!;
|
PdfDTO pdfDTO = PdfDTO.fromJson(rawSectionData)!;
|
||||||
return PDFViewWidget(section: pdfDTO);
|
return PDFViewWidget(section: pdfDTO);
|
||||||
case SectionType.Puzzle :
|
case SectionType.Game :
|
||||||
PuzzleDTO puzzleDTO = PuzzleDTO.fromJson(rawSectionData)!;
|
GameDTO gameDTO = GameDTO.fromJson(rawSectionData)!;
|
||||||
return PuzzleView(section: puzzleDTO);
|
return GamePage(section: gameDTO);
|
||||||
case SectionType.Agenda :
|
case SectionType.Agenda :
|
||||||
AgendaDTO agendaDTO = AgendaDTO.fromJson(rawSectionData)!;
|
AgendaDTO agendaDTO = AgendaDTO.fromJson(rawSectionData)!;
|
||||||
return AgendaView(section: agendaDTO);
|
return AgendaView(section: agendaDTO);
|
||||||
|
|||||||
@ -103,7 +103,7 @@ class _SectionPageDetailState extends State<SectionPageDetail> {
|
|||||||
decoration : BoxDecoration(
|
decoration : BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -179,7 +179,7 @@ class _SectionPageDetailState extends State<SectionPageDetail> {
|
|||||||
backgroundColor: kBackgroundColor,
|
backgroundColor: kBackgroundColor,
|
||||||
focusColor: kBackgroundColor,
|
focusColor: kBackgroundColor,
|
||||||
splashColor: kBackgroundColor,
|
splashColor: kBackgroundColor,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30.0)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
/*Navigator.of(context).pushReplacement(
|
/*Navigator.of(context).pushReplacement(
|
||||||
@ -215,7 +215,7 @@ class _SectionPageDetailState extends State<SectionPageDetail> {
|
|||||||
/*decoration: sectionSelected!.type != SectionType.Video && sectionSelected!.type != SectionType.Web && sectionSelected!.type != SectionType.Slider && sectionSelected!.type != SectionType.Map ? BoxDecoration(
|
/*decoration: sectionSelected!.type != SectionType.Video && sectionSelected!.type != SectionType.Web && sectionSelected!.type != SectionType.Slider && sectionSelected!.type != SectionType.Map ? BoxDecoration(
|
||||||
//color: kBackgroundLight,
|
//color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30.0),
|
||||||
/*boxShadow: [
|
/*boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -268,7 +268,7 @@ boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) {
|
|||||||
return BoxDecoration(
|
return BoxDecoration(
|
||||||
color: !isSelected ? kBackgroundLight : section.imageSource == null ? kBackgroundLight : null,
|
color: !isSelected ? kBackgroundLight : section.imageSource == null ? kBackgroundLight : null,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 30.0),
|
||||||
image: section.imageSource != null ? new DecorationImage(
|
image: section.imageSource != null ? new DecorationImage(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withValues(alpha: 0.2), BlendMode.dstATop) : null,
|
colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withValues(alpha: 0.2), BlendMode.dstATop) : null,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
|
import 'package:tablet_app/Helpers/geo.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_context.dart';
|
import 'package:tablet_app/Screens/Map/map_context.dart';
|
||||||
@ -50,7 +51,7 @@ class _FlutterMapViewState extends State<FlutterMapView> {
|
|||||||
Marker(
|
Marker(
|
||||||
width: 80.0,
|
width: 80.0,
|
||||||
height: 80.0,
|
height: 80.0,
|
||||||
point: LatLng(double.tryParse(point.latitude!)!, double.tryParse(point.longitude!)!),
|
point: LatLng(point.lat!, point.lng!),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
/*final mapContext = Provider.of<MapContext>(context, listen: false);
|
/*final mapContext = Provider.of<MapContext>(context, listen: false);
|
||||||
@ -85,7 +86,7 @@ class _FlutterMapViewState extends State<FlutterMapView> {
|
|||||||
|
|
||||||
if (mapController == null) { // mapContext.getSelectedPointForNavigate() != null
|
if (mapController == null) { // mapContext.getSelectedPointForNavigate() != null
|
||||||
/*var geoPoint = mapContext.getSelectedPointForNavigate();
|
/*var geoPoint = mapContext.getSelectedPointForNavigate();
|
||||||
var center = LatLng(double.tryParse(geoPoint.latitude!)!, double.tryParse(geoPoint.longitude!)!);*/
|
var center = LatLng(geoPoint.lat!, geoPoint.lng!);*/
|
||||||
mapController = MapController();
|
mapController = MapController();
|
||||||
|
|
||||||
//mapController!.move(center, widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12);
|
//mapController!.move(center, widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12);
|
||||||
@ -122,7 +123,7 @@ class _FlutterMapViewState extends State<FlutterMapView> {
|
|||||||
var geoPoint = mapContext.getSelectedPointForNavigate() as GeoPointDTO?;
|
var geoPoint = mapContext.getSelectedPointForNavigate() as GeoPointDTO?;
|
||||||
if (geoPoint != null && mapController != null) {
|
if (geoPoint != null && mapController != null) {
|
||||||
print("COUCOU IL FAUT NAVIGATE FLUTTER MAP");
|
print("COUCOU IL FAUT NAVIGATE FLUTTER MAP");
|
||||||
mapController!.move(LatLng(double.tryParse(geoPoint.latitude!)!, double.tryParse(geoPoint.longitude!)!), mapController!.camera.zoom/*, widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 16*/); // keep actual zoom
|
mapController!.move(LatLng(geoPoint.lat!, geoPoint.lng!), mapController!.camera.zoom/*, widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 16*/); // keep actual zoom
|
||||||
}
|
}
|
||||||
return SizedBox();
|
return SizedBox();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'dart:math';
|
|
||||||
//import 'package:animated_tree_view/animated_tree_view.dart';
|
//import 'package:animated_tree_view/animated_tree_view.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -8,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
//import 'package:generate_tree/generate_tree.dart';
|
//import 'package:generate_tree/generate_tree.dart';
|
||||||
//import 'package:generate_tree/treeNode.dart';
|
//import 'package:generate_tree/treeNode.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
|
import 'package:tablet_app/Helpers/geo.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Helpers/translationHelper.dart';
|
import 'package:tablet_app/Helpers/translationHelper.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
@ -77,9 +77,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
{
|
{
|
||||||
if(pointWithoutCat.title!.where((l) => l.language == widget.language).firstOrNull != null) {
|
if(pointWithoutCat.title!.where((l) => l.language == widget.language).firstOrNull != null) {
|
||||||
TreeNode nodeWithoutCat = TreeNode(
|
TreeNode nodeWithoutCat = TreeNode(
|
||||||
id: 000 + int.parse(
|
id: 000 + pointWithoutCat.coordinateKey,
|
||||||
(pointWithoutCat.latitude ?? '').substring(0, min(pointWithoutCat.latitude!.length, 10)).replaceAll(".", "").replaceAll("-","") + (pointWithoutCat.longitude ?? '').substring(0, min(pointWithoutCat.longitude!.length, 10)).replaceAll(".", "").replaceAll("-","")
|
|
||||||
),
|
|
||||||
title: parse(pointWithoutCat.title!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
|
title: parse(pointWithoutCat.title!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
|
||||||
children: [],
|
children: [],
|
||||||
checked: true, // default true
|
checked: true, // default true
|
||||||
@ -109,9 +107,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
for (var geoPoint in geoPoints.where((gp) => gp.categorieId != null)) {
|
for (var geoPoint in geoPoints.where((gp) => gp.categorieId != null)) {
|
||||||
if (geoPoint.categorieId == category.id && geoPoint.title!.where((l) => l.language == widget.language).firstOrNull != null) {
|
if (geoPoint.categorieId == category.id && geoPoint.title!.where((l) => l.language == widget.language).firstOrNull != null) {
|
||||||
TreeNode geoPointNode = TreeNode(
|
TreeNode geoPointNode = TreeNode(
|
||||||
id: 000 + int.parse(
|
id: 000 + geoPoint.coordinateKey,
|
||||||
(geoPoint.latitude ?? '').substring(0, min(geoPoint.latitude!.length, 10)).replaceAll(".", "").replaceAll("-", "") + (geoPoint.longitude ?? '').substring(0, min(geoPoint.longitude!.length, 10)).replaceAll(".", "").replaceAll("-", "")
|
|
||||||
),
|
|
||||||
title: parse(geoPoint.title!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
|
title: parse(geoPoint.title!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
|
||||||
checked: true, // default true
|
checked: true, // default true
|
||||||
show: false,
|
show: false,
|
||||||
@ -156,15 +152,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
if (childNode.checked) {
|
if (childNode.checked) {
|
||||||
var point = widget.geoPoints.firstWhere(
|
var point = widget.geoPoints.firstWhere(
|
||||||
(point) {
|
(point) {
|
||||||
String latitudePart = (point.latitude ?? '')
|
int combinedValue = point.coordinateKey;
|
||||||
.substring(0, min(point.latitude!.length, 10))
|
|
||||||
.replaceAll(".", "")
|
|
||||||
.replaceAll("-", "");
|
|
||||||
String longitudePart = (point.longitude ?? '')
|
|
||||||
.substring(0, min(point.longitude!.length, 10))
|
|
||||||
.replaceAll(".", "")
|
|
||||||
.replaceAll("-", "");
|
|
||||||
int combinedValue = int.parse(latitudePart + longitudePart);
|
|
||||||
|
|
||||||
return combinedValue == childNode.id;
|
return combinedValue == childNode.id;
|
||||||
},
|
},
|
||||||
@ -180,15 +168,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
if(node.checked) {
|
if(node.checked) {
|
||||||
var point = widget.geoPoints.firstWhere(
|
var point = widget.geoPoints.firstWhere(
|
||||||
(point) {
|
(point) {
|
||||||
String latitudePart = (point.latitude ?? '')
|
int combinedValue = point.coordinateKey;
|
||||||
.substring(0, min(point.latitude!.length, 10))
|
|
||||||
.replaceAll(".", "")
|
|
||||||
.replaceAll("-", "");
|
|
||||||
String longitudePart = (point.longitude ?? '')
|
|
||||||
.substring(0, min(point.longitude!.length, 10))
|
|
||||||
.replaceAll(".", "")
|
|
||||||
.replaceAll("-", "");
|
|
||||||
int combinedValue = int.parse(latitudePart + longitudePart);
|
|
||||||
return combinedValue == node.id;
|
return combinedValue == node.id;
|
||||||
},
|
},
|
||||||
orElse: () => GeoPointDTO(id: -1),
|
orElse: () => GeoPointDTO(id: -1),
|
||||||
@ -256,7 +236,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
width: size.width * 0.3,
|
width: size.width * 0.3,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundColor.withValues(alpha: 0.78),
|
color: kBackgroundColor.withValues(alpha: 0.78),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@ -285,7 +265,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
),
|
),
|
||||||
focusColor: primaryColor,
|
focusColor: primaryColor,
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
borderSide: BorderSide(color: primaryColor)),
|
borderSide: BorderSide(color: primaryColor)),
|
||||||
//labelStyle: TextStyle(color: primaryColor),
|
//labelStyle: TextStyle(color: primaryColor),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
@ -340,16 +320,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
|
|||||||
onClicked: (node, commonID) {
|
onClicked: (node, commonID) {
|
||||||
var selectedNode = widget.geoPoints.firstWhere(
|
var selectedNode = widget.geoPoints.firstWhere(
|
||||||
(point) {
|
(point) {
|
||||||
String latitudePart = (point.latitude ?? '')
|
int combinedValue = point.coordinateKey;
|
||||||
.substring(0, min(point.latitude!.length, 10))
|
|
||||||
.replaceAll(".", "")
|
|
||||||
.replaceAll("-", "");
|
|
||||||
String longitudePart = (point.longitude ?? '')
|
|
||||||
.substring(0, min(point.longitude!.length, 10))
|
|
||||||
.replaceAll(".", "")
|
|
||||||
.replaceAll("-", "");
|
|
||||||
|
|
||||||
int combinedValue = int.parse(latitudePart + longitudePart);
|
|
||||||
|
|
||||||
return combinedValue == commonID;
|
return combinedValue == commonID;
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
|
import 'package:tablet_app/Helpers/geo.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_context.dart';
|
import 'package:tablet_app/Screens/Map/map_context.dart';
|
||||||
@ -50,14 +51,14 @@ class _GoogleMapViewState extends State<GoogleMapView> {
|
|||||||
latitude: point.latitude,
|
latitude: point.latitude,
|
||||||
contents: point.contents
|
contents: point.contents
|
||||||
);*/
|
);*/
|
||||||
if (point.latitude != null && point.longitude != null) {
|
if (point.lat != null && point.lng != null) {
|
||||||
var icon = point.categorieId == null ? BitmapDescriptor.bytes(widget.icons.where((i) => i['id'] == null).first['icon']) : widget.icons.any((i) => i['id'] == point.categorieId) ? BitmapDescriptor.bytes(widget.icons.where((i) => i['id'] == point.categorieId).first['icon']) : BitmapDescriptor.bytes(widget.icons.where((i) => i['id'] == null).first['icon']); //widget.selectedMarkerIcon,;
|
var icon = point.categorieId == null ? BitmapDescriptor.bytes(widget.icons.where((i) => i['id'] == null).first['icon']) : widget.icons.any((i) => i['id'] == point.categorieId) ? BitmapDescriptor.bytes(widget.icons.where((i) => i['id'] == point.categorieId).first['icon']) : BitmapDescriptor.bytes(widget.icons.where((i) => i['id'] == null).first['icon']); //widget.selectedMarkerIcon,;
|
||||||
markers.add(Marker(
|
markers.add(Marker(
|
||||||
draggable: false,
|
draggable: false,
|
||||||
markerId: MarkerId(parse(textSansHTML.body!.text).documentElement!.text + point.latitude! + point.longitude!),
|
markerId: MarkerId(parse(textSansHTML.body!.text).documentElement!.text + point.lat!.toString() + point.lng!.toString()),
|
||||||
position: LatLng(
|
position: LatLng(
|
||||||
double.tryParse(point.latitude!)!,
|
point.lat!,
|
||||||
double.tryParse(point.longitude!)!,
|
point.lng!,
|
||||||
),
|
),
|
||||||
icon: icon, //widget.selectedMarkerIcon,
|
icon: icon, //widget.selectedMarkerIcon,
|
||||||
//widget.selectedMarkerIcon != null ? BitmapDescriptor.fromBytes(widget.selectedMarkerIcon!) : BitmapDescriptor.defaultMarker,
|
//widget.selectedMarkerIcon != null ? BitmapDescriptor.fromBytes(widget.selectedMarkerIcon!) : BitmapDescriptor.defaultMarker,
|
||||||
@ -182,7 +183,7 @@ class _GoogleMapViewState extends State<GoogleMapView> {
|
|||||||
_GoogleMapcontroller!.getZoomLevel().then((actualZoom) {
|
_GoogleMapcontroller!.getZoomLevel().then((actualZoom) {
|
||||||
_GoogleMapcontroller!.animateCamera(CameraUpdate.newCameraPosition(
|
_GoogleMapcontroller!.animateCamera(CameraUpdate.newCameraPosition(
|
||||||
CameraPosition(
|
CameraPosition(
|
||||||
target: LatLng(double.tryParse(geopoint.latitude!)!, double.tryParse(geopoint.longitude!)!),
|
target: LatLng(geopoint.lat!, geopoint.lng!),
|
||||||
tilt: 0.0,
|
tilt: 0.0,
|
||||||
bearing: 0.0,
|
bearing: 0.0,
|
||||||
zoom: actualZoom
|
zoom: actualZoom
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
|
import 'package:tablet_app/Helpers/geo.dart';
|
||||||
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mapBox;
|
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mapBox;
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
@ -40,7 +41,7 @@ class AnnotationClickListener extends mapBox.OnPointAnnotationClickListener {
|
|||||||
@override
|
@override
|
||||||
void onPointAnnotationClick(mapBox.PointAnnotation annotation) {
|
void onPointAnnotationClick(mapBox.PointAnnotation annotation) {
|
||||||
try{
|
try{
|
||||||
var markerToShow = markersList.firstWhere((ml) => "${parse(ml.title!.first.value).documentElement!.text}${ml.latitude}${ml.longitude}" == annotation.textField);
|
var markerToShow = markersList.firstWhere((ml) => "${parse(ml.title!.first.value).documentElement!.text}${ml.lat}${ml.lng}" == annotation.textField);
|
||||||
mapContext.setSelectedPoint(markerToShow);
|
mapContext.setSelectedPoint(markerToShow);
|
||||||
//mapContext.setSelectedPointForNavigate(markerToShow);
|
//mapContext.setSelectedPointForNavigate(markerToShow);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -76,11 +77,11 @@ class _MapBoxViewState extends State<MapBoxView> {
|
|||||||
options.add(mapBox.PointAnnotationOptions(
|
options.add(mapBox.PointAnnotationOptions(
|
||||||
geometry: mapBox.Point(
|
geometry: mapBox.Point(
|
||||||
coordinates: mapBox.Position(
|
coordinates: mapBox.Position(
|
||||||
double.tryParse(point.longitude!)!,
|
point.lng!,
|
||||||
double.tryParse(point.latitude!)!,
|
point.lat!,
|
||||||
)), // .toJson()
|
)), // .toJson()
|
||||||
iconSize: 1.3,
|
iconSize: 1.3,
|
||||||
textField: "${parse(textSansHTML.body!.text).documentElement!.text}${point.latitude}${point.longitude}",
|
textField: "${parse(textSansHTML.body!.text).documentElement!.text}${point.lat}${point.lng}",
|
||||||
textOpacity: 0.0,
|
textOpacity: 0.0,
|
||||||
iconOffset: [0.0, 0.0],
|
iconOffset: [0.0, 0.0],
|
||||||
symbolSortKey: 10,
|
symbolSortKey: 10,
|
||||||
@ -201,7 +202,7 @@ class _MapBoxViewState extends State<MapBoxView> {
|
|||||||
// TODO Handle zoomDetail
|
// TODO Handle zoomDetail
|
||||||
mapboxMap?.easeTo(
|
mapboxMap?.easeTo(
|
||||||
mapBox.CameraOptions(
|
mapBox.CameraOptions(
|
||||||
center: mapBox.Point(coordinates: mapBox.Position(double.tryParse(geoPoint.longitude!)!, double.tryParse(geoPoint.latitude!)!)), //.toJson()
|
center: mapBox.Point(coordinates: mapBox.Position(geoPoint.lng!, geoPoint.lat!)), //.toJson()
|
||||||
zoom: 16,
|
zoom: 16,
|
||||||
bearing: 0,
|
bearing: 0,
|
||||||
pitch: 3),
|
pitch: 3),
|
||||||
|
|||||||
@ -73,7 +73,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundColor, // Colors.amberAccent //kBackgroundLight,
|
color: kBackgroundColor, // Colors.amberAccent //kBackgroundLight,
|
||||||
//shape: BoxShape.rectangle,
|
//shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
/*boxShadow: [
|
/*boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -122,7 +122,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
selectedPoint.imageResourceId != null && selectedPoint.imageUrl != null ? ClipRRect(
|
selectedPoint.imageResourceId != null && selectedPoint.imageUrl != null ? ClipRRect(
|
||||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), bottomLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0), bottomLeft: Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -178,7 +178,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
width: size.width * 0.38,
|
width: size.width * 0.38,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
|
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
|
||||||
@ -215,7 +215,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
width: size.width * 0.38,
|
width: size.width * 0.38,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
|
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
|
||||||
@ -298,7 +298,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
width: size.width * 0.38,
|
width: size.width * 0.38,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(5),
|
padding: EdgeInsets.all(5),
|
||||||
@ -500,7 +500,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -584,13 +584,13 @@ getElementForResource(BuildContext context, AppContext appContext, ContentDTO i,
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
// title: Text(eventAgenda.name!),
|
// title: Text(eventAgenda.name!),
|
||||||
content: Container(
|
content: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
),
|
),
|
||||||
height: size.height * 0.8,
|
height: size.height * 0.8,
|
||||||
@ -598,7 +598,7 @@ getElementForResource(BuildContext context, AppContext appContext, ContentDTO i,
|
|||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
//color: Colors.yellow,
|
//color: Colors.yellow,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0)),
|
||||||
),
|
),
|
||||||
child: PhotoView(
|
child: PhotoView(
|
||||||
imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
||||||
@ -607,7 +607,7 @@ getElementForResource(BuildContext context, AppContext appContext, ContentDTO i,
|
|||||||
backgroundDecoration: BoxDecoration(
|
backgroundDecoration: BoxDecoration(
|
||||||
color: kBackgroundGrey,
|
color: kBackgroundGrey,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -624,7 +624,7 @@ getElementForResource(BuildContext context, AppContext appContext, ContentDTO i,
|
|||||||
image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0)),
|
||||||
/*border: Border.all(
|
/*border: Border.all(
|
||||||
color: kBackgroundGrey,
|
color: kBackgroundGrey,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
@ -645,13 +645,13 @@ getElementForResource(BuildContext context, AppContext appContext, ContentDTO i,
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
// title: Text(eventAgenda.name!),
|
// title: Text(eventAgenda.name!),
|
||||||
content: Container(
|
content: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
),
|
),
|
||||||
height: size.height * 0.8,
|
height: size.height * 0.8,
|
||||||
@ -669,7 +669,7 @@ getElementForResource(BuildContext context, AppContext appContext, ContentDTO i,
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.yellow,
|
color: Colors.yellow,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource?.url, type: i.resource?.type), appContext, false, true),
|
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource?.url, type: i.resource?.type), appContext, false, true),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -169,7 +169,7 @@ boxDecoration(AppContext appContext, SectionDTO section, bool isSelected, Object
|
|||||||
return BoxDecoration(
|
return BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0),
|
||||||
image: section.imageSource != null || section.type == SectionType.Video ? new DecorationImage(
|
image: section.imageSource != null || section.type == SectionType.Video ? new DecorationImage(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withValues(alpha: 0.35), BlendMode.dstATop) : null,
|
colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withValues(alpha: 0.35), BlendMode.dstATop) : null,
|
||||||
|
|||||||
@ -117,7 +117,7 @@ class _PDFViewWidget extends State<PDFViewWidget> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@ -185,7 +185,7 @@ class _PDFViewWidget extends State<PDFViewWidget> {
|
|||||||
builder: (context, value, _) {
|
builder: (context, value, _) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: primaryColor
|
color: primaryColor
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|||||||
@ -1,238 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:manager_api_new/api.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:tablet_app/Components/loading_common.dart';
|
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
|
||||||
import 'package:tablet_app/Screens/Puzzle/message_dialog.dart';
|
|
||||||
import 'package:tablet_app/app_context.dart';
|
|
||||||
import 'package:tablet_app/constants.dart';
|
|
||||||
import 'puzzle_piece.dart';
|
|
||||||
|
|
||||||
const IMAGE_PATH = 'image_path';
|
|
||||||
|
|
||||||
class PuzzleView extends StatefulWidget {
|
|
||||||
final PuzzleDTO section;
|
|
||||||
PuzzleView({required this.section});
|
|
||||||
|
|
||||||
@override
|
|
||||||
_PuzzleView createState() => _PuzzleView();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _PuzzleView extends State<PuzzleView> {
|
|
||||||
PuzzleDTO puzzleDTO = PuzzleDTO();
|
|
||||||
|
|
||||||
int allInPlaceCount = 0;
|
|
||||||
bool isFinished = false;
|
|
||||||
DateTime? _puzzleStartTime;
|
|
||||||
GlobalKey _widgetKey = GlobalKey();
|
|
||||||
Size? realWidgetSize;
|
|
||||||
List<Widget> pieces = [];
|
|
||||||
|
|
||||||
bool isSplittingImage = true;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
//puzzleDTO = PuzzleDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
|
||||||
puzzleDTO = widget.section;
|
|
||||||
puzzleDTO.rows = puzzleDTO.rows != null ? puzzleDTO.rows : 3;
|
|
||||||
puzzleDTO.cols = puzzleDTO.cols != null ? puzzleDTO.cols : 3;
|
|
||||||
_puzzleStartTime = DateTime.now();
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
Size size = MediaQuery.of(context).size;
|
|
||||||
final appContext = Provider.of<AppContext>(context, listen: false);
|
|
||||||
TabletAppContext tabletAppContext = appContext.getContext();
|
|
||||||
|
|
||||||
print(puzzleDTO.messageDebut);
|
|
||||||
TranslationAndResourceDTO? messageDebut = puzzleDTO.messageDebut != null && puzzleDTO.messageDebut!.length > 0 ? puzzleDTO.messageDebut!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null;
|
|
||||||
|
|
||||||
if(messageDebut != null) {
|
|
||||||
showMessage(messageDebut, appContext, context, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
getRealWidgetSize();
|
|
||||||
|
|
||||||
if(puzzleDTO.puzzleImage != null && puzzleDTO.puzzleImage!.url != null) {
|
|
||||||
//splitImage(Image.network(puzzleDTO.image!.resourceUrl!));
|
|
||||||
splitImage(CachedNetworkImage(
|
|
||||||
imageUrl: puzzleDTO.puzzleImage!.url!,
|
|
||||||
fit: BoxFit.fill,
|
|
||||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
isSplittingImage = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> getRealWidgetSize() async {
|
|
||||||
RenderBox renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox;
|
|
||||||
Size size = renderBox.size;
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
realWidgetSize = size;
|
|
||||||
});
|
|
||||||
print("Taille réelle du widget : $size");
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to find out the image size, to be used in the PuzzlePiece widget
|
|
||||||
/*Future<Size> getImageSize(CachedNetworkImage image) async {
|
|
||||||
Completer<Size> completer = Completer<Size>();
|
|
||||||
|
|
||||||
/*image.image
|
|
||||||
.resolve(const ImageConfiguration())
|
|
||||||
.addListener(ImageStreamListener((ImageInfo info, bool _) {
|
|
||||||
completer.complete(
|
|
||||||
Size(info.image.width.toDouble(), info.image.height.toDouble()));
|
|
||||||
}));*/
|
|
||||||
|
|
||||||
CachedNetworkImage(
|
|
||||||
imageUrl: 'https://example.com/image.jpg',
|
|
||||||
placeholder: (context, url) => CircularProgressIndicator(),
|
|
||||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
|
||||||
imageBuilder: (BuildContext context, ImageProvider imageProvider) {
|
|
||||||
Completer<Size> completer = Completer<Size>();
|
|
||||||
|
|
||||||
imageProvider
|
|
||||||
.resolve(const ImageConfiguration())
|
|
||||||
.addListener(ImageStreamListener((ImageInfo info, bool _) {
|
|
||||||
completer.complete(
|
|
||||||
Size(info.image.width.toDouble(), info.image.height.toDouble()));
|
|
||||||
}));
|
|
||||||
|
|
||||||
return CachedNetworkImage(
|
|
||||||
imageUrl: 'https://example.com/image.jpg',
|
|
||||||
placeholder: (context, url) => CircularProgressIndicator(),
|
|
||||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
|
||||||
imageBuilder: (context, imageProvider) {
|
|
||||||
return Image(
|
|
||||||
image: imageProvider,
|
|
||||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
|
||||||
if (loadingProgress == null) {
|
|
||||||
return child;
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
value: loadingProgress.expectedTotalBytes != null
|
|
||||||
? loadingProgress.cumulativeBytesLoaded / (loadingProgress.expectedTotalBytes ?? 1)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Size imageSize = await completer.future;
|
|
||||||
|
|
||||||
return imageSize;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// here we will split the image into small pieces
|
|
||||||
// using the rows and columns defined above; each piece will be added to a stack
|
|
||||||
void splitImage(CachedNetworkImage image) async {
|
|
||||||
//Size imageSize = await getImageSize(image);
|
|
||||||
//imageSize = realWidgetSize!;
|
|
||||||
Size imageSize = Size(realWidgetSize!.width * 1.25, realWidgetSize!.height * 1.25);
|
|
||||||
|
|
||||||
for (int x = 0; x < puzzleDTO.rows!; x++) {
|
|
||||||
for (int y = 0; y < puzzleDTO.cols!; y++) {
|
|
||||||
setState(() {
|
|
||||||
pieces.add(
|
|
||||||
PuzzlePiece(
|
|
||||||
key: GlobalKey(),
|
|
||||||
image: image,
|
|
||||||
imageSize: imageSize,
|
|
||||||
row: x,
|
|
||||||
col: y,
|
|
||||||
maxRow: puzzleDTO.rows!,
|
|
||||||
maxCol: puzzleDTO.cols!,
|
|
||||||
bringToTop: this.bringToTop,
|
|
||||||
sendToBack: this.sendToBack,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
isSplittingImage = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// when the pan of a piece starts, we need to bring it to the front of the stack
|
|
||||||
void bringToTop(Widget widget) {
|
|
||||||
setState(() {
|
|
||||||
pieces.remove(widget);
|
|
||||||
pieces.add(widget);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// when a piece reaches its final position,
|
|
||||||
// it will be sent to the back of the stack to not get in the way of other, still movable, pieces
|
|
||||||
void sendToBack(Widget widget) {
|
|
||||||
setState(() {
|
|
||||||
allInPlaceCount++;
|
|
||||||
isFinished = allInPlaceCount == puzzleDTO.rows! * puzzleDTO.cols!;
|
|
||||||
pieces.remove(widget);
|
|
||||||
pieces.insert(0, widget);
|
|
||||||
|
|
||||||
if(isFinished) {
|
|
||||||
Size size = MediaQuery.of(context).size;
|
|
||||||
final appContext = Provider.of<AppContext>(context, listen: false);
|
|
||||||
TabletAppContext tabletAppContext = appContext.getContext();
|
|
||||||
final duration = _puzzleStartTime != null ? DateTime.now().difference(_puzzleStartTime!).inSeconds : 0;
|
|
||||||
tabletAppContext.statisticsService?.track(
|
|
||||||
VisitEventType.gameComplete,
|
|
||||||
metadata: {'gameType': 'Puzzle', 'durationSeconds': duration},
|
|
||||||
);
|
|
||||||
TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null && puzzleDTO.messageFin!.length > 0 ? puzzleDTO.messageFin!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null;
|
|
||||||
|
|
||||||
if(messageFin != null) {
|
|
||||||
showMessage(messageFin, appContext, context, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final appContext = Provider.of<AppContext>(context);
|
|
||||||
TabletAppContext tabletAppContext = appContext.getContext();
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
//color: Colors.green,
|
|
||||||
child: Padding(
|
|
||||||
key: _widgetKey,
|
|
||||||
padding: const EdgeInsets.all(0.0),
|
|
||||||
child: isSplittingImage ? Center(child: LoadingCommon()) :
|
|
||||||
puzzleDTO.puzzleImage == null || puzzleDTO.puzzleImage!.url == null || realWidgetSize == null
|
|
||||||
? Center(child: Text("Aucune image à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect)))
|
|
||||||
: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(0.0),
|
|
||||||
child: Container(
|
|
||||||
width: tabletAppContext.puzzleSize != null && tabletAppContext.puzzleSize!.width > 0 ? tabletAppContext.puzzleSize!.width : realWidgetSize!.width * 0.8,
|
|
||||||
height: tabletAppContext.puzzleSize != null && tabletAppContext.puzzleSize!.height > 0 ? tabletAppContext.puzzleSize!.height +1.5 : realWidgetSize!.height * 0.85,
|
|
||||||
child: Stack(
|
|
||||||
children: pieces,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -151,7 +151,7 @@ class _QuizzView extends State<QuizzView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -190,7 +190,7 @@ class _QuizzView extends State<QuizzView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -290,7 +290,7 @@ class _QuizzView extends State<QuizzView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0),
|
||||||
image: i.resourceUrl != null ? new DecorationImage(
|
image: i.resourceUrl != null ? new DecorationImage(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
opacity: 0.35,
|
opacity: 0.35,
|
||||||
@ -322,7 +322,7 @@ class _QuizzView extends State<QuizzView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight, // Colors.orange,// kBackgroundLight,
|
color: kBackgroundLight, // Colors.orange,// kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -457,7 +457,7 @@ class _QuizzView extends State<QuizzView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: i.chosen == index ? primaryColor : kBackgroundLight,
|
color: i.chosen == index ? primaryColor : kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -563,13 +563,13 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
// title: Text(eventAgenda.name!),
|
// title: Text(eventAgenda.name!),
|
||||||
content: Container(
|
content: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
),
|
),
|
||||||
height: size.height * 0.8,
|
height: size.height * 0.8,
|
||||||
@ -577,7 +577,7 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
|||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xff7c94b6),
|
color: const Color(0xff7c94b6),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0)),
|
||||||
),
|
),
|
||||||
child: PhotoView(
|
child: PhotoView(
|
||||||
imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
||||||
@ -586,7 +586,7 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
|||||||
backgroundDecoration: BoxDecoration(
|
backgroundDecoration: BoxDecoration(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -603,7 +603,7 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
|||||||
image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0)),
|
||||||
/*border: Border.all(
|
/*border: Border.all(
|
||||||
color: kBackgroundGrey,
|
color: kBackgroundGrey,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
@ -624,13 +624,13 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0))
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
// title: Text(eventAgenda.name!),
|
// title: Text(eventAgenda.name!),
|
||||||
content: Container(
|
content: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: kBackgroundColor,
|
color: kBackgroundColor,
|
||||||
),
|
),
|
||||||
height: size.height * 0.8,
|
height: size.height * 0.8,
|
||||||
@ -648,7 +648,7 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
//color: kBackgroundSecondGrey,
|
//color: kBackgroundSecondGrey,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource!.url, type: i.resource!.type), appContext, false, true),
|
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource!.url, type: i.resource!.type), appContext, false, true),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -81,7 +81,7 @@ class _ShowReponsesWidget extends State<ShowReponsesWidget> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0),
|
||||||
image: i.resourceUrl != null ? new DecorationImage(
|
image: i.resourceUrl != null ? new DecorationImage(
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
opacity: 0.35,
|
opacity: 0.35,
|
||||||
@ -113,7 +113,7 @@ class _ShowReponsesWidget extends State<ShowReponsesWidget> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -177,7 +177,7 @@ class _ShowReponsesWidget extends State<ShowReponsesWidget> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: i.responsesSubDTO![index].isGood! ? kGreen : i.chosen == index ? kMainRed : kBackgroundLight,
|
color: i.responsesSubDTO![index].isGood! ? kGreen : i.chosen == index ? kMainRed : kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
|
|||||||
@ -79,7 +79,7 @@ class _SliderView extends State<SliderView> {
|
|||||||
margin: EdgeInsets.symmetric(horizontal: 5.0),
|
margin: EdgeInsets.symmetric(horizontal: 5.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
//color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? new Color(int.parse(configurationDTO.secondaryColor!.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null,
|
//color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? new Color(int.parse(configurationDTO.secondaryColor!.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
//border: Border.all(width: 0.3, color: kSecondGrey),
|
//border: Border.all(width: 0.3, color: kSecondGrey),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -137,7 +137,7 @@ class _SliderView extends State<SliderView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 10.0),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
@ -265,7 +265,7 @@ class _SliderView extends State<SliderView> {
|
|||||||
backgroundDecoration: BoxDecoration(
|
backgroundDecoration: BoxDecoration(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -277,7 +277,7 @@ class _SliderView extends State<SliderView> {
|
|||||||
backgroundDecoration: BoxDecoration(
|
backgroundDecoration: BoxDecoration(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -288,7 +288,7 @@ class _SliderView extends State<SliderView> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
//color: kBackgroundSecondGrey,
|
//color: kBackgroundSecondGrey,
|
||||||
//shape: BoxShape.rectangle,
|
//shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
|
borderRadius: BorderRadius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 15.0),
|
||||||
),
|
),
|
||||||
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource!.url, type: i.resource!.type), appContext, false, true),
|
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource!.url, type: i.resource!.type), appContext, false, true),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -149,7 +149,7 @@ class _WeatherViewState extends State<WeatherView> {
|
|||||||
|
|
||||||
return weatherData == null ? Center(child: Text("Aucune donnée à afficher")) : Container(
|
return weatherData == null ? Center(child: Text("Aucune donnée à afficher")) : Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topRight,
|
begin: Alignment.topRight,
|
||||||
end: Alignment.bottomLeft,
|
end: Alignment.bottomLeft,
|
||||||
@ -229,7 +229,7 @@ class _WeatherViewState extends State<WeatherView> {
|
|||||||
height: size.height * 0.25,
|
height: size.height * 0.25,
|
||||||
width: size.width * 0.6,
|
width: size.width * 0.6,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
//color: Colors.grey,
|
//color: Colors.grey,
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -251,7 +251,7 @@ class _WeatherViewState extends State<WeatherView> {
|
|||||||
height: size.height * 0.15,
|
height: size.height * 0.15,
|
||||||
width: size.width * 0.1,
|
width: size.width * 0.1,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: Colors.lightBlueAccent,
|
color: Colors.lightBlueAccent,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
@ -286,7 +286,7 @@ class _WeatherViewState extends State<WeatherView> {
|
|||||||
height: size.height * 0.3,
|
height: size.height * 0.3,
|
||||||
width: size.width * 0.75,
|
width: size.width * 0.75,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
//color: Colors.amber,
|
//color: Colors.amber,
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -308,7 +308,7 @@ class _WeatherViewState extends State<WeatherView> {
|
|||||||
height: size.height * 0.22,
|
height: size.height * 0.22,
|
||||||
width: size.width * 0.125,
|
width: size.width * 0.125,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.currentAppConfigurationLink?.roundedValue?.toDouble() ?? 20.0)),
|
||||||
color: Colors.lightBlue,
|
color: Colors.lightBlue,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user