From 3a29ec87152ac06bd0484080429a98726f4283ef Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Tue, 31 Oct 2023 21:08:49 +0100 Subject: [PATCH] Add language icons + quill editor for title, descriptions --- assets/images/ar.png | Bin 0 -> 26167 bytes assets/images/cn.png | Bin 0 -> 4079 bytes assets/images/de.png | Bin 0 -> 225 bytes assets/images/en.png | Bin 0 -> 2032 bytes assets/images/es.png | Bin 0 -> 30073 bytes assets/images/fr.png | Bin 0 -> 233 bytes assets/images/it.png | Bin 0 -> 705 bytes assets/images/nl.png | Bin 0 -> 219 bytes assets/images/pl.png | Bin 0 -> 189 bytes assets/images/uk.png | Bin 0 -> 279 bytes lib/Components/audio_input_container.dart | 15 +- lib/Components/flag_decoration.dart | 36 ++ lib/Components/multi_input_modal.dart | 93 ++--- .../multi_select_dropdown_container.dart | 6 +- .../multi_string_input_html_modal.dart | 269 +++------------ .../translation_input_container.dart | 239 +++++++++++++ .../SubSection/Article/article_config.dart | 1 + .../Map/showNewOrUpdateGeoPoint.dart | 106 +++--- .../SubSection/Menu/showEditSubSection.dart | 110 +++--- .../Quizz/new_update_question_quizz.dart | 116 +++---- .../Quizz/new_update_response_quizz.dart | 86 ++--- .../Quizz/new_update_score_quizz.dart | 79 ++--- .../SubSection/Quizz/quizz_answer_list.dart | 47 ++- .../Slider/listView_card_image.dart | 10 +- .../Slider/new_update_image_slider.dart | 125 +++---- .../Section/section_detail_screen.dart | 1 + .../configuration_detail_screen.dart | 1 + linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 8 + pubspec.lock | 320 ++++++++++++++++++ pubspec.yaml | 2 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 34 files changed, 979 insertions(+), 700 deletions(-) create mode 100644 assets/images/ar.png create mode 100644 assets/images/cn.png create mode 100644 assets/images/de.png create mode 100644 assets/images/en.png create mode 100644 assets/images/es.png create mode 100644 assets/images/fr.png create mode 100644 assets/images/it.png create mode 100644 assets/images/nl.png create mode 100644 assets/images/pl.png create mode 100644 assets/images/uk.png create mode 100644 lib/Components/flag_decoration.dart create mode 100644 lib/Components/translation_input_container.dart diff --git a/assets/images/ar.png b/assets/images/ar.png new file mode 100644 index 0000000000000000000000000000000000000000..395928c08536e78ec84cee142205fafcfb4440a9 GIT binary patch literal 26167 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 CuGr!L literal 0 HcmV?d00001 diff --git a/assets/images/de.png b/assets/images/de.png new file mode 100644 index 0000000000000000000000000000000000000000..c4caaaf186a7db0af2c63a29d52a8b63542f28c9 GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FU8Aw(ga_0k5q5(c3u0Z<#IflDH@;bu{H-?uC z43iibR@g0(0!p-dx;TbZ+r)fMvt>23DN}M(&6M`&*=56x=TL;7I|hf`W4& z&CgypDW7bcvi@J$k2{8h00H)+wrXo?tM-q5)&1*Vzv}nv?pM{X z8E5g{J9Uh8U@+KDpVMA}(73wQzt{$0vwZ~u2Gh85);IVhY+w53<|Y?u0}<{n8;JMn zTEdKO@{Er_9;mG=m7k7!uSmufJ^VY5IM=9ehVU^PYipd3;^l#17>X=(#jA$Jxy%o9 z<+bC)+t3AyNNO78iMN;q$TuE(d0o+GmVOq}GiQ zvhEkQa}5p*NoE(S>-7#$C6`l#BQu|drsL9Tbq-J$-ZorKtr1^Hg0Aq#VNYp1S-l`r zaQ{$$mV*zAM5oU!3kIhjv&ND$2Rwp=?g2`k;B#Z!=-7NtLEHDY-wmC;AoBkEN7$~h zN!g%y_9JhC`cq>n<2U4yJ21T)%Km|+fA-FmR!1gP01uuCoX{@Qhs z@M`4Twcp^{kDfKVHK^ai zs8g1(X-yJOmBi`lkem+heyym=t`D>e#{G2Wq>QqDSCzA8_|Q{yovx2^IbFkbrMph+ zJ9Kz$IFKkVYMoXp4O8=#3%0Kky^H$_5#nIMF!gK~z2za>{;8Kw|7Y6ar1YZXUW(*`@Dh zu<>1%1cyynyWaP85?yi~EA98sqsu{>zcW(7k#vml2~Uz$)U!Q5XEwGw=;#Gd(X{qnur#p{7qYIZ-p;-1_< zJrJ^gI0BW@=1I=Jk%PM`ouW`u(m|~l)m~0>dRPK+p&h8HED6f*__LBrQpssC&Z{q# z;d@2{+v4q@obFdk+ARg|%1nxqv7Aanabfc2jA%k)?Cg9FU)n|DN~P7!QTrOgu^hWa zN#X-vJ7QrrJ5o*GUeIuWjd$VQ`h+tht-9T~UxmakwN~CbC+h$xsx-K5dVhuCvCDU> z_TULUsyuB#ZtmE|K+&hxQ(e>2@W<9W8)98}mlpHy9>vUk&-W=?YCQqnfb`WTlcNf8 z@ykk)%WBJQ#$ZlZ-YYB4I6yNGQCu$XY%wlHh|SDQ@)BqBO(IVF|D4R0dN`W^&u{Bv zw}36$n%(3_P}uQJSpzq_N!0^Oe+n?;3CMNJj^Af%OfWIc)}h^#RZ6h83H|@Sg2D4X86PcEiHjLNaxyug@o8zuEy}sC0BP(6uHsMfCqr0D(uW{O< zCpG``R-p66ZZlgt#7`T)^y8z_4tf-E#&^@f(XpZ;pEkO-+E?iTrdW=Ncj2!G-$asuD%T?$tmp;n>PIIQ{Awlj89iXxW~58oht5b0&k?T{ zG`hw{7gCg_$b}D*ai9?$NqQSMNfez3vC254?N3NZdT8e(%t5o=Ng~rIyNrn%Yv70G zCW96~zT@~A*7GZ41f#3~b}R++j|~@IsI#9i8_l+QpURGH@Xf>#9WcWyilI_{}B&7wz_Y#vG(sFtVB z^$upC1zIt>09+F1%5wUu$@*Q5G!FOVNp1`|+#tdYg?rr@P$#2%F}C~5Ehcaj67>R3 zJ=y3QcZ^)Lh$G|F%G|F>Y>+n9KQ0B!kVR+EDtWg5c}=3=y$2u}{DR@wZon)#R7 z+IL*I2gp1XB0tsWKCK9-Mub+U1b%9;m>}Y{ZDX%(3%C#(ytkF(X?z}u^gQZWz?|-# b(1e-Zjb&Xz47`JW6qwIRyjPXy`K*5dHTxcW literal 0 HcmV?d00001 diff --git a/assets/images/es.png b/assets/images/es.png new file mode 100644 index 0000000000000000000000000000000000000000..f19308d5b49ae90764d34af7e2bff8985bd88797 GIT binary patch literal 30073 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 DY@b^o literal 0 HcmV?d00001 diff --git a/assets/images/fr.png b/assets/images/fr.png new file mode 100644 index 0000000000000000000000000000000000000000..feff21014358db4f4f59d35fce925ee3f8483049 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FU8Aw(ga_0k5q5(c3uK)l4XHcH{R?~9j*4sa~ z?_rRf@J8MsHNK+-sG#4|#WAGf*4wj&j0^@G%mzAV4joBg_#e07!enK`2~{gshWwv$ lH*fpxw`IF&PyPM0uhYB#;db4>NkFGDc)I$ztaD0e0szrAdMf|` literal 0 HcmV?d00001 diff --git a/assets/images/it.png b/assets/images/it.png new file mode 100644 index 0000000000000000000000000000000000000000..81013f0ee15398462da3ba3ed529602750491cff GIT binary patch literal 705 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7+9Er6kFKIlR%0;z$e6&VUnBArrLAb=6AD- z|NsAg%lhXIpcG@0x4R2Vf5y!~pr!;*7srr_TW>EIGBPMIFc~<_XwbT4KUwp~HV$vG xbJ9CvI~W+5SU3a}92!O$qk%wTO31j)|6B9vyM22Vt^yMtgQu&X%Q~loCICIEY5@QM literal 0 HcmV?d00001 diff --git a/assets/images/nl.png b/assets/images/nl.png new file mode 100644 index 0000000000000000000000000000000000000000..e4563020d6dad7798fab7b059511ecd44d3d873e GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FU8Aw(ga_0k5q5(c3uK)l4f3j)YmIF7|$!I9L zb*~bV6Sr%#5N4AGDrod{aSW-r_4e#Rh64ryEC)hYIEgG0Xw^C*zwo})8{0G%wcVO! zyYJ?0zx@^uwft><@VsR})VXbLJAo8ifKQ0)9TA)V|Np<=VR{KD z!kFak?!x$=N%tO*lj`Z>7*cWT?HNa21_ln61(*NLHEq#1=Wy`Nvtnv=P!Ql?A(;Xi bivrf`Uii!OKbF6<3nc96>gTe~DWM4f!0{_8 literal 0 HcmV?d00001 diff --git a/assets/images/uk.png b/assets/images/uk.png new file mode 100644 index 0000000000000000000000000000000000000000..8219610a6758affcfe14f63bb72b3290ac88a2a4 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7?_xWRHv9tCXnI`@Ck8c2;cGlI>Z0}{{^<% z_yYwQlf2zsn9{gwQh=O2o-U3d6}R4=Gh}37;9*kmUROW$=m!Cz2|zi#;PW~khXDl( Z;7 literal 0 HcmV?d00001 diff --git a/lib/Components/audio_input_container.dart b/lib/Components/audio_input_container.dart index 2281716..809d4cb 100644 --- a/lib/Components/audio_input_container.dart +++ b/lib/Components/audio_input_container.dart @@ -10,7 +10,7 @@ import 'package:provider/provider.dart'; class AudioInputContainer extends StatefulWidget { final Color color; - final String label; + final String? label; final String? initialValue; final ValueChanged onChanged; final BoxFit imageFit; @@ -19,7 +19,7 @@ class AudioInputContainer extends StatefulWidget { const AudioInputContainer({ Key? key, this.color = kSecond, - required this.label, + this.label, this.initialValue, required this.onChanged, this.imageFit = BoxFit.cover, @@ -45,8 +45,10 @@ class _AudioInputContainerState extends State { Size size = MediaQuery.of(context).size; return Container( child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Align( + if(widget.label != null) Align( alignment: AlignmentDirectional.centerStart, child: AutoSizeText( widget.label!, @@ -61,8 +63,8 @@ class _AudioInputContainerState extends State { child: Padding( padding: EdgeInsets.only(left: widget.isSmall ? 5 : 10, top: 10, bottom: 10), child: Container( - width: size.width *0.08, - height: size.width *0.08, + width: size.width *0.125, + height: size.width *0.06, child: InkWell( onTap: () async { ResourceDTO? result = await showSelectResourceModal( @@ -131,6 +133,7 @@ class _AudioInputContainerState extends State { "Choisir un fichier audio", style: TextStyle(color: kWhite), maxLines: 1, + textAlign: TextAlign.center, ) ), ) @@ -148,7 +151,7 @@ class _AudioInputContainerState extends State { return BoxDecoration( shape: BoxShape.rectangle, color: kWhite, - borderRadius: BorderRadius.circular(30.0), + borderRadius: BorderRadius.circular(20.0), /*image: new DecorationImage( fit: widget.imageFit, image: resourceDTO.type != null ? new NetworkImage( diff --git a/lib/Components/flag_decoration.dart b/lib/Components/flag_decoration.dart new file mode 100644 index 0000000..f8fbff6 --- /dev/null +++ b/lib/Components/flag_decoration.dart @@ -0,0 +1,36 @@ +import 'package:flare_flutter/flare_actor.dart'; +import 'package:flutter/material.dart'; +import 'package:manager_app/constants.dart'; + +class FlagDecoration extends StatelessWidget { + final String language; + FlagDecoration({Key? key, required this.language}) : super(key: key); + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.of(context).size; + return Container( + width: 35, + height: 35, + decoration: BoxDecoration( + color: kBackgroundColor, + shape: BoxShape.circle, + //border: Border.all(width: 1.5, color: kSecondGrey), + image: DecorationImage( + fit: BoxFit.contain, + image: AssetImage("assets/images/"+language.toLowerCase()+".png")/*Svg( + "assets/images/"+language.toLowerCase()+".svg", + )*/, //AssetImage("assets/images/"+language+".png"), + ), + boxShadow: const [ + BoxShadow( + color: kBackgroundColor, + spreadRadius: 0.5, + blurRadius: 5, + offset: Offset(0, 1.5), // changes position of shadow + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/Components/multi_input_modal.dart b/lib/Components/multi_input_modal.dart index 700ab41..3f4bcb7 100644 --- a/lib/Components/multi_input_modal.dart +++ b/lib/Components/multi_input_modal.dart @@ -13,7 +13,7 @@ import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; import 'audio_input_container.dart'; - +import 'flag_decoration.dart'; showMultiStringInput (String label, String modalLabel, bool isTitle, List values, List newValues, Function onGetResult, int maxLines, bool isAudio, BuildContext context) { /*Function onSelect,*/ showDialog( @@ -51,36 +51,42 @@ showMultiStringInput (String label, String modalLabel, bool isTitle, List element.language == language).first.value, - color: kPrimaryColor, - onChanged: (ResourceDTO resource) { - newValues.where((element) => element.language == language).first.value = resource.id; - }, + width: MediaQuery.of(context).size.width *0.15, + height: 100, + //color: Colors.blueAccent, + child: Center( + child: AudioInputContainer( + //label: "Audio :", + initialValue: newValues.where((element) => element.language == language).first.value, + color: kPrimaryColor, + onChanged: (ResourceDTO resource) { + newValues.where((element) => element.language == language).first.value = resource.id; + }, + ), ), ), ], @@ -150,6 +160,7 @@ getTranslations(BuildContext context, AppContext appContext, String label, bool } return translations; } + /* showValues(List newValues) { List valuesToShow = new List(); diff --git a/lib/Components/multi_select_dropdown_container.dart b/lib/Components/multi_select_dropdown_container.dart index a8acee1..232a201 100644 --- a/lib/Components/multi_select_dropdown_container.dart +++ b/lib/Components/multi_select_dropdown_container.dart @@ -6,9 +6,12 @@ import 'package:multi_select_flutter/dialog/multi_select_dialog_field.dart'; import 'package:multi_select_flutter/util/multi_select_item.dart'; import 'package:multi_select_flutter/util/multi_select_list_type.dart'; +import 'flag_decoration.dart'; + class MultiSelectDropdownContainer extends StatelessWidget { final Color color; final String label; + final String labelHint; final List values; final List initialValue; final bool isMultiple; @@ -19,6 +22,7 @@ class MultiSelectDropdownContainer extends StatelessWidget { Key? key, this.color = kSecond, required this.label, + this.labelHint = "Veuillez sélectionner une langue", required this.values, required this.initialValue, required this.isMultiple, @@ -57,7 +61,7 @@ class MultiSelectDropdownContainer extends StatelessWidget { searchable: true, chipDisplay: MultiSelectChipDisplay.none(), selectedColor: kPrimaryColor, - title: Text("Veuillez sélectionner une langue"), + title: Text(labelHint), dialogHeight: size.height *0.4, dialogWidth: size.width *0.2, onSelectionChanged: (selectedList) { diff --git a/lib/Components/multi_string_input_html_modal.dart b/lib/Components/multi_string_input_html_modal.dart index 1297e8a..8905509 100644 --- a/lib/Components/multi_string_input_html_modal.dart +++ b/lib/Components/multi_string_input_html_modal.dart @@ -1,241 +1,62 @@ import 'dart:ui'; - -import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Components/rounded_button.dart'; -import 'package:manager_app/Components/text_form_input_container.dart'; -import 'package:manager_app/Models/managerContext.dart'; -import 'package:manager_app/Screens/Resources/select_resource_modal.dart'; -import 'package:manager_app/app_context.dart'; +import 'package:manager_app/Components/translation_input_container.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_api_new/api.dart'; import 'package:collection/collection.dart'; -import 'package:provider/provider.dart'; -import 'package:quill_html_editor/quill_html_editor.dart'; -import 'audio_input_container.dart'; - - -showMultiStringInputHTML (String label, String modalLabel, bool isTitle, List values, List newValues, Function onGetResult, int maxLines, bool isAudio, BuildContext context) { /*Function onSelect,*/ - QuillEditorController controllerQuill = QuillEditorController(); +showMultiStringInputHTML (String label, String modalLabel, bool isTitle, List values, List newValues, Function onGetResult, int maxLines, bool isAudio, BuildContext context) { showDialog( - builder: (BuildContext context) => AlertDialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(20.0)) - ), + builder: (BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20.0)) + ), title: Center(child: Text(modalLabel)), content: SingleChildScrollView( - child: Column( - children: [ - Container( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: getTranslations(context, Provider.of(context), controllerQuill, label, isTitle, isAudio, newValues), - ), - ), - ), - /*Container( - width: 500, - height: 200, - child: TranslationTab( - translations: newValues, - maxLines: maxLines - ) - ),*/ - /*Column( - children: showValues(newValues), - ),*/ - ], - ) - ), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - width: 180, - height: 70, - child: RoundedButton( - text: "Annuler", - icon: Icons.undo, - color: kSecond, - press: () { - onGetResult(values); - Navigator.of(context).pop(); - }, - fontSize: 20, - ), - ), - Container( - width: 180, - height: 70, - child: RoundedButton( - text: "Valider", - icon: Icons.check, - color: kPrimaryColor, - textColor: kWhite, - press: () { - Function deepEq = const DeepCollectionEquality().equals; - if (!deepEq(values, newValues)) { - onGetResult(newValues); - } - Navigator.of(context).pop(); - }, - fontSize: 20, - ), - ), - ], + child: TranslationInputContainer(isTitle: isTitle, values: values, newValues: newValues, onGetResult: onGetResult, maxLines: maxLines, isAudio: isAudio) ), - ], - ), context: context - ); -} - -getTranslations(BuildContext context, AppContext appContext, QuillEditorController controllerQuill, String label, bool isTitle, bool isAudio, List newValues) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - final customToolBarList = isTitle ? [ - ToolBarStyle.bold, - ToolBarStyle.italic, - ToolBarStyle.color, - ToolBarStyle.background, - ToolBarStyle.clean - ] : [ - ToolBarStyle.bold, - ToolBarStyle.italic, - ToolBarStyle.align, - ToolBarStyle.color, - ToolBarStyle.background, - ToolBarStyle.listBullet, - ToolBarStyle.listOrdered, - ToolBarStyle.clean - ]; - - var language = managerAppContext.selectedConfiguration!.languages![0]; - //for(var language in managerAppContext.selectedConfiguration!.languages!) { - translations.add( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.10, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - width: MediaQuery.of(context).size.width *0.5, - height: MediaQuery.of(context).size.height *0.5, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - !isAudio ? - Column( - children: [ - ToolBar( - toolBarColor: Colors.cyan.shade50, - activeIconColor: Colors.green, - padding: const EdgeInsets.all(8), - iconSize: 20, - toolBarConfig: customToolBarList, - controller: controllerQuill, - customButtons: [], - ), - QuillHtmlEditor( - text: newValues.where((element) => element.language == language).first.value!, - hintText: 'Hint text goes here', - controller: controllerQuill, - isEnabled: true, - minHeight: 300, - /*textStyle: _editorTextStyle, - hintTextStyle: _hintTextStyle,*/ - hintTextAlign: TextAlign.start, - padding: const EdgeInsets.only(left: 10, top: 5), - hintTextPadding: EdgeInsets.zero, - backgroundColor: kSecond, - onFocusChanged: (hasFocus) => debugPrint('has focus $hasFocus'), - //onTextChanged: (text) => debugPrint('widget text change $text'), - onTextChanged: (value) { - newValues.where((element) => element.language == language).first.value = value; - }, - onEditorCreated: () => debugPrint('Editor has been loaded'), - onEditorResized: (height) => - debugPrint('Editor resized $height'), - onSelectionChanged: (sel) => - debugPrint('${sel.index},${sel.length}'), - ), - ], - ) - /*HtmlEditor( - controller: controller, - htmlEditorOptions: HtmlEditorOptions( - hint: "Your text here...", - initialText: newValues.where((element) => element.language == language).first.value!, - shouldEnsureVisible: true, - ), - htmlToolbarOptions: HtmlToolbarOptions( - toolbarPosition: ToolbarPosition.aboveEditor, //required to place toolbar anywhere! - //other options - ), - otherOptions: OtherOptions( - height: 400, - ), - )*/ - /*TextFormInputContainer( - label: label, - color: kWhite, - isTitle: isTitle, - initialValue: newValues.where((element) => element.language == language).first.value!, - onChanged: (value) { - newValues.where((element) => element.language == language).first.value = value; - }, - )*/ : - Container( - width: 250, - height: 120, - child: AudioInputContainer( - label: "Audio :", - initialValue: newValues.where((element) => element.language == language).first.value, - color: kPrimaryColor, - onChanged: (ResourceDTO resource) { - newValues.where((element) => element.language == language).first.value = resource.id; - }, - ), - ), - ], - ), + width: 180, + height: 70, + child: RoundedButton( + text: "Annuler", + icon: Icons.undo, + color: kSecond, + press: () { + onGetResult(values); + Navigator.of(context).pop(); + }, + fontSize: 20, ), - ) + ), + Container( + width: 180, + height: 70, + child: RoundedButton( + text: "Valider", + icon: Icons.check, + color: kPrimaryColor, + textColor: kWhite, + press: () { + Function deepEq = const DeepCollectionEquality().equals; + if (!deepEq(values, newValues)) { + onGetResult(newValues); + } + Navigator.of(context).pop(); + }, + fontSize: 20, + ), + ), ], ), - ) - ); - //} - return translations; + ], + ); + }, context: context + ); } -/* -showValues(List newValues) { - List valuesToShow = new List(); - newValues.forEach((newValue) { - valuesToShow.add( - new StringInputContainer( - color: Colors.lightBlue, - label: newValue.language, - initialValue: newValue.value, - onChanged: (String value) { - newValue.value = value; - }, - )); - }); - return valuesToShow; -}*/ diff --git a/lib/Components/translation_input_container.dart b/lib/Components/translation_input_container.dart new file mode 100644 index 0000000..d1805af --- /dev/null +++ b/lib/Components/translation_input_container.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:manager_api_new/api.dart'; +import 'package:manager_app/Components/audio_input_container.dart'; +import 'package:manager_app/app_context.dart'; +import 'package:manager_app/constants.dart'; +import 'package:provider/provider.dart'; +import 'package:quill_html_editor/quill_html_editor.dart'; + +import 'flag_decoration.dart'; + +class _TranslationInputContainerState extends State with TickerProviderStateMixin { + TabController? _tabController; + QuillEditorController controllerQuill = QuillEditorController(); + ValueNotifier? currentLanguage; + + @override + void initState() { + super.initState(); + _tabController = new TabController(length: widget.newValues.length, vsync: this); + currentLanguage = ValueNotifier(widget.newValues.first.language!); + controllerQuill.insertText(widget.newValues[_tabController!.index].value!); + + controllerQuill.onTextChanged((p0) async { + var plainText = await controllerQuill.getPlainText(); + if(widget.isTitle) { + if(plainText.length > 60) { + print("to much text au dessus"); + controllerQuill.undo(); + } + } else { + if(plainText.length > 2500) { + print("to much text description au dessus"); + controllerQuill.undo(); + } + } + }); + + _tabController!.addListener(() { + if (!_tabController!.indexIsChanging) { + setState(() { + currentLanguage!.value = widget.newValues[_tabController!.index].language; + if(!widget.isAudio) { + controllerQuill.clear(); + controllerQuill.insertText(widget.newValues[_tabController!.index].value!); + } + }); + } + }); + } + + @override + void dispose() { + super.dispose(); + _tabController!.dispose(); + } + + getTranslation(BuildContext context, AppContext appContext, QuillEditorController controllerQuill, List customToolBarList, bool isTitle, bool isAudio, List newValues, ValueNotifier currentLanguage) { + return Padding( + padding: const EdgeInsets.all(6.0), + child: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Container( + width: MediaQuery.of(context).size.width *0.7, + height: widget.isTitle ? MediaQuery.of(context).size.height *0.25 : MediaQuery.of(context).size.height *0.4, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + !isAudio ? + Column( + children: [ + ToolBar( + toolBarColor: kSecond, + activeIconColor: kPrimaryColor, + padding: const EdgeInsets.all(8), + iconSize: 20, + toolBarConfig: customToolBarList, + controller: controllerQuill, + customButtons: [], + ), + SingleChildScrollView( + child: Container( + height: widget.isTitle ? MediaQuery.of(context).size.height *0.13 : MediaQuery.of(context).size.height *0.35, + child: QuillHtmlEditor( + text: newValues.where((element) => element.language! == currentLanguage.value).first.value!, + //hintText: 'Hint text goes here', + controller: controllerQuill, + minHeight: widget.isTitle ? 80 : 240, + /*textStyle: _editorTextStyle, + hintTextStyle: _hintTextStyle,*/ + hintTextAlign: TextAlign.start, + padding: const EdgeInsets.only(left: 10, right: 10, top: 5), + hintTextPadding: EdgeInsets.zero, + backgroundColor: kBackgroundColor, + ensureVisible: true, + inputAction: widget.isTitle ? InputAction.send : InputAction.newline, // don't accept enter if title + onFocusChanged: (hasFocus) => debugPrint('has focus $hasFocus'), + //onTextChanged: (text) => debugPrint('widget text change $text'), + onTextChanged: (value) { + newValues.where((element) => element.language! == currentLanguage.value).first.value = value; + }, + onEditorCreated: () => debugPrint('Editor has been loaded'), + onEditorResized: (height) => + debugPrint('Editor resized $height'), + onSelectionChanged: (sel) => + debugPrint('${sel.index},${sel.length}'), + ), + ), + ), + ], + ) + /*HtmlEditor( + controller: controller, + htmlEditorOptions: HtmlEditorOptions( + hint: "Your text here...", + initialText: newValues.where((element) => element.language == language).first.value!, + shouldEnsureVisible: true, + ), + htmlToolbarOptions: HtmlToolbarOptions( + toolbarPosition: ToolbarPosition.aboveEditor, //required to place toolbar anywhere! + //other options + ), + otherOptions: OtherOptions( + height: 400, + ), + )*/ + /*TextFormInputContainer( + label: label, + color: kWhite, + isTitle: isTitle, + initialValue: newValues.where((element) => element.language == language).first.value!, + onChanged: (value) { + newValues.where((element) => element.language == language).first.value = value; + }, + )*/ : + Container( + width: 250, + height: 120, + child: ValueListenableBuilder( + valueListenable: currentLanguage, + builder: (context, value, _) { + return AudioInputContainer( + //label: "Audio :", + initialValue: newValues.where((element) => element.language! == value).first.value, + color: kPrimaryColor, + onChanged: (ResourceDTO resource) { + newValues.where((element) => element.language! == value).first.value = resource.id; + }, + ); + }, + ), + ), + ], + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final customToolBarList = widget.isTitle ? [ + ToolBarStyle.bold, + ToolBarStyle.italic, + ToolBarStyle.color, + ToolBarStyle.background, + ToolBarStyle.clean + ] : [ + ToolBarStyle.bold, + ToolBarStyle.italic, + ToolBarStyle.align, + ToolBarStyle.color, + ToolBarStyle.background, + ToolBarStyle.listBullet, + ToolBarStyle.listOrdered, + ToolBarStyle.clean + ]; + + return Container( + height: widget.isTitle ? MediaQuery.of(context).size.height *0.35 : MediaQuery.of(context).size.height *0.53, + width: MediaQuery.of(context).size.width *0.7, + constraints: BoxConstraints( + minHeight: 200, + minWidth: 300 + ), + child: DefaultTabController( + length: widget.newValues.length, + child: Column( + children: [ + RotatedBox( + quarterTurns: 0, // Can be used to test vertical tab in case of smaller screen + child: TabBar( + indicatorColor: kPrimaryColor, + //overlayColor: MaterialStateProperty().c, + labelColor: kPrimaryColor, + unselectedLabelColor: Colors.black, + controller: _tabController, + tabs: widget.newValues.map((v) => Tab(icon: FlagDecoration(language: v.language!))).toList(), // text: v.language!.toUpperCase(), + ), + ), + getTranslation(context, Provider.of(context), controllerQuill, customToolBarList, widget.isTitle, widget.isAudio, widget.newValues, currentLanguage!) + /*TabContainer( + radius: 0, + tabs: values.map((v) => v.language!.toUpperCase()).toList(), + children: getTranslations(context, Provider.of(context), controllerQuill, customToolBarList, label, isTitle, isAudio, newValues), + + /*child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: getTranslations(context, Provider.of(context), controllerQuill, label, isTitle, isAudio, newValues), + ),*/ + ),*/ + ], + ), + ), + ); + } +} + +class TranslationInputContainer extends StatefulWidget { + TranslationInputContainer({ + Key? key, + required this.isTitle, + required this.values, + required this.newValues, + required this.onGetResult, + required this.maxLines, + required this.isAudio, + }) : super(key: key); + + bool isTitle; + List values; + List newValues; + Function onGetResult; + int maxLines; + bool isAudio; + + @override + State createState() => _TranslationInputContainerState(); +} diff --git a/lib/Screens/Configurations/Section/SubSection/Article/article_config.dart b/lib/Screens/Configurations/Section/SubSection/Article/article_config.dart index 8b5d60c..58c9ba5 100644 --- a/lib/Screens/Configurations/Section/SubSection/Article/article_config.dart +++ b/lib/Screens/Configurations/Section/SubSection/Article/article_config.dart @@ -83,6 +83,7 @@ class _ArticleConfigState extends State { label: "Contenu affiché :", modalLabel: "Contenu", color: kPrimaryColor, + isHTML: true, initialValue: articleDTO != null ? articleDTO.content! : [], isTitle: false, onGetResult: (value) { diff --git a/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart b/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart index 3e1d2ed..a6840d8 100644 --- a/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart +++ b/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart @@ -1,5 +1,6 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; +import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/string_input_container.dart'; import 'package:manager_app/Components/text_form_input_container.dart'; @@ -63,11 +64,48 @@ void showNewOrUpdateGeoPoint(GeoPointDTO? inputGeoPointDTO, Function getResult, ], ), Container( - height: size.height * 0.33, + height: size.height * 0.2, width: double.infinity, - child: ListView( - scrollDirection: Axis.horizontal, - children: getTranslations(context, appContext, geoPointDTO), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Titre affiché:", + modalLabel: "Titre", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: geoPointDTO.title != null ? geoPointDTO.title! : [], + onGetResult: (value) { + if (geoPointDTO.title != value) { + geoPointDTO.title = value; + } + }, + maxLines: 1, + isTitle: true + ), + ), + Container( + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Description affichée:", + modalLabel: "Description", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: geoPointDTO.description != null ? geoPointDTO.description! : [], + onGetResult: (value) { + if (geoPointDTO.description != value) { + geoPointDTO.description = value; + } + }, + maxLines: 1, + isTitle: false + ), + ), + ], ), ), Container( @@ -148,63 +186,3 @@ void showNewOrUpdateGeoPoint(GeoPointDTO? inputGeoPointDTO, Function getResult, ), context: context ); } - -getTranslations(BuildContext context, AppContext appContext, GeoPointDTO geoPointDTO) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - for(var language in managerAppContext.selectedConfiguration!.languages!) { - translations.add( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.2, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormInputContainer( - label: "Titre:", - color: kWhite, - isTitle: true, - initialValue: geoPointDTO.title!.where((element) => element.language == language).first.value!, - onChanged: (value) { - geoPointDTO.title!.where((element) => element.language == language).first.value = value; - }, - ), - TextFormInputContainer( - label: "Description:", - color: kWhite, - isTitle: false, - initialValue: geoPointDTO.description!.where((element) => element.language == language).first.value!, - onChanged: (value) { - geoPointDTO.description!.where((element) => element.language == language).first.value = value; - }, - ), - ], - ), - ), - ), - ) - ], - ), - ) - ); - } - return translations; -} - diff --git a/lib/Screens/Configurations/Section/SubSection/Menu/showEditSubSection.dart b/lib/Screens/Configurations/Section/SubSection/Menu/showEditSubSection.dart index 55fd67d..b1af686 100644 --- a/lib/Screens/Configurations/Section/SubSection/Menu/showEditSubSection.dart +++ b/lib/Screens/Configurations/Section/SubSection/Menu/showEditSubSection.dart @@ -1,6 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:manager_app/Components/image_input_container.dart'; import 'package:flutter/material.dart'; +import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/string_input_container.dart'; import 'package:manager_app/Components/text_form_input_container.dart'; @@ -60,12 +61,50 @@ void showEditSubSection(SectionDTO subSectionDTO, Function getResult, AppContext ], ), Container( - height: size.height * 0.33, + height: size.height * 0.1, width: double.infinity, - child: ListView( - scrollDirection: Axis.horizontal, - children: getTranslations(context, appContext, subSectionDTO), - ), + constraints: BoxConstraints(minHeight: 50), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Titre affiché:", + modalLabel: "Titre", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: subSectionDTO.title != null ? subSectionDTO.title! : [], + onGetResult: (value) { + if (subSectionDTO.title != value) { + subSectionDTO.title = value; + } + }, + maxLines: 1, + isTitle: true + ), + ), + Container( + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Description affichée:", + modalLabel: "Description", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: subSectionDTO.description != null ? subSectionDTO.description! : [], + onGetResult: (value) { + if (subSectionDTO.description != value) { + subSectionDTO.description = value; + } + }, + maxLines: 1, + isTitle: false + ), + ), + ], + ) ), Container( decoration: BoxDecoration( @@ -182,64 +221,3 @@ getSpecificData(SectionDTO sectionDTO, BuildContext context, AppContext appConte ); } } - -getTranslations(BuildContext context, AppContext appContext, SectionDTO subSectionDTO) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - for(var language in managerAppContext.selectedConfiguration!.languages!) { - translations.add( - SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.2, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormInputContainer( - label: "Titre:", - color: kWhite, - isTitle: true, - maxLines: 1, - initialValue: subSectionDTO.title!.where((element) => element.language == language).first.value!, - onChanged: (value) { - subSectionDTO.title!.where((element) => element.language == language).first.value = value; - }, - ), - TextFormInputContainer( - label: "Description:", - color: kWhite, - isTitle: false, - initialValue: subSectionDTO.description!.where((element) => element.language == language).first.value!, - onChanged: (value) { - subSectionDTO.description!.where((element) => element.language == language).first.value = value; - }, - ), - ], - ), - ), - ) - ], - ), - ), - ) - ); - } - return translations; -} - diff --git a/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_question_quizz.dart b/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_question_quizz.dart index 5620579..e2c6142 100644 --- a/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_question_quizz.dart +++ b/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_question_quizz.dart @@ -2,6 +2,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:manager_app/Components/image_input_container.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Components/message_notification.dart'; +import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/text_form_input_container.dart'; import 'package:manager_app/Models/managerContext.dart'; @@ -48,30 +49,48 @@ Future showNewOrUpdateQuestionQuizz(QuestionDTO? inputQuestionDTO, Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Center( - child: ImageInputContainer( - label: "Image :", - initialValue: questionDTO.resourceId, - color: kPrimaryColor, - onChanged: (ResourceDTO resource) { - if(resource.id == null) { - questionDTO.resourceId = null; - questionDTO.source_ = null; - } else { - questionDTO.resourceId = resource.id; - questionDTO.source_ = resource.type == ResourceType.ImageUrl ? resource.data : (appContext.getContext() as ManagerAppContext).clientAPI!.resourceApi!.apiClient.basePath+"/api/Resource/"+ resource.id!; - } - }, - isSmall: true - ), - ), Container( - //color: Colors.orangeAccent, - height: size.height * 0.15, - width: double.infinity, - child: ListView( - scrollDirection: Axis.horizontal, - children: getTranslations(dialogContext, appContext, questionDTO), + height: size.height*0.25, + constraints: BoxConstraints(minHeight: 100, maxHeight: 150), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + ImageInputContainer( + label: "Image :", + initialValue: questionDTO.resourceId, + color: kPrimaryColor, + onChanged: (ResourceDTO resource) { + if(resource.id == null) { + questionDTO.resourceId = null; + questionDTO.source_ = null; + } else { + questionDTO.resourceId = resource.id; + questionDTO.source_ = resource.type == ResourceType.ImageUrl ? resource.data : (appContext.getContext() as ManagerAppContext).clientAPI!.resourceApi!.apiClient.basePath+"/api/Resource/"+ resource.id!; + } + }, + isSmall: true + ), + Container( + //color: Colors.orangeAccent, + height: size.height * 0.15, + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Question:", + modalLabel: "Question", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: questionDTO.label != null ? questionDTO.label! : [], + onGetResult: (value) { + if (questionDTO.label != value) { + questionDTO.label = value; + } + }, + maxLines: 1, + isTitle: true + ), + ), + ], ), ), Container( @@ -152,54 +171,3 @@ Future showNewOrUpdateQuestionQuizz(QuestionDTO? inputQuestionDTO, ); return result; } - -getTranslations(BuildContext context, AppContext appContext, QuestionDTO questionDTO) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - for(var language in managerAppContext.selectedConfiguration!.languages!) { - translations.add( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.2, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormInputContainer( - label: "Question:", - color: kWhite, - isTitle: false, - initialValue: questionDTO.label!.where((element) => element.language == language).first.value!, - onChanged: (value) { - questionDTO.label!.where((element) => element.language == language).first.value = value; - }, - ), - ], - ), - ), - ), - ) - ], - ), - ) - ); - } - return translations; -} - diff --git a/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_response_quizz.dart b/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_response_quizz.dart index d9643ec..fb0038e 100644 --- a/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_response_quizz.dart +++ b/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_response_quizz.dart @@ -1,6 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Components/message_notification.dart'; +import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/text_form_input_container.dart'; import 'package:manager_app/Models/managerContext.dart'; @@ -27,6 +28,9 @@ Future showNewOrUpdateResponseQuizz(ResponseDTO? inputResponseDTO, } Size size = MediaQuery.of(context).size; + + //showMultiStringInputHTML("Réponse", "Modifier la réponse:", false, initials, newValues, onGetResult, 1, false, context); + var result = await showDialog( builder: (BuildContext dialogContext) => AlertDialog( shape: RoundedRectangleBorder( @@ -39,18 +43,27 @@ Future showNewOrUpdateResponseQuizz(ResponseDTO? inputResponseDTO, mainAxisAlignment: MainAxisAlignment.center, children: [ Text(text, style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)), - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - height: size.height * 0.25, - width: double.infinity, - child: ListView( - scrollDirection: Axis.horizontal, - children: getTranslations(dialogContext, appContext, responseDTO), - ), + Container( + height: size.height * 0.25, + width: double.infinity, + child: Container( + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Modifier la réponse:", + modalLabel: "Réponse", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: responseDTO.label != null ? responseDTO.label! : [], + onGetResult: (value) { + if (responseDTO.label != value) { + responseDTO.label = value; + } + }, + maxLines: 1, + isTitle: true ), - ], + ), ), /*Row( mainAxisAlignment: MainAxisAlignment.center, @@ -124,54 +137,3 @@ Future showNewOrUpdateResponseQuizz(ResponseDTO? inputResponseDTO, ); return result; } - -getTranslations(BuildContext context, AppContext appContext, ResponseDTO responseDTO) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - for(var language in managerAppContext.selectedConfiguration!.languages!) { - translations.add( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.2, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormInputContainer( - label: "Réponse:", - color: kWhite, - isTitle: true, - initialValue: responseDTO.label!.where((element) => element.language == language).first.value!, - onChanged: (value) { - responseDTO.label!.where((element) => element.language == language).first.value = value; - }, - ), - ], - ), - ), - ), - ) - ], - ), - ) - ); - } - return translations; -} - diff --git a/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_score_quizz.dart b/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_score_quizz.dart index 4e08b62..61a6f6d 100644 --- a/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_score_quizz.dart +++ b/lib/Screens/Configurations/Section/SubSection/Quizz/new_update_score_quizz.dart @@ -1,6 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:manager_app/Components/image_input_container.dart'; import 'package:flutter/material.dart'; +import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/text_form_input_container.dart'; import 'package:manager_app/Models/managerContext.dart'; @@ -39,8 +40,8 @@ Future showNewOrUpdateScoreQuizz(LevelDTO? inputLevelDTO, AppContext mainAxisAlignment: MainAxisAlignment.center, children: [ Text(text, style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)), - Column( - mainAxisAlignment: MainAxisAlignment.center, + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Center( child: ImageInputContainer( @@ -60,12 +61,23 @@ Future showNewOrUpdateScoreQuizz(LevelDTO? inputLevelDTO, AppContext ), ), Container( - height: size.height * 0.33, - width: double.infinity, - child: ListView( - scrollDirection: Axis.horizontal, - children: getTranslations(dialogContext, appContext, levelDTO), - ), + height: size.height * 0.2, + constraints: BoxConstraints(minHeight: 50, maxHeight: 80), + child: MultiStringInputContainer( + label: "Message:", + modalLabel: "Message", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: levelDTO.label != null ? levelDTO.label! : [], + onGetResult: (value) { + if (levelDTO.label != value) { + levelDTO.label = value; + } + }, + maxLines: 1, + isTitle: true + ) ), ], ), @@ -117,54 +129,3 @@ Future showNewOrUpdateScoreQuizz(LevelDTO? inputLevelDTO, AppContext ); return result; } - -getTranslations(BuildContext context, AppContext appContext, LevelDTO levelDTO) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - for(var language in managerAppContext.selectedConfiguration!.languages!) { - translations.add( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.2, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormInputContainer( - label: "Message:", - color: kWhite, - isTitle: false, - initialValue: levelDTO.label!.where((element) => element.language == language).first.value!, - onChanged: (value) { - levelDTO.label!.where((element) => element.language == language).first.value = value; - }, - ), - ], - ), - ), - ), - ) - ], - ), - ) - ); - } - return translations; -} - diff --git a/lib/Screens/Configurations/Section/SubSection/Quizz/quizz_answer_list.dart b/lib/Screens/Configurations/Section/SubSection/Quizz/quizz_answer_list.dart index 12f9bf3..3ecfd2d 100644 --- a/lib/Screens/Configurations/Section/SubSection/Quizz/quizz_answer_list.dart +++ b/lib/Screens/Configurations/Section/SubSection/Quizz/quizz_answer_list.dart @@ -1,5 +1,9 @@ +import 'dart:convert'; + import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; +import 'package:manager_app/Components/multi_string_input_html_modal.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_api_new/api.dart'; @@ -137,11 +141,10 @@ class _QuizzResponseListState extends State { Center( child: Padding( padding: const EdgeInsets.all(2.0), - child: AutoSizeText( - response.label == null ? "" : response.label![0].value!, - style: new TextStyle(fontSize: 15), - maxLines: 2, - textAlign: TextAlign.center, + child: HtmlWidget( + response.label == null ? "" : response.label![0].value!, + //textAlign: TextAlign.left, + textStyle: TextStyle(fontSize: 15) ), ), ), @@ -174,19 +177,31 @@ class _QuizzResponseListState extends State { message: "Modifier", child: InkWell( onTap: () async { - var result = await showNewOrUpdateResponseQuizz( - response, - appContext, - context, - "Modifier la réponse" - ); + List newValues = []; - if (result != null) { - setState(() { - responsesMiddle[response.order!] = result; - widget.onChanged(responsesMiddle); - }); + List initials = response.label!; + if(initials == null) { + initials = []; } + + languages.forEach((value) { + if(initials.map((iv) => iv.language).contains(value)) { + newValues.add(TranslationDTO.fromJson(jsonDecode(jsonEncode(initials.firstWhere((element) => element.language == value)))!)!); + } else { + // New language + newValues.add(TranslationDTO(language: value, value: null)); + } + }); + + showMultiStringInputHTML("Réponse", "Modifier la réponse", true, initials, newValues, (value) { + setState(() { + if (response.label! != value) { + response.label = value; + responsesMiddle[response.order!] = value; + widget.onChanged(responsesMiddle); + } + }); + }, 1, false, context); }, child: Padding( padding: const EdgeInsets.all(8.0), diff --git a/lib/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart b/lib/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart index 15987ff..3c9a552 100644 --- a/lib/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart +++ b/lib/Screens/Configurations/Section/SubSection/Slider/listView_card_image.dart @@ -4,6 +4,7 @@ import 'package:manager_app/Screens/Configurations/Section/SubSection/Slider/new import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_api_new/api.dart'; +import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; class ListViewCardImage extends StatefulWidget { final int index; @@ -46,11 +47,16 @@ class _ListViewCard extends State { padding: const EdgeInsets.only(right: 20.0), child: Column( children: [ - AutoSizeText( + HtmlWidget( + widget.listItems[widget.index].title == null ? "" : widget.listItems[widget.index].title![0].value!, + //textAlign: TextAlign.left, + textStyle: TextStyle(fontSize: 15) + ), + /*AutoSizeText( widget.listItems[widget.index].title == null ? "" : widget.listItems[widget.index].title![0].value!, style: new TextStyle(fontSize: 15), maxLines: 1, - ), + ),*/ Center( child: Container( height: MediaQuery.of(context).size.height * 0.1, diff --git a/lib/Screens/Configurations/Section/SubSection/Slider/new_update_image_slider.dart b/lib/Screens/Configurations/Section/SubSection/Slider/new_update_image_slider.dart index f61cfae..ab69351 100644 --- a/lib/Screens/Configurations/Section/SubSection/Slider/new_update_image_slider.dart +++ b/lib/Screens/Configurations/Section/SubSection/Slider/new_update_image_slider.dart @@ -1,6 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:manager_app/Components/image_input_container.dart'; import 'package:flutter/material.dart'; +import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/text_form_input_container.dart'; import 'package:manager_app/Models/managerContext.dart'; @@ -39,7 +40,8 @@ Future showNewOrUpdateImageSlider(ImageDTO? inputImageDTO, AppContext borderRadius: BorderRadius.all(Radius.circular(20.0)) ), content: Container( - width: size.width *0.5, + width: size.width *0.35, + constraints: BoxConstraints(minWidth: 300), child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -53,6 +55,7 @@ Future showNewOrUpdateImageSlider(ImageDTO? inputImageDTO, AppContext label: "Image :", initialValue: imageDTO.resourceId, color: kPrimaryColor, + fontSize: 20, onChanged: (ResourceDTO resource) { if(resource.id == null) { imageDTO.resourceId = null; @@ -67,12 +70,43 @@ Future showNewOrUpdateImageSlider(ImageDTO? inputImageDTO, AppContext ), if(showTitle || showDescription) Container( - height: size.height * 0.33, + height: size.height * 0.2, width: double.infinity, - child: ListView( - scrollDirection: Axis.horizontal, - children: getTranslations(dialogContext, appContext, imageDTO, showTitle, showDescription), - ), + constraints: BoxConstraints(minHeight: 150), + child: Column( + children: [ + MultiStringInputContainer( + label: "Titre affiché:", + modalLabel: "Titre", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: imageDTO.title != null ? imageDTO.title! : [], + onGetResult: (value) { + if (imageDTO.title != value) { + imageDTO.title = value; + } + }, + maxLines: 1, + isTitle: true + ), + MultiStringInputContainer( + label: "Description affichée:", + modalLabel: "Description", + fontSize: 20, + isHTML: true, + color: kPrimaryColor, + initialValue: imageDTO.description != null ? imageDTO.description! : [], + onGetResult: (value) { + if (imageDTO.description != value) { + imageDTO.description = value; + } + }, + maxLines: 1, + isTitle: false + ), + ], + ) ), ], ), @@ -127,82 +161,3 @@ Future showNewOrUpdateImageSlider(ImageDTO? inputImageDTO, AppContext return result; } - -getTranslations(BuildContext context, AppContext appContext, ImageDTO imageDTO, bool showTitle, bool showDescription) { - List translations = []; - ManagerAppContext managerAppContext = appContext.getContext(); - for(var language in managerAppContext.selectedConfiguration!.languages!) { - - if(imageDTO.title!.where((element) => element.language == language).length == 0) { - imageDTO.title = []; - var translationTitleDTO = new TranslationDTO(); - translationTitleDTO.language = language; - translationTitleDTO.value = ""; - imageDTO.title!.add(translationTitleDTO); - } - - if(imageDTO.description!.where((element) => element.language == language).length == 0) { - imageDTO.description = []; - var translationDescriptionDTO = new TranslationDTO(); - translationDescriptionDTO.language = language; - translationDescriptionDTO.value = ""; - imageDTO.description!.add(translationDescriptionDTO); - } - - translations.add( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width *0.05, - height: MediaQuery.of(context).size.height *0.2, - decoration: BoxDecoration( - border: Border( - right: BorderSide(width: 1.5, color: kSecond), - ), - ), - child: Center(child: AutoSizeText(language.toUpperCase())) - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Container( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if(showTitle) - TextFormInputContainer( - label: "Titre:", - color: kWhite, - isTitle: true, - initialValue: imageDTO.title!.where((element) => element.language == language).first.value!, - onChanged: (value) { - imageDTO.title!.where((element) => element.language == language).first.value = value; - }, - ), - if(showDescription) - TextFormInputContainer( - label: "Description:", - color: kWhite, - isTitle: false, - initialValue: imageDTO.description!.where((element) => element.language == language).first.value!, - onChanged: (value) { - imageDTO.description!.where((element) => element.language == language).first.value = value; - }, - ), - ], - ), - ), - ), - ) - ], - ), - ) - ); - } - return translations; -} - diff --git a/lib/Screens/Configurations/Section/section_detail_screen.dart b/lib/Screens/Configurations/Section/section_detail_screen.dart index 746a852..12006e2 100644 --- a/lib/Screens/Configurations/Section/section_detail_screen.dart +++ b/lib/Screens/Configurations/Section/section_detail_screen.dart @@ -250,6 +250,7 @@ class _SectionDetailScreenState extends State { label: "Description affichée:", modalLabel: "Description", color: kPrimaryColor, + isHTML: true, initialValue: sectionDTO != null ? sectionDTO.description! : [], onGetResult: (value) { if (sectionDTO!.description != value) { diff --git a/lib/Screens/Configurations/configuration_detail_screen.dart b/lib/Screens/Configurations/configuration_detail_screen.dart index 1b1f379..d2e8337 100644 --- a/lib/Screens/Configurations/configuration_detail_screen.dart +++ b/lib/Screens/Configurations/configuration_detail_screen.dart @@ -269,6 +269,7 @@ class _ConfigurationDetailScreenState extends State { label: "Titre affiché:", modalLabel: "Titre", fontSize: 20, + isHTML: true, color: kPrimaryColor, initialValue: configurationDTO != null ? configurationDTO.title! : [], onGetResult: (value) { diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index d21238c..1560fc8 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,9 +7,13 @@ #include "generated_plugin_registrant.h" #include +#include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) pasteboard_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin"); pasteboard_plugin_register_with_registrar(pasteboard_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index c242e0a..5a3c388 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST pasteboard + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 9b15cc8..d4702a9 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,10 @@ import just_audio import package_info_plus import pasteboard import path_provider_foundation +import sqflite +import url_launcher_macos +import video_player_avfoundation +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) @@ -17,4 +21,8 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 612a692..23ff367 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -153,6 +153,30 @@ packages: url: "https://pub.dev" source: hosted version: "8.6.3" + cached_network_image: + dependency: transitive + description: + name: cached_network_image + sha256: f98972704692ba679db144261172a8e20feb145636c617af0eb4022132a6797f + url: "https://pub.dev" + source: hosted + version: "3.3.0" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "56aa42a7a01e3c9db8456d9f3f999931f1e05535b5a424271e9a38cabf066613" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "759b9a9f8f6ccbb66c185df805fac107f05730b1dab9c64626d1008cca532257" + url: "https://pub.dev" + source: hosted + version: "1.1.0" characters: dependency: transitive description: @@ -169,6 +193,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" + chewie: + dependency: transitive + description: + name: chewie + sha256: ccfce3350ae9fd419cd336cdf3380f77a08e45171e1e3cb3d499d204de5e7ea8 + url: "https://pub.dev" + source: hosted + version: "1.7.1" clock: dependency: transitive description: @@ -209,6 +241,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" cupertino_icons: dependency: "direct main" description: @@ -225,6 +265,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + dbus: + dependency: transitive + description: + name: dbus + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" + source: hosted + version: "0.7.8" diacritic: dependency: "direct main" description: @@ -302,6 +350,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba" + url: "https://pub.dev" + source: hosted + version: "3.3.1" flutter_colorpicker: dependency: "direct main" description: @@ -318,6 +374,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.17" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + sha256: bfc7cc3c75fe1282e8ce2e056d8fd1533f1a6848b65c379b4a5e7a9b623d3371 + url: "https://pub.dev" + source: hosted + version: "2.0.8" flutter_test: dependency: "direct dev" description: flutter @@ -328,6 +392,22 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_widget_from_html: + dependency: "direct main" + description: + name: flutter_widget_from_html + sha256: "8d2a9a7979a9c1a5d866d1f4134d2ec2cca78716c112c76803d6a552281405cc" + url: "https://pub.dev" + source: hosted + version: "0.10.6" + flutter_widget_from_html_core: + dependency: transitive + description: + name: flutter_widget_from_html_core + sha256: "22140caa191cb4bba0fe4d5e4ad875c7e8a9ba47d61517f56d733019cf76396d" + url: "https://pub.dev" + source: hosted + version: "0.10.6" frontend_server_client: dependency: transitive description: @@ -336,6 +416,54 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.0" + fwfh_cached_network_image: + dependency: transitive + description: + name: fwfh_cached_network_image + sha256: "3de22aa3a6943c968e0d9fbcba4463b3dbbf7103171d62c84b6c672fb83eebdf" + url: "https://pub.dev" + source: hosted + version: "0.7.0+7" + fwfh_chewie: + dependency: transitive + description: + name: fwfh_chewie + sha256: "0b51a1c976bb74da5e8e45d545c74cb54a7168ad3938dd77103a7aee485f55fa" + url: "https://pub.dev" + source: hosted + version: "0.7.1+4" + fwfh_just_audio: + dependency: transitive + description: + name: fwfh_just_audio + sha256: "237b93a4cb9f0495a4b51940f361adda2a5abd57231dd44f07459db00144a6cd" + url: "https://pub.dev" + source: hosted + version: "0.9.0+3" + fwfh_svg: + dependency: transitive + description: + name: fwfh_svg + sha256: "26df142c1784c29c3675ad0d37f589fc5c2173a14fc002d2c38cde3d0f117302" + url: "https://pub.dev" + source: hosted + version: "0.8.0+4" + fwfh_url_launcher: + dependency: transitive + description: + name: fwfh_url_launcher + sha256: "2a526c9819f74b4106ba2fba4dac79f0082deecd8d2c7011cd0471cb710e3eff" + url: "https://pub.dev" + source: hosted + version: "0.9.0+4" + fwfh_webview: + dependency: transitive + description: + name: fwfh_webview + sha256: "90a8dda0695403cf57abd7e8b83f6fb1f1a12933930a0bf9cac7cafb06e06a18" + url: "https://pub.dev" + source: hosted + version: "0.9.0+2" glob: dependency: transitive description: @@ -352,6 +480,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" + html: + dependency: transitive + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" http: dependency: transitive description: @@ -543,6 +679,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "45b40f99622f11901238e18d48f5f12ea36426d8eced9f4cbf58479c7aa2430d" + url: "https://pub.dev" + source: hosted + version: "2.0.0" openapi_generator: dependency: "direct dev" description: @@ -836,6 +980,22 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" stack_trace: dependency: transitive description: @@ -868,6 +1028,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + tab_container: + dependency: "direct main" + description: + name: tab_container + sha256: "05782d9364332a55a5615825f83fa2595d21c2876dee2374bd32ff8b1031ee1d" + url: "https://pub.dev" + source: hosted + version: "2.0.0" term_glyph: dependency: transitive description: @@ -900,6 +1076,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba + url: "https://pub.dev" + source: hosted + version: "6.2.1" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" + url: "https://pub.dev" + source: hosted + version: "6.2.0" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a" + url: "https://pub.dev" + source: hosted + version: "6.2.0" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 + url: "https://pub.dev" + source: hosted + version: "3.1.0" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" + url: "https://pub.dev" + source: hosted + version: "3.1.0" uuid: dependency: transitive description: @@ -908,6 +1148,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43" + url: "https://pub.dev" + source: hosted + version: "1.1.9+1" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7" + url: "https://pub.dev" + source: hosted + version: "1.1.9+1" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26 + url: "https://pub.dev" + source: hosted + version: "1.1.9+1" vector_math: dependency: transitive description: @@ -916,6 +1180,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + video_player: + dependency: transitive + description: + name: video_player + sha256: "74b86e63529cf5885130c639d74cd2f9232e7c8a66cbecbddd1dcb9dbd060d1e" + url: "https://pub.dev" + source: hosted + version: "2.7.2" + video_player_android: + dependency: transitive + description: + name: video_player_android + sha256: "3fe89ab07fdbce786e7eb25b58532d6eaf189ceddc091cb66cba712f8d9e8e55" + url: "https://pub.dev" + source: hosted + version: "2.4.10" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + sha256: "6387c2de77763b45104256b3b00b660089be4f909ded8631457dc11bf635e38f" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a + url: "https://pub.dev" + source: hosted + version: "6.2.1" + video_player_web: + dependency: transitive + description: + name: video_player_web + sha256: "2dd24f7ba46bfb5d070e9c795001db95e0ca5f2a3d025e98f287c10c9f0fd62f" + url: "https://pub.dev" + source: hosted + version: "2.1.1" vm_service: dependency: transitive description: @@ -924,6 +1228,22 @@ packages: url: "https://pub.dev" source: hosted version: "12.0.0" + wakelock_plus: + dependency: transitive + description: + name: wakelock_plus + sha256: f45a6c03aa3f8322e0a9d7f4a0482721c8789cb41d555407367650b8f9c26018 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + wakelock_plus_platform_interface: + dependency: transitive + description: + name: wakelock_plus_platform_interface + sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385" + url: "https://pub.dev" + source: hosted + version: "1.1.0" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 825ad8f..5da4b87 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,8 @@ dependencies: cupertino_icons: ^1.0.6 quill_html_editor: ^2.2.7 responsive_framework: ^1.1.1 + tab_container: ^2.0.0 + flutter_widget_from_html: ^0.10.1 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 7c2f20e..02129f5 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,8 +7,11 @@ #include "generated_plugin_registrant.h" #include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { PasteboardPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PasteboardPlugin")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 6414160..82731c9 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST pasteboard + url_launcher_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST