570 lines
19 KiB
Dart
570 lines
19 KiB
Dart
import 'dart:convert';
|
|
import 'dart:developer';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:pwa_ios/main.dart';
|
|
import 'package:pwa_ios/model/interaction_data.dart';
|
|
import 'package:pwa_ios/model/json_form_data.dart';
|
|
import 'package:pwa_ios/model/save_interaction.dart';
|
|
import 'package:pwa_ios/model/userdata_model.dart';
|
|
import 'package:pwa_ios/utils/apicall.dart';
|
|
import 'package:pwa_ios/utils/mockapi.dart';
|
|
import 'package:pwa_ios/utils/sessionmanager.dart';
|
|
import 'package:pwa_ios/utils/util.dart';
|
|
import 'package:pwa_ios/viewmodel/configprovider.dart';
|
|
import 'package:pwa_ios/viewmodel/interactionprovider.dart';
|
|
import 'package:pwa_ios/viewmodel/loginprovider.dart';
|
|
import 'package:pwa_ios/viewmodel/viewinteractionprovider.dart';
|
|
import 'package:pwa_ios/views/login.dart';
|
|
import 'package:pwa_ios/utils/validations.dart';
|
|
import 'package:pwa_ios/widgets/custombutton.dart';
|
|
import 'package:pwa_ios/widgets/customtextfield.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
|
|
|
class ProfileScreen extends StatefulWidget {
|
|
const ProfileScreen({super.key});
|
|
|
|
@override
|
|
State<ProfileScreen> createState() => _ProfileScreenState();
|
|
}
|
|
|
|
class _ProfileScreenState extends State<ProfileScreen> {
|
|
final nameTextController = TextEditingController();
|
|
final emailTextController = TextEditingController();
|
|
final domainTextConrtroller = TextEditingController();
|
|
final secretKeyTextConrtroller = TextEditingController();
|
|
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
|
late String _username;
|
|
late String _useremail;
|
|
late String _domain;
|
|
late String _key;
|
|
late Future<bool> _login;
|
|
late String bytes;
|
|
Uint8List? imagebytes;
|
|
late String base64Image;
|
|
late LoginProvider provider;
|
|
ValueNotifier<String> username = ValueNotifier<String>(' ');
|
|
File? imageFile;
|
|
|
|
bool toggleLockDomain = false;
|
|
bool toggleLockKey = false;
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
provider = Provider.of<LoginProvider>(context, listen: false);
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
UserData userData = await provider.getUserData();
|
|
|
|
print(userData.name);
|
|
print(userData.email);
|
|
print(userData.secretkey);
|
|
|
|
_username = userData.name!;
|
|
nameTextController.text = _username;
|
|
username.value = _username;
|
|
_useremail = userData.email!;
|
|
emailTextController.text = _useremail;
|
|
_domain = userData.domainUrl!;
|
|
domainTextConrtroller.text = _domain;
|
|
_key = userData.secretkey!;
|
|
secretKeyTextConrtroller.text = _key;
|
|
|
|
setState(() {
|
|
bytes = userData.imageBytes ?? "";
|
|
imagebytes = base64Decode(userData.imageBytes ?? "");
|
|
base64Image = userData.imageBytes ?? "";
|
|
print("images");
|
|
print(imagebytes);
|
|
// bytes = _prefs.then((SharedPreferences prefs) {
|
|
// imagebytes = base64Decode(prefs.getString('image') ?? "");
|
|
// print("images");
|
|
// print(imagebytes);
|
|
// return prefs.getString('image') ?? "";
|
|
// });
|
|
});
|
|
});
|
|
}
|
|
|
|
@override
|
|
void didChangeDependencies() {
|
|
// TODO: implement didChangeDependencies
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
provider = Provider.of<LoginProvider>(context, listen: false);
|
|
|
|
UserData userData = await provider.getUserData();
|
|
print(userData.imageBytes);
|
|
bytes = userData.imageBytes ?? "";
|
|
imagebytes = base64Decode(userData.imageBytes ?? "");
|
|
print("images1");
|
|
print(imagebytes);
|
|
});
|
|
super.didChangeDependencies();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return OrientationBuilder(
|
|
builder: (BuildContext context, Orientation orientation) {
|
|
return Scaffold(
|
|
resizeToAvoidBottomInset: false,
|
|
body: orientation == Orientation.portrait
|
|
? Column(
|
|
children: _buildBody(orientation),
|
|
)
|
|
: Row(
|
|
children: _buildBody(orientation),
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
List<Widget> _buildBody(Orientation orientation) {
|
|
return [
|
|
Expanded(
|
|
flex: 1,
|
|
child: Container(
|
|
width: orientation == Orientation.portrait
|
|
? double.infinity
|
|
: MediaQuery.of(context).size.height * 0.35,
|
|
decoration: const BoxDecoration(
|
|
gradient: LinearGradient(
|
|
begin: Alignment.topRight,
|
|
end: Alignment.bottomLeft,
|
|
colors: [
|
|
Color.fromARGB(255, 8, 39, 92),
|
|
Color.fromARGB(255, 11, 60, 144),
|
|
Color.fromARGB(255, 26, 64, 129),
|
|
],
|
|
)),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Container(
|
|
padding: orientation == Orientation.portrait
|
|
? const EdgeInsets.only(top: 40)
|
|
: EdgeInsets.zero,
|
|
width: MediaQuery.of(context).size.height * 0.45,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Stack(
|
|
alignment: AlignmentDirectional.bottomEnd,
|
|
children: [
|
|
SizedBox(
|
|
width: isTablet ? 160 : 100,
|
|
height: isTablet ? 160 : 100,
|
|
child: CircleAvatar(
|
|
backgroundColor:
|
|
const Color.fromARGB(255, 126, 134, 147),
|
|
radius: isTablet ? 140 - 5 : 100 - 5,
|
|
backgroundImage: imageFile != null
|
|
? Image.file(
|
|
imageFile!,
|
|
fit: BoxFit.cover,
|
|
).image
|
|
: imagebytes != null
|
|
? Image.memory(imagebytes!).image
|
|
: const NetworkImage(
|
|
'https://via.placeholder.com/150'),
|
|
),
|
|
),
|
|
InkWell(
|
|
onTap: () {
|
|
showAlertDialog(context);
|
|
},
|
|
child: const CircleAvatar(
|
|
backgroundColor: Colors.white,
|
|
child: Icon(
|
|
Icons.camera_alt_sharp,
|
|
size: 30,
|
|
color: Color.fromARGB(255, 8, 39, 92),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 20,
|
|
),
|
|
Text(
|
|
'Hello,${username.value}',
|
|
style: const TextStyle(fontSize: 22, color: Colors.white),
|
|
),
|
|
SizedBox(
|
|
height: isTablet ? 20 : 5,
|
|
),
|
|
CustomButton(
|
|
backgroundColor: Colors.grey.shade300,
|
|
onPressed: () async {
|
|
//cancelTimer();
|
|
bool result =
|
|
await InternetConnectionChecker().hasConnection;
|
|
if (result == true) {
|
|
showLoaderDialog(context);
|
|
|
|
// ignore: use_build_context_synchronously
|
|
final provider = Provider.of<ViewInteractionProvider>(
|
|
context,
|
|
listen: false);
|
|
final prov = Provider.of<InteractionProvider>(context,
|
|
listen: false);
|
|
List<SaveInteractionFormJson> senSavedList = [];
|
|
List<SaveInteraction> savedList =
|
|
await provider.getAllRecords();
|
|
for (var obj in savedList) {
|
|
senSavedList.add(prov.formJson(obj));
|
|
}
|
|
|
|
SendSaveJson jsonData =
|
|
SendSaveJson(savedList: senSavedList);
|
|
DataJson dataJson = DataJson(sendSaveJson: jsonData);
|
|
String jsonstr = saveFormJsonToJson(jsonData);
|
|
print(jsonstr);
|
|
String jsonDataEncoded =
|
|
saveInteractionFormJsonToJson(dataJson);
|
|
print(jsonDataEncoded);
|
|
|
|
var result = await MockApiCall().postSavedData(
|
|
jsonstr,
|
|
"/Users/aissel/Library/Developer/CoreSimulator/Devices/1E435121-7E65-45C6-9E0B-411C8B9915F5/data/Containers/Data/Application/4B7EDC75-F376-4A21-A1E4-2A621BCCBD13/Documents/konectar/files/Flutter Questionaire.pdf");
|
|
if (result != null) {
|
|
Navigator.pop(context);
|
|
_displaySnackBar('Data synced sucessfully!');
|
|
} else {
|
|
Navigator.pop(context);
|
|
_displaySnackBar('Something went wrong!');
|
|
}
|
|
}
|
|
},
|
|
textColor: Colors.black,
|
|
title: "Sync now",
|
|
height: isTablet ? 40 : 35,
|
|
width: 120,
|
|
fontsize: 14,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 20.0,
|
|
vertical: orientation == Orientation.portrait ? 10 : 0),
|
|
child: _buildform(),
|
|
))
|
|
];
|
|
}
|
|
|
|
showLoaderDialog(BuildContext context) {
|
|
AlertDialog alert = AlertDialog(
|
|
content: Row(
|
|
children: [
|
|
const CircularProgressIndicator(),
|
|
Container(
|
|
margin: const EdgeInsets.only(left: 7),
|
|
child: Text("Syncing...")),
|
|
],
|
|
),
|
|
);
|
|
showDialog(
|
|
barrierDismissible: false,
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return alert;
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _buildform() {
|
|
return SingleChildScrollView(
|
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
|
// const Expanded(child: SizedBox.shrink()),
|
|
const Text(
|
|
'Profile Settings',
|
|
style: TextStyle(fontSize: 22),
|
|
),
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
CustomTextField(labelText: "Name", controller: nameTextController),
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
CustomTextField(
|
|
labelText: "Email",
|
|
controller: emailTextController,
|
|
enabled: false,
|
|
),
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
Row(
|
|
children: [
|
|
Flexible(
|
|
child: CustomTextField(
|
|
labelText: "Application url",
|
|
controller: domainTextConrtroller,
|
|
enabled: toggleLockDomain,
|
|
obscure: !toggleLockDomain,
|
|
),
|
|
),
|
|
IconButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
toggleLockDomain = !toggleLockDomain;
|
|
});
|
|
},
|
|
icon: toggleLockDomain
|
|
? const Icon(Icons.lock_open)
|
|
: const Icon(Icons.lock),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
Row(
|
|
children: [
|
|
Flexible(
|
|
child: CustomTextField(
|
|
labelText: "Secret key",
|
|
controller: secretKeyTextConrtroller,
|
|
enabled: toggleLockKey,
|
|
obscure: !toggleLockKey,
|
|
),
|
|
),
|
|
IconButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
toggleLockKey = !toggleLockKey;
|
|
});
|
|
},
|
|
icon: toggleLockKey
|
|
? const Icon(Icons.lock_open)
|
|
: const Icon(Icons.lock),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
Align(
|
|
alignment: Alignment.bottomRight,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
CustomButton(
|
|
backgroundColor: Colors.green.shade800,
|
|
onPressed: () {
|
|
if (textFieldsValidation().isEmpty) {
|
|
//_joinMeeting(roomText.text, "demo meet2");
|
|
_saveprefs(
|
|
nameTextController.text,
|
|
emailTextController.text,
|
|
domainTextConrtroller.text,
|
|
secretKeyTextConrtroller.text,
|
|
base64Image)
|
|
.then((value) {
|
|
setState(() {
|
|
username.value = nameTextController.text;
|
|
// final bytes = imageFile!.readAsBytesSync();
|
|
// saveImage(bytes);
|
|
});
|
|
_displaySnackBar('Updated Sucessfully!');
|
|
});
|
|
} else {
|
|
_displaySnackBar(textFieldsValidation());
|
|
}
|
|
},
|
|
textColor: Colors.white,
|
|
title: "Save Profile",
|
|
height: 50,
|
|
fontsize: 16,
|
|
),
|
|
CustomButton(
|
|
backgroundColor: Colors.red.shade800,
|
|
onPressed: () {
|
|
showDeleteProfileAlertDialog(context);
|
|
},
|
|
textColor: Colors.white,
|
|
title: "Delete Profile",
|
|
height: 50,
|
|
fontsize: 16,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 30,
|
|
),
|
|
]),
|
|
);
|
|
}
|
|
|
|
Future<void> _saveprefs(String name, String email, String domain, String key,
|
|
String imageBytes) async {
|
|
UserData userData = UserData(
|
|
email: email,
|
|
name: name,
|
|
domainUrl: domain,
|
|
secretkey: key,
|
|
imageBytes: imageBytes);
|
|
await provider.saveUserData(userData);
|
|
}
|
|
|
|
_displaySnackBar(String msg) {
|
|
final snackBar = SnackBar(content: Text(msg));
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
//scaffoldKeyLogin.currentState!.showSnackBar(snackBar);
|
|
}
|
|
|
|
String textFieldsValidation() {
|
|
if (FieldValidation.validateName(nameTextController.text).isNotEmpty) {
|
|
return FieldValidation.validateName(nameTextController.text);
|
|
}
|
|
if (FieldValidation.validateEmail(emailTextController.text).isNotEmpty) {
|
|
return FieldValidation.validateEmail(emailTextController.text);
|
|
}
|
|
if (FieldValidation.validateUrl(domainTextConrtroller.text).isNotEmpty) {
|
|
return FieldValidation.validateUrl(domainTextConrtroller.text);
|
|
}
|
|
if (FieldValidation.validateSecretKey(secretKeyTextConrtroller.text)
|
|
.isNotEmpty) {
|
|
return FieldValidation.validateSecretKey(secretKeyTextConrtroller.text);
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
_getFromGallery() async {
|
|
try {
|
|
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
|
|
if (image == null) return;
|
|
final imageTemp = File(image.path);
|
|
setState(() => imageFile = imageTemp);
|
|
final bytes = imageFile!.readAsBytesSync();
|
|
await saveImage(bytes);
|
|
} on PlatformException catch (e) {
|
|
print('Failed to pick image: $e');
|
|
}
|
|
}
|
|
|
|
_getFromCamera() async {
|
|
try {
|
|
final image = await ImagePicker().pickImage(source: ImageSource.camera);
|
|
if (image == null) return;
|
|
final imageTemp = File(image.path);
|
|
setState(() => imageFile = imageTemp);
|
|
final bytes = imageFile!.readAsBytesSync();
|
|
await saveImage(bytes);
|
|
} on PlatformException catch (e) {
|
|
print('Failed to pick image: $e');
|
|
}
|
|
}
|
|
|
|
showAlertDialog(BuildContext context) {
|
|
// set up the buttons
|
|
Widget cancelButton = TextButton(
|
|
child: Text("Gallery"),
|
|
onPressed: () async {
|
|
await _getFromGallery();
|
|
setState(() {});
|
|
Navigator.pop(context);
|
|
},
|
|
);
|
|
Widget continueButton = TextButton(
|
|
child: Text("Camera"),
|
|
onPressed: () async {
|
|
await _getFromCamera();
|
|
setState(() {});
|
|
Navigator.pop(context);
|
|
},
|
|
);
|
|
|
|
// set up the AlertDialog
|
|
AlertDialog alert = AlertDialog(
|
|
title: Text(""),
|
|
content: Text("Profile photo"),
|
|
actions: [
|
|
cancelButton,
|
|
continueButton,
|
|
],
|
|
);
|
|
|
|
// show the dialog
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return alert;
|
|
},
|
|
);
|
|
}
|
|
|
|
showDeleteProfileAlertDialog(BuildContext context) {
|
|
// set up the buttons
|
|
Widget cancelButton = TextButton(
|
|
child: Text("YES"),
|
|
onPressed: () async {
|
|
await provider.deleteUserData().then((value) async {
|
|
await SessionManager().clearSession().then((value) {
|
|
Navigator.of(context).popUntil((route) => route.isFirst);
|
|
Navigator.of(context, rootNavigator: true)
|
|
.pushReplacementNamed("/");
|
|
});
|
|
});
|
|
},
|
|
);
|
|
Widget continueButton = TextButton(
|
|
child: Text("NO"),
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
);
|
|
|
|
// set up the AlertDialog
|
|
AlertDialog alert = AlertDialog(
|
|
title: const Text(""),
|
|
content: const Text(
|
|
"Are you sure you want to delete the profile as it is not synced and all the data will be unsaved ?"),
|
|
actions: [
|
|
cancelButton,
|
|
continueButton,
|
|
],
|
|
);
|
|
|
|
// show the dialog
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return alert;
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<bool> saveImage(List<int> imageBytes) async {
|
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
base64Image = base64Encode(imageBytes);
|
|
UserData userData = await provider.getUserData();
|
|
userData.imageBytes = base64Image;
|
|
await provider.saveUserData(userData);
|
|
return prefs.setString("image", base64Image);
|
|
}
|
|
|
|
Future<Image> getImage() async {
|
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
Uint8List bytes = base64Decode(prefs.getString("image")!);
|
|
return Image.memory(bytes);
|
|
}
|
|
}
|