Working Web, Pdf and Video type + misc and clean code
This commit is contained in:
parent
4946247812
commit
bddde86974
@ -4,8 +4,6 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
|
||||||
import 'package:mymuseum_visitapp/Screens/Quizz/quizz_page.dart';
|
|
||||||
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/constants.dart';
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
|||||||
@ -32,10 +32,11 @@ class _SearchBoxState extends State<SearchBox> {
|
|||||||
vertical: kDefaultPadding / 4, // 5 top and bottom
|
vertical: kDefaultPadding / 4, // 5 top and bottom
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white.withOpacity(0.4),
|
color: Colors.white.withValues(alpha: 0.4),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
cursorColor: kMainColor,
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
onChanged: widget.onChanged,
|
onChanged: widget.onChanged,
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(color: Colors.white),
|
||||||
|
|||||||
@ -26,10 +26,11 @@ class _SearchNumberBoxState extends State<SearchNumberBox> {
|
|||||||
vertical: kDefaultPadding / 4, // 5 top and bottom
|
vertical: kDefaultPadding / 4, // 5 top and bottom
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white.withOpacity(0.4),
|
color: Colors.white.withValues(alpha: 0.4),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
cursorColor: kMainColor,
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
onChanged: widget.onChanged,
|
onChanged: widget.onChanged,
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
|
|||||||
@ -6,9 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
|
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
|
||||||
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
|
||||||
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
||||||
|
|
||||||
// NOT USED ANYMORE
|
// NOT USED ANYMORE
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
|||||||
import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/audio_player.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Article/audio_player.dart';
|
||||||
import 'package:mymuseum_visitapp/Services/apiService.dart';
|
import 'package:mymuseum_visitapp/Services/apiService.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/client.dart';
|
import 'package:mymuseum_visitapp/client.dart';
|
||||||
124
lib/Screens/Sections/PDF/pdf_filter.dart
Normal file
124
lib/Screens/Sections/PDF/pdf_filter.dart
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
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:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class PdfFilter extends StatefulWidget {
|
||||||
|
final List<OrderedTranslationAndResourceDTO> pdfsList;
|
||||||
|
final Function(int?) onPDFSelected;
|
||||||
|
|
||||||
|
PdfFilter({required this.pdfsList, required this.onPDFSelected});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PdfFilterState createState() => _PdfFilterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PdfFilterState extends State<PdfFilter> with SingleTickerProviderStateMixin {
|
||||||
|
bool isExpanded = false;
|
||||||
|
int _selectedOrderPdf = 0;
|
||||||
|
late AnimationController _controller;
|
||||||
|
late Animation<double> _widthAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = AnimationController(vsync: this, duration: Duration(milliseconds: 300));
|
||||||
|
_widthAnimation = Tween<double>(begin: 40, end: 250).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleExpand() {
|
||||||
|
setState(() {
|
||||||
|
isExpanded = !isExpanded;
|
||||||
|
isExpanded ? _controller.forward() : _controller.reverse();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
VisitAppContext visitAppContext = appContext.getContext();
|
||||||
|
var currentLanguage = visitAppContext.language;
|
||||||
|
|
||||||
|
var primaryColor = visitAppContext.configuration?.primaryColor != null
|
||||||
|
? Color(int.parse(visitAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16))
|
||||||
|
: kSecondColor;
|
||||||
|
|
||||||
|
double rounded = visitAppContext.configuration?.roundedValue?.toDouble() ?? 20.0;
|
||||||
|
|
||||||
|
return AnimatedBuilder(
|
||||||
|
animation: _widthAnimation,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Container(
|
||||||
|
width: _widthAnimation.value,
|
||||||
|
height: isExpanded ? 300 : 75,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isExpanded ? primaryColor.withValues(alpha: 0.9) : primaryColor.withValues(alpha: 0.5) ,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topRight: Radius.circular(rounded),
|
||||||
|
bottomRight: Radius.circular(rounded),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: isExpanded
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.close, color: Colors.white),
|
||||||
|
onPressed: toggleExpand,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: widget.pdfsList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var pdfItem = widget.pdfsList[index];
|
||||||
|
var title = pdfItem.translationAndResourceDTOs!
|
||||||
|
.firstWhere((pfat) => pfat.language == currentLanguage)
|
||||||
|
.value;
|
||||||
|
|
||||||
|
bool isSelected = _selectedOrderPdf == pdfItem.order;
|
||||||
|
|
||||||
|
return ListTile(
|
||||||
|
title: HtmlWidget(
|
||||||
|
title!,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 15.0,
|
||||||
|
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
|
||||||
|
color: isSelected ? Colors.white : Colors.black,
|
||||||
|
fontFamily: 'Roboto',
|
||||||
|
),
|
||||||
|
customStylesBuilder: (element)
|
||||||
|
{
|
||||||
|
return {'text-align': 'center', 'font-family': "Roboto", '-webkit-line-clamp': "2"};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedOrderPdf = pdfItem.order!;
|
||||||
|
});
|
||||||
|
widget.onPDFSelected(_selectedOrderPdf);
|
||||||
|
toggleExpand(); // collapse after selection
|
||||||
|
},
|
||||||
|
tileColor: isSelected ? primaryColor.withValues(alpha: 0.6) : null,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: IconButton(
|
||||||
|
icon: const Icon(Icons.menu, color: Colors.white),
|
||||||
|
onPressed: toggleExpand,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
349
lib/Screens/Sections/PDF/pdf_view.dart
Normal file
349
lib/Screens/Sections/PDF/pdf_view.dart
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
//import 'dart:html';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_pdfview/flutter_pdfview.dart';
|
||||||
|
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||||
|
import 'package:manager_api_new/api.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Components/loading_common.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Screens/Sections/PDF/pdf_filter.dart';
|
||||||
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class PDFPage extends StatefulWidget {
|
||||||
|
final PdfDTO section;
|
||||||
|
const PDFPage({super.key, required this.section});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PDFPage createState() => _PDFPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PDFPage extends State<PDFPage> {
|
||||||
|
PdfDTO pdfDTO = PdfDTO();
|
||||||
|
String remotePDFpath = "";
|
||||||
|
final Completer<PDFViewController> _controller = Completer<PDFViewController>();
|
||||||
|
int? pages = 0;
|
||||||
|
int? currentPage = 0;
|
||||||
|
bool isReady = false;
|
||||||
|
String errorMessage = '';
|
||||||
|
late ValueNotifier<OrderedTranslationAndResourceDTO?> selectedPdf = ValueNotifier<OrderedTranslationAndResourceDTO?>(pdfDTO.pdfs!.first);
|
||||||
|
ValueNotifier<Map<String, int>> currentState = ValueNotifier<Map<String, int>>({'page': 0, 'total': 1});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
/*print(widget.section!.data);
|
||||||
|
pdfDTO = PdfDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
print(pdfDTO);*/
|
||||||
|
pdfDTO = widget.section;
|
||||||
|
pdfDTO.pdfs!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
/*createFileOfPdfUrl(pdfDTO.source_!).then((f) {
|
||||||
|
setState(() {
|
||||||
|
remotePDFpath = f.path;
|
||||||
|
print("paaath");
|
||||||
|
print(remotePDFpath);
|
||||||
|
});
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<File?> createFileOfPdfUrl(VisitAppContext visitAppContext, OrderedTranslationAndResourceDTO pdfFileDTO) async {
|
||||||
|
Completer<File?> completer = Completer();
|
||||||
|
|
||||||
|
if(pdfFileDTO.translationAndResourceDTOs!.firstWhere((pfat) => pfat.language == visitAppContext.language).resourceId == null) {
|
||||||
|
completer.complete(null);
|
||||||
|
} else {
|
||||||
|
var file = await _checkIfLocalResourceExists(visitAppContext, pdfFileDTO.translationAndResourceDTOs!.firstWhere((pfat) => pfat.language == visitAppContext.language).resourceId!);
|
||||||
|
|
||||||
|
if(file == null) {
|
||||||
|
print("Start download file from internet!");
|
||||||
|
try {
|
||||||
|
// "https://berlin2017.droidcon.cod.newthinking.net/sites/global.droidcon.cod.newthinking.net/files/media/documents/Flutter%20-%2060FPS%20UI%20of%20the%20future%20%20-%20DroidconDE%2017.pdf";
|
||||||
|
// final url = "https://pdfkit.org/docs/guide.pdf";
|
||||||
|
final url = pdfFileDTO.translationAndResourceDTOs!.firstWhere((pfat) => pfat.language == visitAppContext.language).resource!.url!;
|
||||||
|
final filename = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
var request = await HttpClient().getUrl(Uri.parse(url));
|
||||||
|
var response = await request.close();
|
||||||
|
var bytes = await consolidateHttpClientResponseBytes(response);
|
||||||
|
var dir = await getApplicationDocumentsDirectory();
|
||||||
|
print("Download files");
|
||||||
|
print("${dir.path}/$filename");
|
||||||
|
File file = File("${dir.path}/$filename");
|
||||||
|
|
||||||
|
await file.writeAsBytes(bytes, flush: true);
|
||||||
|
completer.complete(file);
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Error parsing asset file!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("FOUND FILE PDF");
|
||||||
|
completer.complete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
//_webView = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
VisitAppContext visitAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
var primaryColor = visitAppContext.configuration != null ? visitAppContext.configuration!.primaryColor != null ? new Color(int.parse(visitAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)) : kSecondColor : kSecondColor;
|
||||||
|
|
||||||
|
pdfDTO.pdfs!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
|
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: const LinearGradient(
|
||||||
|
begin: Alignment.centerRight,
|
||||||
|
end: Alignment.centerLeft,
|
||||||
|
colors: [
|
||||||
|
/*Color(0xFFDD79C2),
|
||||||
|
Color(0xFFB65FBE),
|
||||||
|
Color(0xFF9146BA),
|
||||||
|
Color(0xFF7633B8),
|
||||||
|
Color(0xFF6528B6),
|
||||||
|
Color(0xFF6025B6)*/
|
||||||
|
kMainColor0, //Color(0xFFf6b3c4)
|
||||||
|
kMainColor1,
|
||||||
|
kMainColor2,
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
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: const BoxDecoration(
|
||||||
|
color: kMainColor,
|
||||||
|
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: pdfDTO.pdfs != null && pdfDTO.pdfs!.isNotEmpty ?
|
||||||
|
Center(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: ValueListenableBuilder<OrderedTranslationAndResourceDTO?>(
|
||||||
|
valueListenable: selectedPdf,
|
||||||
|
builder: (context, value, _) {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: createFileOfPdfUrl(visitAppContext, value!),
|
||||||
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
|
print("snapshot.data");
|
||||||
|
print(snapshot.data);
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
if(snapshot.data == null) {
|
||||||
|
return Center(child: Text("Aucun fichier à afficher"));
|
||||||
|
} else {
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
PDFView(
|
||||||
|
filePath: snapshot.data.path,
|
||||||
|
enableSwipe: true,
|
||||||
|
fitEachPage: true,
|
||||||
|
swipeHorizontal: true,
|
||||||
|
autoSpacing: false,
|
||||||
|
pageFling: true,
|
||||||
|
fitPolicy: FitPolicy.HEIGHT,
|
||||||
|
onRender: (_pages) {
|
||||||
|
//setState(() {
|
||||||
|
pages = _pages;
|
||||||
|
isReady = true;
|
||||||
|
//});
|
||||||
|
},
|
||||||
|
onError: (error) {
|
||||||
|
print(error.toString());
|
||||||
|
},
|
||||||
|
onPageError: (page, error) {
|
||||||
|
print('$page: ${error.toString()}');
|
||||||
|
},
|
||||||
|
onViewCreated: (PDFViewController pdfViewController) {
|
||||||
|
//_controller.complete(pdfViewController);
|
||||||
|
},
|
||||||
|
onPageChanged: (int? page, int? total) {
|
||||||
|
currentPage = page;
|
||||||
|
pages = total;
|
||||||
|
currentState.value = {'page': page!, 'total': total!};
|
||||||
|
|
||||||
|
print('page change: $page/$total');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 20,
|
||||||
|
left: 20,
|
||||||
|
child: ValueListenableBuilder<Map<String, int>>(
|
||||||
|
valueListenable: currentState,
|
||||||
|
builder: (context, value, _) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
||||||
|
color: primaryColor
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(6.0),
|
||||||
|
child: Text("${value["page"]!+1}/${value["total"]!}",
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 20)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
child: LoadingCommon()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pdfDTO.pdfs!.length > 1 ? Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: PdfFilter(
|
||||||
|
pdfsList: pdfDTO.pdfs!,
|
||||||
|
onPDFSelected: (selectedOrder) {
|
||||||
|
selectedPdf.value = pdfDTO.pdfs!.firstWhere((pdf) => pdf.order == selectedOrder);
|
||||||
|
}),
|
||||||
|
): const SizedBox(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
) :
|
||||||
|
Center(child: Text("Aucun pdf à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
} //_webView
|
||||||
|
|
||||||
|
Future<File?> _checkIfLocalResourceExists(VisitAppContext visitAppContext, String resourceId) async {
|
||||||
|
try {
|
||||||
|
Directory? appDocumentsDirectory = Platform.isIOS ? await getApplicationDocumentsDirectory() : await getDownloadsDirectory();
|
||||||
|
String localPath = appDocumentsDirectory!.path;
|
||||||
|
Directory configurationDirectory = Directory('$localPath/${visitAppContext.configuration!.id}');
|
||||||
|
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
||||||
|
|
||||||
|
if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(resourceId))) {
|
||||||
|
File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(resourceId)).path);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("ERROR _checkIfLocalResourceExists PDF");
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
|||||||
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
//import 'package:mymuseum_visitapp/Screens/Quizz/drawPath.dart';
|
//import 'package:mymuseum_visitapp/Screens/Quizz/drawPath.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Quizz/questions_list.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Quiz/questions_list.dart';
|
||||||
//import 'package:mymuseum_visitapp/Screens/Quizz/showResponses.dart';
|
//import 'package:mymuseum_visitapp/Screens/Quizz/showResponses.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/client.dart';
|
import 'package:mymuseum_visitapp/client.dart';
|
||||||
263
lib/Screens/Sections/Video/video_view.dart
Normal file
263
lib/Screens/Sections/Video/video_view.dart
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.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:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
//import 'package:youtube_player_iframe/youtube_player_iframe.dart' as iframe;
|
||||||
|
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
||||||
|
|
||||||
|
class VideoPage extends StatefulWidget {
|
||||||
|
final VideoDTO section;
|
||||||
|
VideoPage({required this.section});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_VideoPage createState() => _VideoPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VideoPage extends State<VideoPage> {
|
||||||
|
//iframe.YoutubePlayer? _videoViewWeb;
|
||||||
|
YoutubePlayer? _videoView;
|
||||||
|
VideoDTO? videoDTO;
|
||||||
|
late YoutubePlayerController _controller;
|
||||||
|
bool isFullScreen = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
//print(widget.section!.data);
|
||||||
|
//videoDTO = VideoDTO.fromJson(jsonDecode(widget.section!.data!));
|
||||||
|
//print(videoDTO);
|
||||||
|
videoDTO= widget.section;
|
||||||
|
|
||||||
|
String? videoId;
|
||||||
|
if (videoDTO!.source_ != null && videoDTO!.source_!.isNotEmpty) {
|
||||||
|
videoId = YoutubePlayer.convertUrlToId(videoDTO!.source_!);
|
||||||
|
|
||||||
|
/*if (false) {
|
||||||
|
final _controllerWeb = iframe.YoutubePlayerController(
|
||||||
|
params: iframe.YoutubePlayerParams(
|
||||||
|
mute: false,
|
||||||
|
showControls: true,
|
||||||
|
showFullscreenButton: false,
|
||||||
|
loop: true,
|
||||||
|
showVideoAnnotations: false,
|
||||||
|
strictRelatedVideos: false,
|
||||||
|
enableKeyboard: false,
|
||||||
|
enableCaption: false,
|
||||||
|
pointerEvents: iframe.PointerEvents.auto
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_controllerWeb.loadVideo(videoDTO!.source_!);
|
||||||
|
|
||||||
|
_videoViewWeb = iframe.YoutubePlayer(
|
||||||
|
controller: _controllerWeb,
|
||||||
|
//showVideoProgressIndicator: false,
|
||||||
|
/*progressIndicatorColor: Colors.amber,
|
||||||
|
progressColors: ProgressBarColors(
|
||||||
|
playedColor: Colors.amber,
|
||||||
|
handleColor: Colors.amberAccent,
|
||||||
|
),*/
|
||||||
|
);
|
||||||
|
} else {*/
|
||||||
|
videoId = YoutubePlayer.convertUrlToId(videoDTO!.source_!);
|
||||||
|
_controller = YoutubePlayerController(
|
||||||
|
initialVideoId: videoId!,
|
||||||
|
flags: const YoutubePlayerFlags(
|
||||||
|
autoPlay: true,
|
||||||
|
controlsVisibleAtStart: false,
|
||||||
|
loop: true,
|
||||||
|
hideControls: false,
|
||||||
|
hideThumbnail: true,
|
||||||
|
),
|
||||||
|
)..addListener(_onYoutubePlayerChanged);
|
||||||
|
|
||||||
|
_videoView = YoutubePlayer(
|
||||||
|
controller: _controller,
|
||||||
|
//showVideoProgressIndicator: false,
|
||||||
|
progressIndicatorColor: kMainColor,
|
||||||
|
progressColors: const ProgressBarColors(
|
||||||
|
playedColor: kMainColor,
|
||||||
|
handleColor: kSecondColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
//}
|
||||||
|
_controller.toggleFullScreenMode();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onYoutubePlayerChanged() {
|
||||||
|
if (_controller.value.isFullScreen) {
|
||||||
|
setState(() {
|
||||||
|
isFullScreen = true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
isFullScreen = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_videoView = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
|
||||||
|
var title = TranslationHelper.get(widget.section.title, appContext.getContext());
|
||||||
|
String cleanedTitle = title.replaceAll('\n', ' ').replaceAll('<br>', ' ');
|
||||||
|
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
!isFullScreen ? 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: const LinearGradient(
|
||||||
|
begin: Alignment.centerRight,
|
||||||
|
end: Alignment.centerLeft,
|
||||||
|
colors: [
|
||||||
|
/*Color(0xFFDD79C2),
|
||||||
|
Color(0xFFB65FBE),
|
||||||
|
Color(0xFF9146BA),
|
||||||
|
Color(0xFF7633B8),
|
||||||
|
Color(0xFF6528B6),
|
||||||
|
Color(0xFF6025B6)*/
|
||||||
|
kMainColor0, //Color(0xFFf6b3c4)
|
||||||
|
kMainColor1,
|
||||||
|
kMainColor2,
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
image: widget.section.imageSource != null ? DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.65,
|
||||||
|
image: NetworkImage(
|
||||||
|
widget.section.imageSource!,
|
||||||
|
),
|
||||||
|
): null,
|
||||||
|
),
|
||||||
|
) : const SizedBox(),
|
||||||
|
Column(
|
||||||
|
children: <Widget>[
|
||||||
|
!isFullScreen ? 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: () {
|
||||||
|
_controller.dispose();
|
||||||
|
_videoView = null;
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: kMainColor,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: const Icon(Icons.arrow_back, size: 23, color: Colors.white)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
): const SizedBox(),
|
||||||
|
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: !isFullScreen ? const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(30),
|
||||||
|
topRight: Radius.circular(30),
|
||||||
|
): BorderRadius.zero,
|
||||||
|
child: videoDTO!.source_ != null && videoDTO!.source_!.isNotEmpty ?
|
||||||
|
_videoView :
|
||||||
|
const Center(child: Text("La vidéo ne peut pas être affichée, l'url est incorrecte", style: TextStyle(fontSize: kNoneInfoOrIncorrect))))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
isFullScreen ? Positioned(
|
||||||
|
top: 35,
|
||||||
|
left: 10,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
_controller.toggleFullScreenMode();
|
||||||
|
_controller.dispose();
|
||||||
|
_videoView = null;
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: kMainColor,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: const Icon(Icons.arrow_back, size: 23, color: Colors.white)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
): const SizedBox(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
242
lib/Screens/Sections/Web/web_page.dart
Normal file
242
lib/Screens/Sections/Web/web_page.dart
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.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:mymuseum_visitapp/Components/loading_common.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
||||||
|
|
||||||
|
class WebPage extends StatefulWidget {
|
||||||
|
final WebDTO section;
|
||||||
|
WebPage({required this.section});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_WebPage createState() => _WebPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _WebPage extends State<WebPage> {
|
||||||
|
//final IFrameElement _iframeElement = IFrameElement();
|
||||||
|
//WebView _webView;
|
||||||
|
WebDTO webDTO = WebDTO();
|
||||||
|
WebViewController? controller;
|
||||||
|
PlatformWebViewController? controllerWeb;
|
||||||
|
bool isLoading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
//print(widget.section!.data);
|
||||||
|
webDTO = widget.section;
|
||||||
|
//webDTO = WebDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
print(webDTO);
|
||||||
|
|
||||||
|
|
||||||
|
if(kIsWeb) {
|
||||||
|
/*_iframeElement.src = webDTO.source_!;
|
||||||
|
_iframeElement.style.border = 'none';
|
||||||
|
|
||||||
|
//ignore: undefined_prefixed_name
|
||||||
|
ui.platformViewRegistry.registerViewFactory(
|
||||||
|
webDTO.source_!, //use source as registered key to ensure uniqueness
|
||||||
|
(int viewId) => _iframeElement,
|
||||||
|
);*/
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(webDTO.source_ != null && webDTO.source_!.length > 0) {
|
||||||
|
try {
|
||||||
|
controller = WebViewController()
|
||||||
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||||
|
..setBackgroundColor(const Color(0x00000000))
|
||||||
|
..setNavigationDelegate(
|
||||||
|
NavigationDelegate(
|
||||||
|
onProgress: (int progress) {
|
||||||
|
// Update loading bar.
|
||||||
|
},
|
||||||
|
onPageStarted: (String url) {},
|
||||||
|
onPageFinished: (String url) {
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onWebResourceError: (WebResourceError error) {},
|
||||||
|
onNavigationRequest: (NavigationRequest request) {
|
||||||
|
Uri sourceUri = Uri.parse(webDTO.source_!);
|
||||||
|
Uri requestUri = Uri.parse(request.url);
|
||||||
|
|
||||||
|
if (requestUri.host != sourceUri.host) { // handle navigation to site
|
||||||
|
print('blocking navigation to $request}');
|
||||||
|
return NavigationDecision.prevent;
|
||||||
|
}
|
||||||
|
return NavigationDecision.navigate;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
..loadRequest(Uri.parse(webDTO.source_!));
|
||||||
|
} catch (e) {
|
||||||
|
print("Invalid source ${webDTO.source_}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
/*_webView = WebView(
|
||||||
|
initialUrl: webDTO.source_, //"https://my.matterport.com/show/?m=k8bvdezfHbT"
|
||||||
|
javascriptMode: JavascriptMode.unrestricted,
|
||||||
|
navigationDelegate: (NavigationRequest request) {
|
||||||
|
print(request.url);
|
||||||
|
print(webDTO.source_);
|
||||||
|
if (request.url != webDTO.source_) {
|
||||||
|
print('blocking navigation to $request}');
|
||||||
|
return NavigationDecision.prevent;
|
||||||
|
}
|
||||||
|
print('allowing navigation to $request');
|
||||||
|
return NavigationDecision.navigate;
|
||||||
|
}
|
||||||
|
);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
//_webView = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
|
||||||
|
var title = TranslationHelper.get(widget.section.title, appContext.getContext());
|
||||||
|
String cleanedTitle = title.replaceAll('\n', ' ').replaceAll('<br>', ' ');
|
||||||
|
|
||||||
|
return webDTO.source_ != null && webDTO.source_!.isNotEmpty ?
|
||||||
|
kIsWeb ?
|
||||||
|
HtmlElementView(
|
||||||
|
key: UniqueKey(),
|
||||||
|
viewType: webDTO.source_!,
|
||||||
|
) :
|
||||||
|
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: const LinearGradient(
|
||||||
|
begin: Alignment.centerRight,
|
||||||
|
end: Alignment.centerLeft,
|
||||||
|
colors: [
|
||||||
|
/*Color(0xFFDD79C2),
|
||||||
|
Color(0xFFB65FBE),
|
||||||
|
Color(0xFF9146BA),
|
||||||
|
Color(0xFF7633B8),
|
||||||
|
Color(0xFF6528B6),
|
||||||
|
Color(0xFF6025B6)*/
|
||||||
|
kMainColor0, //Color(0xFFf6b3c4)
|
||||||
|
kMainColor1,
|
||||||
|
kMainColor2,
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
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: const BoxDecoration(
|
||||||
|
color: kMainColor,
|
||||||
|
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: isLoading ? Center(child: SizedBox(height: size.height * 0.15, child: const LoadingCommon())) : WebViewWidget(controller: controller!))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
) :
|
||||||
|
const Center(child: Text("La page internet ne peut pas être affichée, l'url est incorrecte ou vide", style: TextStyle(fontSize: kNoneInfoOrIncorrect)));
|
||||||
|
}
|
||||||
|
} //_webView
|
||||||
@ -12,7 +12,7 @@ import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
|||||||
import 'package:mymuseum_visitapp/Models/beaconSection.dart';
|
import 'package:mymuseum_visitapp/Models/beaconSection.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Article/article_page.dart';
|
||||||
import 'package:mymuseum_visitapp/Services/apiService.dart';
|
import 'package:mymuseum_visitapp/Services/apiService.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/client.dart';
|
import 'package:mymuseum_visitapp/client.dart';
|
||||||
|
|||||||
@ -69,6 +69,22 @@ class _BodyState extends State<Body> {
|
|||||||
offset: Offset(0, 1), // changes position of shadow
|
offset: Offset(0, 1), // changes position of shadow
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
gradient: widget.configuration.imageSource == null ? const LinearGradient(
|
||||||
|
begin: Alignment.centerRight,
|
||||||
|
end: Alignment.centerLeft,
|
||||||
|
colors: [
|
||||||
|
/*Color(0xFFDD79C2),
|
||||||
|
Color(0xFFB65FBE),
|
||||||
|
Color(0xFF9146BA),
|
||||||
|
Color(0xFF7633B8),
|
||||||
|
Color(0xFF6528B6),
|
||||||
|
Color(0xFF6025B6)*/
|
||||||
|
kMainColor0, //Color(0xFFf6b3c4)
|
||||||
|
kMainColor1,
|
||||||
|
kMainColor2,
|
||||||
|
|
||||||
|
],
|
||||||
|
) : null,
|
||||||
image: widget.configuration.imageSource != null ? DecorationImage(
|
image: widget.configuration.imageSource != null ? DecorationImage(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
opacity: 0.65,
|
opacity: 0.65,
|
||||||
@ -170,6 +186,7 @@ class _BodyState extends State<Body> {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 0),
|
padding: const EdgeInsets.only(bottom: 0),
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
|
color: kMainColor,
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
if(!widget.configuration.isOffline!) {
|
if(!widget.configuration.isOffline!) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|||||||
@ -13,8 +13,8 @@ import 'package:mymuseum_visitapp/Helpers/requirement_state_controller.dart';
|
|||||||
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/beaconSection.dart';
|
import 'package:mymuseum_visitapp/Models/beaconSection.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Article/article_page.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Quizz/quizz_page.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Quiz/quizz_page.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Visit/beaconArticleFound.dart';
|
import 'package:mymuseum_visitapp/Screens/Visit/beaconArticleFound.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
|
|||||||
@ -7,20 +7,17 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
|
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/Loading.dart';
|
|
||||||
import 'package:mymuseum_visitapp/Components/loading_common.dart';
|
import 'package:mymuseum_visitapp/Components/loading_common.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/rounded_button.dart';
|
|
||||||
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
|
||||||
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/ResponseSubDTO.dart';
|
|
||||||
import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Article/article_page.dart';
|
||||||
//import 'package:mymuseum_visitapp/Screens/Quizz/drawPath.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/PDF/pdf_view.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Quizz/questions_list.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Quiz/quizz_page.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Quizz/quizz_page.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Video/video_view.dart';
|
||||||
//import 'package:mymuseum_visitapp/Screens/Quizz/showResponses.dart';
|
import 'package:mymuseum_visitapp/Screens/Sections/Web/web_page.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/client.dart';
|
import 'package:mymuseum_visitapp/client.dart';
|
||||||
import 'package:mymuseum_visitapp/constants.dart';
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
@ -67,7 +64,7 @@ class _SectionPageState extends State<SectionPage> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
appBar: test!.type != SectionType.Quiz && test.type != SectionType.Article ? CustomAppBar(
|
appBar: test!.type != SectionType.Quiz && test.type != SectionType.Article && test.type != SectionType.Web && test.type != SectionType.Pdf && test.type != SectionType.Video ? CustomAppBar(
|
||||||
title: sectionDTO != null ? TranslationHelper.get(sectionDTO!.title, visitAppContext) : "",
|
title: sectionDTO != null ? TranslationHelper.get(sectionDTO!.title, visitAppContext) : "",
|
||||||
isHomeButton: false,
|
isHomeButton: false,
|
||||||
) : null,
|
) : null,
|
||||||
@ -85,6 +82,15 @@ class _SectionPageState extends State<SectionPage> {
|
|||||||
case SectionType.Quiz:
|
case SectionType.Quiz:
|
||||||
QuizDTO quizDTO = QuizDTO.fromJson(sectionResult)!;
|
QuizDTO quizDTO = QuizDTO.fromJson(sectionResult)!;
|
||||||
return QuizPage(visitAppContextIn: widget.visitAppContextIn, quizDTO: quizDTO, resourcesModel: resourcesModel);
|
return QuizPage(visitAppContextIn: widget.visitAppContextIn, quizDTO: quizDTO, resourcesModel: resourcesModel);
|
||||||
|
case SectionType.Web:
|
||||||
|
WebDTO webDTO = WebDTO.fromJson(sectionResult)!;
|
||||||
|
return WebPage(section: webDTO);
|
||||||
|
case SectionType.Pdf:
|
||||||
|
PdfDTO pdfDTO = PdfDTO.fromJson(sectionResult)!;
|
||||||
|
return PDFPage(section: pdfDTO);
|
||||||
|
case SectionType.Video:
|
||||||
|
VideoDTO videoDTO = VideoDTO.fromJson(sectionResult)!;
|
||||||
|
return VideoPage(section: videoDTO);
|
||||||
default:
|
default:
|
||||||
return const Center(child: Text("Unsupported type"));
|
return const Center(child: Text("Unsupported type"));
|
||||||
}
|
}
|
||||||
|
|||||||
152
pubspec.lock
152
pubspec.lock
@ -318,6 +318,70 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.2"
|
version: "3.3.2"
|
||||||
|
flutter_inappwebview:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview
|
||||||
|
sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.5"
|
||||||
|
flutter_inappwebview_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_android
|
||||||
|
sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.3"
|
||||||
|
flutter_inappwebview_internal_annotations:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_internal_annotations
|
||||||
|
sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
flutter_inappwebview_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_ios
|
||||||
|
sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_inappwebview_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_macos
|
||||||
|
sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_inappwebview_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_platform_interface
|
||||||
|
sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0+1"
|
||||||
|
flutter_inappwebview_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_web
|
||||||
|
sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_inappwebview_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_windows
|
||||||
|
sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -331,6 +395,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_pdfview:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_pdfview
|
||||||
|
sha256: "51413e36ab3f1a2fe0edf97ebfa770e20182ea4a066bc9f292920330d9245c9d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0+1"
|
||||||
flutter_staggered_grid_view:
|
flutter_staggered_grid_view:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -377,10 +449,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
sha256: "7eae679e596a44fdf761853a706f74979f8dd3cd92cf4e23cae161fda091b847"
|
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.2.6"
|
version: "8.2.12"
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -521,10 +593,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
|
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.4.0"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -601,10 +673,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: just_audio_web
|
name: just_audio_web
|
||||||
sha256: "0edb481ad4aa1ff38f8c40f1a3576013c3420bf6669b686fe661627d49bc606c"
|
sha256: "9a98035b8b24b40749507687520ec5ab404e291d2b0937823ff45d92cb18d448"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.11"
|
version: "0.4.13"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -736,18 +808,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus
|
name: package_info_plus
|
||||||
sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0
|
sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.0"
|
version: "8.0.2"
|
||||||
package_info_plus_platform_interface:
|
package_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_platform_interface
|
name: package_info_plus_platform_interface
|
||||||
sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e
|
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.2.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -976,10 +1048,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
|
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.2.1"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1125,10 +1197,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
|
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "6.3.1"
|
||||||
url_launcher_android:
|
url_launcher_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1173,10 +1245,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
|
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.3"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1261,10 +1333,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: video_player_web
|
name: video_player_web
|
||||||
sha256: ff4d69a6614b03f055397c27a71c9d3ddea2b2a23d71b2ba0164f59ca32b8fe2
|
sha256: "881b375a934d8ebf868c7fb1423b2bfaa393a0a265fa3f733079a86536064a10"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.3"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1277,18 +1349,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: wakelock_plus
|
name: wakelock_plus
|
||||||
sha256: "14758533319a462ffb5aa3b7ddb198e59b29ac3b02da14173a1715d65d4e6e68"
|
sha256: "775c50f226ab43ff859b479acc73f11c0744bf345a782e83355c4d25df758803"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.5"
|
version: "1.3.0"
|
||||||
wakelock_plus_platform_interface:
|
wakelock_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: wakelock_plus_platform_interface
|
name: wakelock_plus_platform_interface
|
||||||
sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16"
|
sha256: e10444072e50dbc4999d7316fd303f7ea53d31c824aa5eb05d7ccbdd98985207
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.3"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1301,26 +1373,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "1.1.1"
|
||||||
web_socket:
|
web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket
|
name: web_socket
|
||||||
sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078"
|
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.5"
|
version: "1.0.1"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276
|
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.3"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1385,6 +1457,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
|
youtube_player_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: youtube_player_flutter
|
||||||
|
sha256: "4d14aa47f9c84929b5400a87ade4dcfdab87a2ca2e0b18ecc2ef852b1440e123"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.1.1"
|
||||||
|
youtube_player_iframe:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: youtube_player_iframe
|
||||||
|
sha256: "66020f7756accfb22b3297565d845f9bef14249c730dd51e1ec648fa155fb24a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.1"
|
||||||
|
youtube_player_iframe_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: youtube_player_iframe_web
|
||||||
|
sha256: "05222a228937932e7ee7a6171e8020fee4cd23d1c7bf6b4128c569484338c593"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.5.0 <4.0.0"
|
dart: ">=3.5.0 <4.0.0"
|
||||||
flutter: ">=3.24.0"
|
flutter: ">=3.24.0"
|
||||||
|
|||||||
@ -50,6 +50,10 @@ dependencies:
|
|||||||
webview_flutter: ^4.10.0
|
webview_flutter: ^4.10.0
|
||||||
ar_flutter_plugin: ^0.7.3
|
ar_flutter_plugin: ^0.7.3
|
||||||
|
|
||||||
|
flutter_pdfview: ^1.4.0+1
|
||||||
|
youtube_player_flutter: ^9.1.1
|
||||||
|
youtube_player_iframe: ^5.2.1
|
||||||
|
|
||||||
# Specific mobile
|
# Specific mobile
|
||||||
qr_code_scanner: ^1.0.1 #not in web
|
qr_code_scanner: ^1.0.1 #not in web
|
||||||
sqflite: #not in web
|
sqflite: #not in web
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user