diff --git a/lib/Components/audio_input_container.dart b/lib/Components/audio_input_container.dart index 3682f36..f03e49e 100644 --- a/lib/Components/audio_input_container.dart +++ b/lib/Components/audio_input_container.dart @@ -23,7 +23,7 @@ class AudioInputContainer extends StatefulWidget { this.onChanged, this.imageFit = BoxFit.cover, this.isSmall = false, - this.fontSize = 25 + this.fontSize = 20 }) : super(key: key); @override @@ -138,8 +138,9 @@ class _AudioInputContainerState extends State { } Future getResource(String resourceIdToShow, dynamic appContext) async { - ResourceDTO resource = await appContext.getContext().clientAPI.resourceApi.resourceGetDetail(resourceIdToShow); - return resource; + // Just in resource tab detail not here + //ResourceDTO resource = await appContext.getContext().clientAPI.resourceApi.resourceGetDetail(resourceIdToShow); + return new ResourceDTO(); } boxDecoration(ResourceDTO resourceDTO, appContext) { diff --git a/lib/Components/audio_player.dart b/lib/Components/audio_player.dart index e17a947..f19a379 100644 --- a/lib/Components/audio_player.dart +++ b/lib/Components/audio_player.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; +import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:managerapi/api.dart'; @@ -178,7 +179,8 @@ class _AudioPlayerContainerState extends State { Future getAudio(String resourceId, AppContext appContext) async { try { - var url = "https://api.mymuseum.be/api/Resource/"+resourceId; // TO TEST TODO UPDATE ROUTE + ManagerAppContext managerAppContext = appContext.getContext() as ManagerAppContext; + var url = managerAppContext.host + "/api/Resource/" + resourceId; // TO TEST TODO UPDATE ROUTE print("DOWNLOAD AUDDDDIOOOOO ------------"); print(url); //HttpClient client2 = HttpClient(); diff --git a/lib/Components/multi_input_modal.dart b/lib/Components/multi_input_modal.dart index 2bdbab0..5a8b0ac 100644 --- a/lib/Components/multi_input_modal.dart +++ b/lib/Components/multi_input_modal.dart @@ -1,15 +1,21 @@ +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/constants.dart'; import 'package:managerapi/api.dart'; import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; -showMultiStringInput (String label, String modalLabel, bool isTitle, List values, List newValues, Function onGetResult, int maxLines, BuildContext context) { /*Function onSelect,*/ +import 'audio_input_container.dart'; + + +showMultiStringInput (String label, String modalLabel, bool isTitle, List values, List newValues, Function onGetResult, int maxLines, bool isAudio, BuildContext context) { /*Function onSelect,*/ showDialog( builder: (BuildContext context) => AlertDialog( shape: RoundedRectangleBorder( @@ -23,7 +29,7 @@ showMultiStringInput (String label, String modalLabel, bool isTitle, List(context), label, isTitle, newValues), + children: getTranslations(context, Provider.of(context), label, isTitle, isAudio, newValues), ), ), ), @@ -84,7 +90,7 @@ showMultiStringInput (String label, String modalLabel, bool isTitle, List newValues) { +getTranslations(BuildContext context, AppContext appContext, String label, bool isTitle, bool isAudio, List newValues) { List translations = []; ManagerAppContext managerAppContext = appContext.getContext(); for(var language in managerAppContext.selectedConfiguration.languages) { @@ -111,6 +117,7 @@ getTranslations(BuildContext context, AppContext appContext, String label, bool mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ + !isAudio ? TextFormInputContainer( label: label, color: kWhite, @@ -119,6 +126,18 @@ getTranslations(BuildContext context, AppContext appContext, String label, bool 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; + }, + ), ), ], ), @@ -147,5 +166,3 @@ showValues(List newValues) { }); return valuesToShow; }*/ - - diff --git a/lib/Components/multi_string_input_container.dart b/lib/Components/multi_string_input_container.dart index a34db45..6ed7a01 100644 --- a/lib/Components/multi_string_input_container.dart +++ b/lib/Components/multi_string_input_container.dart @@ -14,6 +14,7 @@ class MultiStringContainer extends StatelessWidget { final Function onGetResult; final int maxLines; final bool isTitle; + final bool isAudio; final double fontSize; const MultiStringContainer({ Key key, @@ -24,6 +25,7 @@ class MultiStringContainer extends StatelessWidget { this.onGetResult, this.maxLines, this.isTitle, + this.isAudio = false, this.fontSize = 25, }) : super(key: key); @@ -56,7 +58,8 @@ class MultiStringContainer extends StatelessWidget { initialValue.forEach((value) { newValues.add(TranslationDTO.fromJson(jsonDecode(jsonEncode(value)))); }); - showMultiStringInput(label, modalLabel, isTitle, initialValue, newValues, onGetResult, maxLines, context); + + showMultiStringInput(label, modalLabel, isTitle, initialValue, newValues, onGetResult, maxLines, isAudio, context); } }, child: Container( @@ -68,7 +71,7 @@ class MultiStringContainer extends StatelessWidget { padding: const EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 15), child: Center( child: AutoSizeText( - "Changer les traductions", + isAudio ? "Changer audios" : "Changer traductions", style: TextStyle(color: kWhite), maxLines: 2, ) diff --git a/lib/Components/rounded_input_field.dart b/lib/Components/rounded_input_field.dart index cdfe94b..ac803d1 100644 --- a/lib/Components/rounded_input_field.dart +++ b/lib/Components/rounded_input_field.dart @@ -11,6 +11,7 @@ class RoundedInputField extends StatelessWidget { final int maxLength; final bool isEmail; final double fontSize; + final String autofill; const RoundedInputField({ Key key, this.hintText, @@ -23,6 +24,7 @@ class RoundedInputField extends StatelessWidget { this.maxLength, // 50 this.isEmail = false, this.fontSize = 20, + this.autofill, }) : super(key: key); @override @@ -34,6 +36,7 @@ class RoundedInputField extends StatelessWidget { initialValue: initialValue, cursorColor: textColor, maxLength: maxLength, + autofillHints: [autofill], keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text, style: TextStyle(fontSize: fontSize, color: textColor), decoration: InputDecoration( diff --git a/lib/Components/rounded_password_field.dart b/lib/Components/rounded_password_field.dart index 381fdd1..0959f7c 100644 --- a/lib/Components/rounded_password_field.dart +++ b/lib/Components/rounded_password_field.dart @@ -8,7 +8,7 @@ class RoundedPasswordField extends StatefulWidget { const RoundedPasswordField({ Key key, this.onChanged, - this.initialValue, + this.initialValue }) : super(key: key); @override @@ -25,6 +25,7 @@ class _RoundedPasswordFieldState extends State { obscureText: isVisible, onChanged: widget.onChanged, initialValue: widget.initialValue, + autofillHints: [AutofillHints.password], cursorColor: kPrimaryColor, style: TextStyle(fontSize: 20, color: kBlack), decoration: InputDecoration( diff --git a/lib/Components/upload_online_resources_container.dart b/lib/Components/upload_online_resources_container.dart index 43c45a2..7ef709b 100644 --- a/lib/Components/upload_online_resources_container.dart +++ b/lib/Components/upload_online_resources_container.dart @@ -66,7 +66,22 @@ class _UploadOnlineResourceContainerState extends State { child: Column( children: [ Container( - height: size.height * 0.1, + height: size.height * 0.15, //width: size.width * 0.5,//, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - MultiStringContainer( - label: "Contenu affiché :", - modalLabel: "Contenu", - color: kPrimaryColor, - initialValue: articleDTO != null ? articleDTO.content : [], - isTitle: false, - onGetResult: (value) { - setState(() { - if (articleDTO.content != value) { - articleDTO.content = value; - //save(true, articleDTO, appContext); - widget.onChanged(jsonEncode(articleDTO).toString()); - } - }); - }, - maxLines: 1, + Column( + children: [ + MultiStringContainer( + label: "Contenu affiché :", + modalLabel: "Contenu", + color: kPrimaryColor, + initialValue: articleDTO != null ? articleDTO.content : [], + isTitle: false, + onGetResult: (value) { + setState(() { + if (articleDTO.content != value) { + articleDTO.content = value; + //save(true, articleDTO, appContext); + widget.onChanged(jsonEncode(articleDTO).toString()); + } + }); + }, + maxLines: 1, + ), + CheckInputContainer( + label: "Contenu au-dessus :", + isChecked: articleDTO.isContentTop, + onChanged: (value) { + setState(() { + //print(value); + articleDTO.isContentTop = value; + widget.onChanged(jsonEncode(articleDTO).toString()); + }); + }, + ), + ], ), - CheckInputContainer( - label: "Contenu au-dessus :", - isChecked: articleDTO.isContentTop, - onChanged: (value) { - setState(() { - //print(value); - articleDTO.isContentTop = value; - widget.onChanged(jsonEncode(articleDTO).toString()); - }); - }, - ), - AudioInputContainer( - label: "Audio :", - initialValue: articleDTO.audioId, - color: kPrimaryColor, - onChanged: (ResourceDTO resource) { - articleDTO.audioId = resource.id; - widget.onChanged(jsonEncode(articleDTO).toString()); - }, - ), - CheckInputContainer( - label: "Lecture auto audio :", - isChecked: articleDTO.isReadAudioAuto, - onChanged: (value) { - setState(() { - //print(value); - articleDTO.isReadAudioAuto = value; - widget.onChanged(jsonEncode(articleDTO).toString()); - }); - }, + + Column( + children: [ + MultiStringContainer( + label: "Audio :", + isAudio: true, + modalLabel: "Audio", + color: kPrimaryColor, + initialValue: articleDTO != null ? articleDTO.audioIds : [], + isTitle: false, + onGetResult: (value) { + setState(() { + if (articleDTO.audioIds != value) { + articleDTO.audioIds = value; + //save(true, articleDTO, appContext); + widget.onChanged(jsonEncode(articleDTO).toString()); + } + }); + }, + maxLines: 1, + ), + CheckInputContainer( + label: "Lecture auto audio :", + isChecked: articleDTO.isReadAudioAuto, + onChanged: (value) { + setState(() { + //print(value); + articleDTO.isReadAudioAuto = value; + widget.onChanged(jsonEncode(articleDTO).toString()); + }); + }, + ), + ], ), ], ), @@ -141,7 +159,7 @@ class _ArticleConfigState extends State { padding: const EdgeInsets.only(top: 40, left: 10, right: 10, bottom: 10), child: Container( height: 250, - width: size.height * 0.95, + width: size.width * 0.95, child: ReorderableListView( onReorder: _onReorder, scrollDirection: Axis.horizontal, @@ -162,7 +180,7 @@ class _ArticleConfigState extends State { testToSend = testToSend.where((element) => element.source_ != null).toList(); var articleToSend = new ArticleDTO(); articleToSend.images = testToSend; - articleToSend.audioId = articleDTO.audioId; + articleToSend.audioIds = articleDTO.audioIds; articleToSend.isContentTop = articleDTO.isContentTop; articleToSend.content = articleDTO.content; articleToSend.isReadAudioAuto = articleDTO.isReadAudioAuto; diff --git a/lib/Screens/Configurations/Section/SubSection/Map/listView_card_geoPoint_images.dart b/lib/Screens/Configurations/Section/SubSection/Map/listView_card_geoPoint_images.dart index 170e155..9e31873 100644 --- a/lib/Screens/Configurations/Section/SubSection/Map/listView_card_geoPoint_images.dart +++ b/lib/Screens/Configurations/Section/SubSection/Map/listView_card_geoPoint_images.dart @@ -83,7 +83,22 @@ class _ListViewCardGeoPointImagesState extends State Center( child: Image.network( imageGeoPoint.imageSource, - fit:BoxFit.scaleDown + fit:BoxFit.scaleDown, + loadingBuilder: (BuildContext context, Widget child, + ImageChunkEvent loadingProgress) { + if (loadingProgress == null) { + return child; + } + return Center( + child: CircularProgressIndicator( + color: kPrimaryColor, + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes + : null, + ), + ); + }, ), ) /*Align( diff --git a/lib/Screens/Main/components/body.dart b/lib/Screens/Main/components/body.dart index 13aa83f..f6be36c 100644 --- a/lib/Screens/Main/components/body.dart +++ b/lib/Screens/Main/components/body.dart @@ -1,3 +1,5 @@ +import 'dart:html'; + import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Models/managerContext.dart'; @@ -134,6 +136,8 @@ class _BodyState extends State { setState(() { print("Logout"); + Storage localStorage = window.localStorage; + localStorage.clear(); ManagerAppContext managerAppContext = appContext.getContext(); managerAppContext.token = null; appContext.setContext(managerAppContext); diff --git a/lib/Screens/Resources/get_element_for_resource.dart b/lib/Screens/Resources/get_element_for_resource.dart index 42476d8..df80357 100644 --- a/lib/Screens/Resources/get_element_for_resource.dart +++ b/lib/Screens/Resources/get_element_for_resource.dart @@ -1,5 +1,6 @@ import 'package:manager_app/Components/audio_player.dart'; import 'package:manager_app/app_context.dart'; +import 'package:manager_app/constants.dart'; import 'package:managerapi/api.dart'; import 'package:flutter/material.dart'; @@ -8,13 +9,43 @@ getElementForResource(dynamic resourceDTO, AppContext appContext) { case ResourceType.image: return Image.network( appContext.getContext().clientAPI.resourceApi.apiClient.basePath+"/api/Resource/"+ resourceDTO.id, - fit:BoxFit.fill + fit:BoxFit.fill, + loadingBuilder: (BuildContext context, Widget child, + ImageChunkEvent loadingProgress) { + if (loadingProgress == null) { + return child; + } + return Center( + child: CircularProgressIndicator( + color: kPrimaryColor, + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes + : null, + ), + ); + }, ); break; case ResourceType.imageUrl: return Image.network( resourceDTO.data, - fit:BoxFit.fill + fit:BoxFit.fill, + loadingBuilder: (BuildContext context, Widget child, + ImageChunkEvent loadingProgress) { + if (loadingProgress == null) { + return child; + } + return Center( + child: CircularProgressIndicator( + color: kPrimaryColor, + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes + : null, + ), + ); + }, ); break; case ResourceType.audio: diff --git a/lib/Screens/Resources/new_resource_popup.dart b/lib/Screens/Resources/new_resource_popup.dart index b09f3e1..a013302 100644 --- a/lib/Screens/Resources/new_resource_popup.dart +++ b/lib/Screens/Resources/new_resource_popup.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter/foundation.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/resource_tab.dart'; import 'package:flutter/material.dart'; @@ -89,10 +90,18 @@ dynamic showNewResource(AppContext appContext, BuildContext context) async { textColor: kWhite, press: () { if (resourceDetailDTO.label != null && resourceDetailDTO.label.trim() != '') { - if (resourceDetailDTO.data != null || filesToSendWeb.length > 0 || filesToSend.length > 0) { - Navigator.pop(context, [resourceDetailDTO, filesToSend, filesToSendWeb]); + if(kIsWeb) { + if(resourceDetailDTO.data != null || filesToSendWeb != null) { + Navigator.pop(context, [resourceDetailDTO, filesToSend, filesToSendWeb]); + } else { + showNotification(Colors.orange, kWhite, 'Aucun fichier n\'a été chargé', context, null); + } } else { - showNotification(Colors.orange, kWhite, 'Aucun fichier n\'a été chargé', context, null); + if (resourceDetailDTO.data != null || filesToSendWeb.length > 0 || filesToSend.length > 0) { + Navigator.pop(context, [resourceDetailDTO, filesToSend, filesToSendWeb]); + } else { + showNotification(Colors.orange, kWhite, 'Aucun fichier n\'a été chargé', context, null); + } } } else { showNotification(Colors.orange, kWhite, 'Veuillez donner un nom à la ressource', context, null); diff --git a/lib/Screens/login_screen.dart b/lib/Screens/login_screen.dart index 54723db..eff9591 100644 --- a/lib/Screens/login_screen.dart +++ b/lib/Screens/login_screen.dart @@ -2,6 +2,7 @@ import 'dart:html'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:manager_app/Components/loading_common.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/rounded_button.dart'; @@ -34,6 +35,8 @@ class _LoginScreenState extends State { bool isLoading = false; bool isRememberMe = false; String pageTitle = "MyMuseum"; + String token; + Storage localStorage = window.localStorage; void authenticateTRY(dynamic appContext) async { //print("try auth.. "); @@ -44,7 +47,7 @@ class _LoginScreenState extends State { clientAPI = Client(this.host); - if (this.email != null && this.password != null && this.host != null) { + if (this.email != null && this.password != null || this.token != null) { // if () {} // Add if token exist and not null + not expired try { @@ -58,11 +61,25 @@ class _LoginScreenState extends State { TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO); setAccessToken(token.accessToken); - if (isRememberMe) { + if(!isRememberMe) { + localStorage.clear(); + } else { + + if(!localStorage.containsKey("remember")) { + localStorage.addEntries({"remember": "true"}.entries); + } + + if(!localStorage.containsKey("email") && !localStorage.containsKey("token")) { + localStorage.addEntries({"email": email}.entries); + localStorage.addEntries({"token": token.accessToken}.entries); + } + } + // Desktop + /*if (isRememberMe) { Session updatedSession = new Session(rememberMe: isRememberMe, host: host, email: email, password: password); // update JSON FILE FileHelper().writeSession(updatedSession); - } + }*/ showNotification(kSuccess, kWhite, 'Connexion réussie', context, null); @@ -74,6 +91,7 @@ class _LoginScreenState extends State { // store user info locally managerAppContext.email = email; + managerAppContext.host = host; managerAppContext.instanceId = token.instanceId; managerAppContext.token = token; managerAppContext.clientAPI = clientAPI; @@ -85,6 +103,14 @@ class _LoginScreenState extends State { isLoading = false; }); + //Navigator.pushNamed(context, '/main'); + + /*Navigator.pushNamedAndRemoveUntil( + context, + '/main', + (Route route) => false // For pushAndRemoveUntil + );*/ + Navigator.pushAndRemoveUntil( context, MaterialPageRoute( @@ -117,10 +143,20 @@ class _LoginScreenState extends State { @override void initState() { - this.isRememberMe = widget.session.rememberMe; - this.host = "https://api.mymuseum.be"; // "http://localhost:5000" //widget.session.host; // MDLF "http://192.168.1.19:8089" // "https://api.mymuseum.be" + //this.isRememberMe = widget.session.rememberMe; + this.host = "http://localhost:5000"; // "http://localhost:5000" //widget.session.host; // MDLF "http://192.168.1.19:8089" // "https://api.mymuseum.be" //this.email = "test@email.be"; //widget.session.email; //this.password = "kljqsdkljqsd"; //widget.session.password; + + if(localStorage.containsKey("remember")) { + this.isRememberMe = true; + if(localStorage.containsKey("email")) { + this.email = localStorage.entries.where((element) => element.key == "email").first.value; + } + if(localStorage.containsKey("token")) { + this.token = localStorage.entries.where((element) => element.key == "token").first.value; + } + } super.initState(); } @@ -157,6 +193,11 @@ class _LoginScreenState extends State { initInstance(appContext.getContext()); + if(mounted && appContext != null && this.token != null) + { + this.authenticateTRY(appContext); + } + return Scaffold( body: Center( child: SingleChildScrollView( @@ -208,62 +249,73 @@ class _LoginScreenState extends State { initialValue: host, icon: Icons.home ),*/ - SizedBox( - width: size.width*0.2, - child: RoundedInputField( - hintText: "E-mail", - onChanged: (value) { - email = value; - }, - icon: Icons.person, - initialValue: email, - isEmail: true, - ), - ), - SizedBox( - width: size.width *0.2, - child: RoundedPasswordField( - initialValue: password, - onChanged: (value) { - password = value; - }, - ), - ), - if(!kIsWeb) Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - child: Checkbox( - checkColor: kTextLightColor, - activeColor: kPrimaryColor, - value: this.isRememberMe, - onChanged: (bool value) { - setState(() { - this.isRememberMe = value; - }); - }, + Form( + key: widget.key, + child: AutofillGroup( + child: Column( + children: [ + SizedBox( + width: size.width*0.2, + child: RoundedInputField( + hintText: "E-mail", + autofill: AutofillHints.email, + onChanged: (value) { + email = value; + }, + icon: Icons.person, + initialValue: email, + isEmail: true, + ), ), - ), - Text("Se souvenir de moi", style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),), - ], + SizedBox( + width: size.width*0.2, + child: RoundedPasswordField( + initialValue: password, + onChanged: (value) { + password = value; + }, + ), + ), + if(kIsWeb) Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + child: Checkbox( + checkColor: kTextLightColor, + activeColor: kPrimaryColor, + value: this.isRememberMe, + onChanged: (bool value) { + setState(() { + this.isRememberMe = value; + }); + }, + ), + ), + Text("Se souvenir de moi", style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),), + ], + ), + ), + SizedBox(height: size.height * 0.05), + !isLoading ? RoundedButton( + text: "SE CONNECTER", + fontSize: 25, + vertical: 25, + horizontal: 45, + press: () { + TextInput.finishAutofillContext(); + authenticateTRY(appContext); + }, + ): Container( + height: size.height * 0.1, + child: LoadingCommon() + ), + ], + ) ), ), - SizedBox(height: size.height * 0.05), - !isLoading ? RoundedButton( - text: "SE CONNECTER", - fontSize: 25, - vertical: 25, - horizontal: 45, - press: () { - authenticateTRY(appContext); - }, - ): Container( - height: size.height * 0.1, - child: LoadingCommon() - ), ], ), ), diff --git a/manager_api/doc/ArticleDTO.md b/manager_api/doc/ArticleDTO.md index c3cb9d7..c17a87a 100644 --- a/manager_api/doc/ArticleDTO.md +++ b/manager_api/doc/ArticleDTO.md @@ -11,7 +11,7 @@ Name | Type | Description | Notes **content** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **qrCode** | **String** | | [optional] **isContentTop** | **bool** | | [optional] -**audioId** | **String** | | [optional] +**audioIds** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **isReadAudioAuto** | **bool** | | [optional] **images** | [**List**](ImageDTO.md) | | [optional] [default to const []] diff --git a/manager_api/lib/model/article_dto.dart b/manager_api/lib/model/article_dto.dart index 763934b..9c898d5 100644 --- a/manager_api/lib/model/article_dto.dart +++ b/manager_api/lib/model/article_dto.dart @@ -15,7 +15,7 @@ class ArticleDTO { this.content, this.qrCode, this.isContentTop, - this.audioId, + this.audioIds, this.isReadAudioAuto, this.images, }); @@ -26,7 +26,7 @@ class ArticleDTO { bool isContentTop; - String audioId; + List audioIds; bool isReadAudioAuto; @@ -37,7 +37,7 @@ class ArticleDTO { other.content == content && other.qrCode == qrCode && other.isContentTop == isContentTop && - other.audioId == audioId && + other.audioIds == audioIds && other.isReadAudioAuto == isReadAudioAuto && other.images == images; @@ -46,12 +46,12 @@ class ArticleDTO { (content == null ? 0 : content.hashCode) + (qrCode == null ? 0 : qrCode.hashCode) + (isContentTop == null ? 0 : isContentTop.hashCode) + - (audioId == null ? 0 : audioId.hashCode) + + (audioIds == null ? 0 : audioIds.hashCode) + (isReadAudioAuto == null ? 0 : isReadAudioAuto.hashCode) + (images == null ? 0 : images.hashCode); @override - String toString() => 'ArticleDTO[content=$content, qrCode=$qrCode, isContentTop=$isContentTop, audioId=$audioId, isReadAudioAuto=$isReadAudioAuto, images=$images]'; + String toString() => 'ArticleDTO[content=$content, qrCode=$qrCode, isContentTop=$isContentTop, audioIds=$audioIds, isReadAudioAuto=$isReadAudioAuto, images=$images]'; Map toJson() { final json = {}; @@ -64,8 +64,8 @@ class ArticleDTO { if (isContentTop != null) { json[r'isContentTop'] = isContentTop; } - if (audioId != null) { - json[r'audioId'] = audioId; + if (audioIds != null) { + json[r'audioIds'] = audioIds; } if (isReadAudioAuto != null) { json[r'isReadAudioAuto'] = isReadAudioAuto; @@ -84,7 +84,7 @@ class ArticleDTO { content: TranslationDTO.listFromJson(json[r'content']), qrCode: json[r'qrCode'], isContentTop: json[r'isContentTop'], - audioId: json[r'audioId'], + audioIds: TranslationDTO.listFromJson(json[r'audioIds']), isReadAudioAuto: json[r'isReadAudioAuto'], images: ImageDTO.listFromJson(json[r'images']), ); diff --git a/manager_api/swagger.yaml b/manager_api/swagger.yaml index 2b5be51..71513eb 100644 --- a/manager_api/swagger.yaml +++ b/manager_api/swagger.yaml @@ -2107,9 +2107,11 @@ components: nullable: true isContentTop: type: boolean - audioId: - type: string + audioIds: + type: array nullable: true + items: + $ref: '#/components/schemas/TranslationDTO' isReadAudioAuto: type: boolean images: