flutter tts

merge-requests/140/head
Sultan Khan 4 years ago
parent e3e868e47c
commit a3e01ff938

@ -7,7 +7,8 @@ import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart' as list; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'
as list;
import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart';
@ -29,9 +30,10 @@ import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/routes.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MyFamily extends StatefulWidget { class MyFamily extends StatefulWidget {
final bool isAppbarVisible; final bool isAppbarVisible;
MyFamily({this.isAppbarVisible =true}); MyFamily({this.isAppbarVisible = true});
@override @override
_MyFamily createState() => _MyFamily(); _MyFamily createState() => _MyFamily();
} }
@ -44,9 +46,9 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
TabController _tabController; TabController _tabController;
int _tabIndex = 0; int _tabIndex = 0;
AuthenticatedUserObject authenticatedUserObject = AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>(); locator<AuthenticatedUserObject>();
AppointmentRateViewModel appointmentRateViewModel = AppointmentRateViewModel appointmentRateViewModel =
locator<AppointmentRateViewModel>(); locator<AppointmentRateViewModel>();
ProjectViewModel projectViewModel; ProjectViewModel projectViewModel;
AuthenticatedUser user; AuthenticatedUser user;
@override @override
@ -59,118 +61,118 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
bool expandFlag = false; bool expandFlag = false;
Widget build(BuildContext context) { Widget build(BuildContext context) {
imagesInfo.add(ImagesInfo( imagesInfo.add(
imageEn: ImagesInfo(
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png', imageEn:
imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png',
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'), imageAr:
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'),
); );
imagesInfo.add(ImagesInfo( imagesInfo.add(
imageEn: ImagesInfo(
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', imageEn:
imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png',
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), imageAr:
'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'),
); );
projectViewModel = Provider.of(context); projectViewModel = Provider.of(context);
return AppScaffold( return AppScaffold(
appBarTitle: TranslationBase.of(context).myFamilyFiles, appBarTitle: TranslationBase.of(context).myFamilyFiles,
isShowAppBar: widget.isAppbarVisible, isShowAppBar: widget.isAppbarVisible,
imagesInfo: imagesInfo, // imagesInfo: imagesInfo,
description: TranslationBase.of(context).familyInfo, description: TranslationBase.of(context).familyInfo,
body: Scaffold( body: Scaffold(
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: Size.fromHeight(65.0), preferredSize: Size.fromHeight(65.0),
child: Stack( child: Stack(
children: <Widget>[ children: <Widget>[
Positioned( Positioned(
bottom: 1, bottom: 1,
left: 0, left: 0,
right: 0, right: 0,
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container( child: Container(
color: Theme.of(context) color: Theme.of(context)
.scaffoldBackgroundColor .scaffoldBackgroundColor
.withOpacity(0.8), .withOpacity(0.8),
height: 70.0, height: 70.0,
),
), ),
), ),
Center( ),
child: Container( Center(
height: 60.0, child: Container(
margin: EdgeInsets.only(top: 10.0), height: 60.0,
width: MediaQuery.of(context).size.width * 0.92, // 0.9, margin: EdgeInsets.only(top: 10.0),
decoration: BoxDecoration( width: MediaQuery.of(context).size.width * 0.92, // 0.9,
border: Border( decoration: BoxDecoration(
bottom: BorderSide( border: Border(
color: Theme.of(context).dividerColor, bottom: BorderSide(
width: 0.9), //width: 0.7 color: Theme.of(context).dividerColor,
), width: 0.9), //width: 0.7
color: Colors.white), ),
child: Center( color: Colors.white),
child: TabBar( child: Center(
isScrollable: true, child: TabBar(
controller: _tabController, isScrollable: true,
indicatorWeight: 5.0, controller: _tabController,
//indicatorSize: TabBarIndicatorSize.label, indicatorWeight: 5.0,
indicatorSize: TabBarIndicatorSize.tab, //indicatorSize: TabBarIndicatorSize.label,
indicatorSize: TabBarIndicatorSize.tab,
indicatorColor: Theme.of(context).primaryColor,
labelColor: Theme.of(context).primaryColor,
labelPadding:
EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0),
unselectedLabelColor: Colors.grey[800],
tabs: [
Container( indicatorColor: Theme.of(context).primaryColor,
width: MediaQuery.of(context).size.width * 0.30, labelColor: Theme.of(context).primaryColor,
child: Center( labelPadding:
child: AppText(TranslationBase.of(context).family), EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0),
), unselectedLabelColor: Colors.grey[800],
tabs: [
Container(
width: MediaQuery.of(context).size.width * 0.30,
child: Center(
child: AppText(TranslationBase.of(context).family),
), ),
Container( ),
width: MediaQuery.of(context).size.width * 0.30, Container(
child: Center( width: MediaQuery.of(context).size.width * 0.30,
child: AppText(TranslationBase.of(context).request), child: Center(
), child: AppText(TranslationBase.of(context).request),
), ),
], ),
), ],
), ),
), ),
), ),
], ),
),
),
body: Column(
children: <Widget>[
Expanded(
child: (user != null && projectViewModel.isLogin) ? TabBarView(
physics: BouncingScrollPhysics(),
controller: _tabController,
children: [
myFamilyDetails(context),
myFamilyRequest(context)
],
) : Container(child:AppText('Loading..')),
)
], ],
), ),
), ),
); body: Column(
children: <Widget>[
Expanded(
child: (user != null && projectViewModel.isLogin)
? TabBarView(
physics: BouncingScrollPhysics(),
controller: _tabController,
children: [
myFamilyDetails(context),
myFamilyRequest(context)
],
)
: Container(child: AppText('Loading..')),
)
],
),
),
);
return AppScaffold( return AppScaffold(
appBarTitle: TranslationBase.of(context).myFamilyFiles, appBarTitle: TranslationBase.of(context).myFamilyFiles,
isShowAppBar: widget.isAppbarVisible, isShowAppBar: widget.isAppbarVisible,
body: SingleChildScrollView( body: SingleChildScrollView(
child: Container( child: Container(
height: SizeConfig.screenHeight *.9, height: SizeConfig.screenHeight * .9,
width: SizeConfig.realScreenWidth, width: SizeConfig.realScreenWidth,
padding: EdgeInsets.all(20), padding: EdgeInsets.all(20),
child: Stack( child: Stack(
@ -179,11 +181,13 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
controller: _tabController, controller: _tabController,
indicatorColor: Colors.red, indicatorColor: Colors.red,
tabs: [ tabs: [
Tab( // padding: EdgeInsets.all(6),
child:AppText(TranslationBase.of(context).family)),
Tab( Tab(
// padding: EdgeInsets.all(6), // padding: EdgeInsets.all(6),
child:AppText(TranslationBase.of(context).request)), child: AppText(TranslationBase.of(context).family)),
Tab(
// padding: EdgeInsets.all(6),
child:
AppText(TranslationBase.of(context).request)),
], ],
), ),
TabBarView( TabBarView(
@ -317,13 +321,13 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
Widget myFamilyRequest(context) { Widget myFamilyRequest(context) {
return //Padding( return //Padding(
// padding: const EdgeInsets.symmetric(horizontal: 10.0), // padding: const EdgeInsets.symmetric(horizontal: 10.0),
// child: // child:
SingleChildScrollView( SingleChildScrollView(
child: Container( child: Container(
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,
margin: EdgeInsets.only(top:65), margin: EdgeInsets.only(top: 65),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
RoundedContainer( RoundedContainer(
child: ExpansionTile( child: ExpansionTile(
@ -375,13 +379,21 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
// )), // )),
Column(children: [ Column(children: [
Padding( Padding(
padding: EdgeInsets.only(left:10, right:10), child:Row(children: [ padding: EdgeInsets.only(
Expanded(flex: 3, child: AppText('Name')), left: 10, right: 10),
Expanded(flex: 1, child: AppText('Allow')), child: Row(children: [
Expanded(flex: 1, child: AppText('Reject')), Expanded(
])), flex: 3, child: AppText('Name')),
Expanded(
flex: 1, child: AppText('Allow')),
Expanded(
flex: 1,
child: AppText('Reject')),
])),
Column( Column(
children:familyFileProvider.allSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList children: familyFileProvider
.allSharedRecordsByStatusResponse
.getAllSharedRecordsByStatusList
.map<Widget>((result) { .map<Widget>((result) {
return Padding( return Padding(
padding: EdgeInsets.all(10), padding: EdgeInsets.all(10),
@ -400,7 +412,9 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
), ),
onPressed: () { onPressed: () {
acceptRemoveRequest( acceptRemoveRequest(
result.iD, 3, context); result.iD,
3,
context);
}, },
)), )),
Expanded( Expanded(
@ -412,7 +426,9 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
), ),
onPressed: () { onPressed: () {
acceptRemoveRequest( acceptRemoveRequest(
result.iD,4, context); result.iD,
4,
context);
}, },
)) ))
], ],
@ -462,13 +478,15 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
flex: 3, flex: 3,
child: child: Text(
Text(result.patientName)), result.patientName)),
Expanded( Expanded(
flex: 2, flex: 2,
child: AppText( child: AppText(
result.statusDescription, result.statusDescription,
color: result.status==3 ? Colors.green: Colors.red, color: result.status == 3
? Colors.green
: Colors.red,
)), )),
], ],
)); ));
@ -487,8 +505,8 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
children: <Widget>[ children: <Widget>[
FutureBuilder( FutureBuilder(
future: getUserViewRequest(), // async work future: getUserViewRequest(), // async work
builder: builder: (BuildContext context,
(BuildContext context, AsyncSnapshot<dynamic> snapshot) { AsyncSnapshot<dynamic> snapshot) {
switch (snapshot.connectionState) { switch (snapshot.connectionState) {
case ConnectionState.waiting: case ConnectionState.waiting:
return Padding( return Padding(
@ -502,38 +520,43 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
else else
return Column( return Column(
children: [ children: [
// Padding( // Padding(
// padding:EdgeInsets.only(left:10, right:10), // padding:EdgeInsets.only(left:10, right:10),
// child: Row( // child: Row(
// mainAxisAlignment: // mainAxisAlignment:
// MainAxisAlignment.spaceBetween, // MainAxisAlignment.spaceBetween,
// children: <Widget>[ // children: <Widget>[
// Expanded( // Expanded(
// flex: 3, // flex: 3,
// child: AppText( // child: AppText(
// TranslationBase.of(context).request), // TranslationBase.of(context).request),
// ), // ),
// Expanded( // Expanded(
// flex: 2, // flex: 2,
// child: AppText( // child: AppText(
// TranslationBase.of(context).switchUser, // TranslationBase.of(context).switchUser,
// )), // )),
// Expanded( // Expanded(
// flex: 1, // flex: 1,
// child: AppText( // child: AppText(
// TranslationBase.of(context).deleteView, // TranslationBase.of(context).deleteView,
// )), // )),
// ], // ],
// )), // )),
Column(children: [ Column(children: [
Padding( Padding(
padding:EdgeInsets.only(left:10, right:10), padding:
child: Row(children: [ EdgeInsets.only(left: 10, right: 10),
Expanded(flex: 3, child: AppText('Name')), child: Row(children: [
Expanded(flex: 1, child: AppText('Delete')), Expanded(
])), flex: 3, child: AppText('Name')),
Expanded(
flex: 1, child: AppText('Delete')),
])),
Column( Column(
children: familyFileProvider.allSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList children: familyFileProvider
.allSharedRecordsByStatusResponse
.getAllSharedRecordsByStatusList
.map<Widget>((result) { .map<Widget>((result) {
return Padding( return Padding(
padding: EdgeInsets.all(10), padding: EdgeInsets.all(10),
@ -541,7 +564,8 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
flex: 3, flex: 3,
child: AppText(result.patientName)), child: AppText(
result.patientName)),
Expanded( Expanded(
flex: 1, flex: 1,
child: IconButton( child: IconButton(
@ -550,8 +574,8 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
color: Colors.black, color: Colors.black,
), ),
onPressed: () { onPressed: () {
deactivateRequest(result.iD, deactivateRequest(
5, context); result.iD, 5, context);
}, },
)), )),
], ],
@ -625,17 +649,17 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
} }
switchUser(user, context) { switchUser(user, context) {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
// this // this
// .familyFileProvider // .familyFileProvider
// .silentLoggin(user) // .silentLoggin(user)
// .then((value) => loginAfter(value, context)); // .then((value) => loginAfter(value, context));
// Utils.showProgressDialog(context); // Utils.showProgressDialog(context);
this this
.familyFileProvider .familyFileProvider
.silentLoggin(user is AuthenticatedUser ? null : user, .silentLoggin(user is AuthenticatedUser ? null : user,
mainUser: user is AuthenticatedUser) mainUser: user is AuthenticatedUser)
.then((value) => loginAfter(value, context)) .then((value) => loginAfter(value, context))
.catchError((err) { .catchError((err) {
print(err); print(err);
@ -644,26 +668,26 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
}); });
} }
loginAfter(result, context) async{ loginAfter(result, context) async {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
// var familyFile = await sharedPref.getObject(FAMILY_FILE); // var familyFile = await sharedPref.getObject(FAMILY_FILE);
// var mainUser = await sharedPref.getObject(MAIN_USER); // var mainUser = await sharedPref.getObject(MAIN_USER);
// result = CheckActivationCode.fromJson(result); // result = CheckActivationCode.fromJson(result);
// this.sharedPref.clear(); // this.sharedPref.clear();
// this.sharedPref.setObject(FAMILY_FILE, familyFile); // this.sharedPref.setObject(FAMILY_FILE, familyFile);
// this.sharedPref.setObject(MAIN_USER, mainUser); // this.sharedPref.setObject(MAIN_USER, mainUser);
// result.list.isFamily = true; // result.list.isFamily = true;
// this.sharedPref.setObject(USER_PROFILE, result.list); // this.sharedPref.setObject(USER_PROFILE, result.list);
// this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); // this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID);
// this.sharedPref.setString(TOKEN, result.authenticationTokenID); // this.sharedPref.setString(TOKEN, result.authenticationTokenID);
// //
// authenticatedUserObject.isLogin = true; // authenticatedUserObject.isLogin = true;
// appointmentRateViewModel.isLogin = true; // appointmentRateViewModel.isLogin = true;
// projectViewModel.isLogin = true; // projectViewModel.isLogin = true;
// //this.checkIfUserAgreedBefore(result), // //this.checkIfUserAgreedBefore(result),
// Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
// HOME, // HOME,
// ); // );
result = list.CheckActivationCode.fromJson(result); result = list.CheckActivationCode.fromJson(result);
var familyFile = await sharedPref.getObject(FAMILY_FILE); var familyFile = await sharedPref.getObject(FAMILY_FILE);
var mainUser = await sharedPref.getObject(MAIN_USER); var mainUser = await sharedPref.getObject(MAIN_USER);
@ -687,32 +711,30 @@ class _MyFamily extends State<MyFamily> with TickerProviderStateMixin {
Map<String, dynamic> request = {}; Map<String, dynamic> request = {};
request["ID"] = ID; request["ID"] = ID;
request["Status"] = status; request["Status"] = status;
this.familyFileProvider.deactivateFamily(request).then((value) => { this.familyFileProvider.deactivateFamily(request).then((value) =>
GifLoaderDialogUtils.hideDialog(context), {GifLoaderDialogUtils.hideDialog(context), refreshFamily(context)});
refreshFamily(context)
});
} }
acceptRemoveRequest(ID, status, context) { acceptRemoveRequest(ID, status, context) {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
Map<String, dynamic> request = {}; Map<String, dynamic> request = {};
request["ID"] = ID; request["ID"] = ID;
request["Status"] = status; request["Status"] = status;
this.familyFileProvider.acceptRejectFamily(request).then((value) => { this.familyFileProvider.acceptRejectFamily(request).then((value) =>
GifLoaderDialogUtils.hideDialog(context), {GifLoaderDialogUtils.hideDialog(context), refreshFamily(context)});
refreshFamily(context)
});
} }
checkUserData() async{
checkUserData() async {
if (await this.sharedPref.getObject(USER_PROFILE) != null) { if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson( var data = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE)); await this.sharedPref.getObject(USER_PROFILE));
var data2 = AuthenticatedUser.fromJson( var data2 = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(MAIN_USER)); await this.sharedPref.getObject(MAIN_USER));
print(data2); print(data2);
setState(() { setState(() {
this.user = data; this.user = data;
}); });
} }
} }
} }

@ -107,7 +107,6 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
// }); // });
Future.delayed(const Duration(seconds: 2), () { Future.delayed(const Duration(seconds: 2), () {
requestPermissions(); requestPermissions();
getUserData(); getUserData();
@ -119,9 +118,8 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
projectProvider = Provider.of(context); projectProvider = Provider.of(context);
return Container(child: return Container(
isShow ? getStack() child: isShow ? getStack() : Stack(children: <Widget>[Container()]));
: Stack(children: <Widget>[Container()]));
} }
Widget getStack() { Widget getStack() {
@ -134,7 +132,7 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
// mainAxisSize: MainAxisSize.min, // mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.stretch, // crossAxisAlignment: CrossAxisAlignment.stretch,
// children: <Widget>[ // children: <Widget>[
GestureDetector( GestureDetector(
child: Container( child: Container(
child: Image.asset('assets/images/gif/robot-idle.gif'), child: Image.asset('assets/images/gif/robot-idle.gif'),
), ),
@ -151,7 +149,7 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
onTap: () { onTap: () {
setState(() { setState(() {
if (this.mounted) { if (this.mounted) {
isShow =false; isShow = false;
} }
}); });
}, },
@ -780,14 +778,14 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
speak() async { speak() async {
var voice = await flutterTts.getVoices; var voice = await flutterTts.getVoices;
await flutterTts.setVoice({"name": "es-us-x-sfb-local", "locale": "es-US"});
print(voice); print(voice);
if (_currentLocaleId == 'en' && results['ReturnMessage'] != null) { if (_currentLocaleId == 'en' && results['ReturnMessage'] != null) {
await flutterTts.setVoice("en-us-x-sfg#male_1-local" ); //await flutterTts.setLanguage("en-US");
await flutterTts.setLanguage("en-US");
await flutterTts.speak(results['ReturnMessage']); await flutterTts.speak(results['ReturnMessage']);
} else if (results['ReturnMessage_Ar'] != null) { } else if (results['ReturnMessage_Ar'] != null) {
await flutterTts.setLanguage("ar-SA"); await flutterTts.setLanguage("ar-SA");
await flutterTts.setVoice("ar-xa-x-arc-local"); // await flutterTts.setVoice("ar-xa-x-arc-local");
await flutterTts.speak(results['ReturnMessage_Ar']); await flutterTts.speak(results['ReturnMessage_Ar']);
} }
// Future.delayed(const Duration(seconds: 10), () { // Future.delayed(const Duration(seconds: 10), () {
@ -815,6 +813,6 @@ class _FloatingSearchButton extends State<FloatingSearchButton>
user = AuthenticatedUser.fromJson( user = AuthenticatedUser.fromJson(
await this.sharedPref.getObject(USER_PROFILE)); await this.sharedPref.getObject(USER_PROFILE));
} }
await flutterTts.setVoice("en-us-x-sfg#male_1-local" ); //await flutterTts.setVoice("en-us-x-sfg#male_1-local");
} }
} }

Loading…
Cancel
Save