null safe code + latest dart SDK

This commit is contained in:
Muhammad Hamza 2021-10-14 10:00:07 +05:00
parent 368f9ef617
commit 6b5d4c3958
25 changed files with 204 additions and 253 deletions

View File

@ -6,7 +6,7 @@ class Animator extends StatefulWidget {
final Widget child;
final Duration time;
const Animator(this.child, this.time, {Key key}) : super(key: key);
const Animator(this.child, this.time, {Key? key}) : super(key: key);
@override
_AnimatorState createState() => _AnimatorState();
@ -14,9 +14,9 @@ class Animator extends StatefulWidget {
class _AnimatorState extends State<Animator>
with SingleTickerProviderStateMixin {
Timer timer;
AnimationController animationController;
Animation animation;
Timer? timer;
AnimationController? animationController;
Animation? animation;
@override
void initState() {
@ -24,27 +24,27 @@ class _AnimatorState extends State<Animator>
animationController = AnimationController(
duration: const Duration(milliseconds: 290), vsync: this);
animation =
CurvedAnimation(parent: animationController, curve: Curves.easeInOut);
timer = Timer(widget.time, animationController.forward);
CurvedAnimation(parent: animationController!, curve: Curves.easeInOut);
timer = Timer(widget.time, animationController!.forward);
}
@override
void dispose() {
animationController.dispose();
animationController!.dispose();
super.dispose();
timer.cancel();
timer!.cancel();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animation,
animation: animation!,
child: widget.child,
builder: (BuildContext context, Widget child) {
builder: (BuildContext context, Widget? child) {
return Opacity(
opacity: animation.value,
opacity: animation!.value,
child: Transform.translate(
offset: Offset(0.0, (1 - animation.value) * 20),
offset: Offset(0.0, (1 - animation!.value) * 20),
child: child,
),
);
@ -53,11 +53,11 @@ class _AnimatorState extends State<Animator>
}
}
Timer timer;
Timer? timer;
Duration duration = const Duration();
Duration wait() {
if (timer == null || !timer.isActive) {
if (timer == null || !timer!.isActive) {
timer = Timer(const Duration(microseconds: 120), () {
duration = const Duration();
});
@ -69,7 +69,7 @@ Duration wait() {
class WidgetAnimator extends StatelessWidget {
final Widget child;
const WidgetAnimator({this.child, Key key}) : super(key: key);
const WidgetAnimator({required this.child, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -14,8 +14,8 @@ class EntranceFader extends StatefulWidget {
final Offset offset;
const EntranceFader({
Key key,
this.child,
Key? key,
required this.child,
this.delay = const Duration(milliseconds: 0),
this.duration = const Duration(milliseconds: 400),
this.offset = const Offset(0.0, 32.0),
@ -29,39 +29,39 @@ class EntranceFader extends StatefulWidget {
class EntranceFaderState extends State<EntranceFader>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation _dxAnimation;
Animation _dyAnimation;
AnimationController? _controller;
Animation? _dxAnimation;
Animation? _dyAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: widget.duration);
_dxAnimation =
Tween(begin: widget.offset.dx, end: 0.0).animate(_controller);
Tween(begin: widget.offset.dx, end: 0.0).animate(_controller!);
_dyAnimation =
Tween(begin: widget.offset.dy, end: 0.0).animate(_controller);
Tween(begin: widget.offset.dy, end: 0.0).animate(_controller!);
Future.delayed(widget.delay, () {
if (mounted) {
_controller.forward();
_controller!.forward();
}
});
}
@override
void dispose() {
_controller.dispose();
_controller!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
animation: _controller!,
builder: (context, child) => Opacity(
opacity: _controller.value,
opacity: _controller!.value,
child: Transform.translate(
offset: Offset(_dxAnimation.value, _dyAnimation.value),
offset: Offset(_dxAnimation!.value, _dyAnimation!.value),
child: widget.child,
),
),

View File

@ -14,6 +14,5 @@ class ScrollBehaviorModified extends ScrollBehavior {
case TargetPlatform.windows:
return const ClampingScrollPhysics();
}
return null;
}
}

View File

@ -17,7 +17,7 @@ void main() {
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -38,7 +38,7 @@ class MyApp extends StatelessWidget {
),
builder: (context, widget) {
return ScrollConfiguration(
behavior: const ScrollBehaviorModified(), child: widget);
behavior: const ScrollBehaviorModified(), child: widget!);
},
initialRoute: AppRoutes.splash,
routes: <String, WidgetBuilder>{

View File

@ -7,8 +7,8 @@ class Contact {
final bool isGroup;
Contact({
this.name,
this.subtitle,
required this.name,
required this.subtitle,
this.photo = '',
this.isGroup = false,
});

View File

@ -8,8 +8,8 @@ class Group {
final bool isGroup;
Group({
this.name,
this.subtitle,
required this.name,
required this.subtitle,
this.photo = '',
this.isGroup = true,
this.members = const [],

View File

@ -5,7 +5,7 @@ import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:simplex_chat/views/contacts/qr_code_details_view.dart';
class AddContactView extends StatefulWidget {
const AddContactView({Key key}) : super(key: key);
const AddContactView({Key? key}) : super(key: key);
@override
_AddContactViewState createState() => _AddContactViewState();
@ -13,16 +13,16 @@ class AddContactView extends StatefulWidget {
class _AddContactViewState extends State<AddContactView> {
final qrKey = GlobalKey(debugLabel: 'qr');
QRViewController _qrViewController;
Barcode result;
QRViewController? _qrViewController;
Barcode? result;
@override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
_qrViewController.pauseCamera();
_qrViewController!.pauseCamera();
} else if (Platform.isIOS) {
_qrViewController.resumeCamera();
_qrViewController!.resumeCamera();
}
}
@ -113,7 +113,7 @@ class _AddContactViewState extends State<AddContactView> {
context,
MaterialPageRoute(
builder: (_) => QRCodeDetailsView(
barcode: result,
barcode: result!,
),
),
);

View File

@ -1,28 +1,23 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simplex_chat/animations/bottom_animation.dart';
import 'package:simplex_chat/app_routes.dart';
import 'package:simplex_chat/constants.dart';
import 'package:simplex_chat/model/contact.dart';
import 'package:simplex_chat/model/group.dart';
import 'package:simplex_chat/providers/drawer_providers.dart';
import 'package:simplex_chat/views/conversation/conversation_view.dart';
class Conversations extends StatefulWidget {
const Conversations({Key key}) : super(key: key);
const Conversations({Key? key}) : super(key: key);
@override
_ConversationsState createState() => _ConversationsState();
}
class _ConversationsState extends State<Conversations> {
bool _eraseMedia = false;
String _photo = '';
String _displayName = '';
bool? _eraseMedia = false;
List<dynamic> _conversations = [];
@ -38,7 +33,7 @@ class _ConversationsState extends State<Conversations> {
// getting data from local storage FOR NOW!!
void _getContacts() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String _contacts = prefs.getString('contacts');
final String? _contacts = prefs.getString('contacts');
if (_contacts != null) {
setState(() {
_contactsList = List.from(Contact.decode(_contacts));
@ -49,7 +44,7 @@ class _ConversationsState extends State<Conversations> {
// getting data from local storage FOR NOW!!
void _getGroups() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String _groups = prefs.getString('groups');
final String? _groups = prefs.getString('groups');
if (_groups != null) {
setState(() {
_groupList = List.from(Group.decode(_groups));
@ -59,14 +54,6 @@ class _ConversationsState extends State<Conversations> {
_gettingGroupContactsChats();
}
void _getUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_displayName = prefs.getString('displayName');
_photo = prefs.getString('photo$_displayName');
});
}
void _gettingGroupContactsChats() {
setState(() {
_conversations = List.from(_contactsList);
@ -76,7 +63,6 @@ class _ConversationsState extends State<Conversations> {
@override
void initState() {
_getUserData();
_getContacts();
_getGroups();
super.initState();
@ -84,7 +70,6 @@ class _ConversationsState extends State<Conversations> {
@override
Widget build(BuildContext context) {
final _drawerProviders = Provider.of<DrawerProvider>(context);
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
@ -93,42 +78,19 @@ class _ConversationsState extends State<Conversations> {
child: Center(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: _addNewContacts,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text('Hi! $_displayName', style: kSmallHeadingStyle),
const Text('Good day!'),
],
),
),
const SizedBox(width: 10.0),
GestureDetector(
onTap: () {
_drawerProviders.currentIndex = 0;
},
child: CircleAvatar(
backgroundImage: _photo.isEmpty
? const AssetImage('assets/dp.png') as ImageProvider
: FileImage(File(_photo)),
),
)
],
),
const SizedBox(height: 15.0),
Row(
children: const [
Icon(Icons.chat, color: kPrimaryColor),
SizedBox(width: 8.0),
Text(
'Conversations',
style: kHeadingStyle,
)
],
const SizedBox(height: 40.0),
GestureDetector(
onTap: _addNewContacts,
child: Row(
children: const [
Icon(Icons.chat, color: kPrimaryColor),
SizedBox(width: 8.0),
Text(
'Conversations',
style: kHeadingStyle,
)
],
),
),
const SizedBox(height: 5.0),
_contactsList.isEmpty
@ -219,7 +181,7 @@ class _ConversationsState extends State<Conversations> {
await Navigator.pushNamed(context, AppRoutes.addContact);
} else {
var value = await Navigator.pushNamed(context, AppRoutes.addGroup);
if (value) {
if (value == true) {
_getGroups();
}
}
@ -414,7 +376,7 @@ class _ConversationsState extends State<Conversations> {
// adding dummy contact
List<Contact> _localList = [];
final String _local = prefs.getString('contacts');
final String? _local = prefs.getString('contacts');
if (_local != null) {
_localList = List.from(Contact.decode(_local));
}
@ -434,9 +396,9 @@ class _ConversationsState extends State<Conversations> {
// adding dummy contact
List<Group> _localListGroup = [];
final String _localGroups = prefs.getString('groups');
final String? _localGroups = prefs.getString('groups');
if (_local != null) {
_localListGroup = List.from(Group.decode(_localGroups));
_localListGroup = List.from(Group.decode(_localGroups!));
}
List<Group> _newGroups = [

View File

@ -6,8 +6,8 @@ import 'package:simplex_chat/widgets/custom_btn.dart';
class QRCodeDetailsView extends StatelessWidget {
final Barcode barcode;
const QRCodeDetailsView({
Key key,
this.barcode,
Key? key,
required this.barcode,
}) : super(key: key);
@override

View File

@ -4,7 +4,8 @@ import 'package:simplex_chat/model/contact.dart';
class ContactDetailsConversation extends StatelessWidget {
final Contact contact;
const ContactDetailsConversation({Key key, this.contact}) : super(key: key);
const ContactDetailsConversation({Key? key, required this.contact})
: super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -6,8 +6,9 @@ import 'package:simplex_chat/views/conversation/group_detail_conversation.dart';
import 'package:simplex_chat/widgets/message_bubble.dart';
class ConversationView extends StatefulWidget {
// ignore: prefer_typing_uninitialized_variables
final data;
const ConversationView({Key key, this.data}) : super(key: key);
const ConversationView({Key? key, this.data}) : super(key: key);
@override
_ConversationViewState createState() => _ConversationViewState();
@ -17,16 +18,16 @@ class _ConversationViewState extends State<ConversationView> {
final ScrollController _scrollController = ScrollController();
final TextEditingController _messageFieldController = TextEditingController();
FocusNode _focus;
FocusNode? _focus;
bool _fieldEnabled = false;
final List<Widget> _chatMessages = [];
@override
void initState() {
_focus = FocusNode();
_focus.addListener(() {
debugPrint('FOCUS ${_focus.hasFocus}');
_fieldEnabled = _focus.hasFocus;
_focus!.addListener(() {
debugPrint('FOCUS ${_focus!.hasFocus}');
_fieldEnabled = _focus!.hasFocus;
debugPrint('MESSAGE ENABLED $_fieldEnabled');
});
super.initState();
@ -36,7 +37,7 @@ class _ConversationViewState extends State<ConversationView> {
void dispose() {
_messageFieldController.dispose();
_scrollController.dispose();
_focus.dispose();
_focus!.dispose();
super.dispose();
}
@ -81,7 +82,7 @@ class _ConversationViewState extends State<ConversationView> {
radius: 15,
// ignore: avoid_dynamic_calls
backgroundImage: widget.data.photo == ''
? const AssetImage('assets/dp.png')
? const AssetImage('assets/dp.png') as ImageProvider
: FileImage(
// ignore: avoid_dynamic_calls
File(widget.data.photo),
@ -175,7 +176,7 @@ class _ConversationViewState extends State<ConversationView> {
));
});
_messageFieldController.clear();
_focus.unfocus();
_focus!.unfocus();
}
},
icon: const Icon(Icons.send_rounded,

View File

@ -8,7 +8,8 @@ import 'package:simplex_chat/model/group.dart';
class GroupDetailsConversation extends StatefulWidget {
final Group group;
const GroupDetailsConversation({Key key, this.group}) : super(key: key);
const GroupDetailsConversation({Key? key, required this.group})
: super(key: key);
@override
_GroupDetailsConversationState createState() =>
@ -33,7 +34,7 @@ class _GroupDetailsConversationState extends State<GroupDetailsConversation> {
// getting groups
void _getGroups() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String _groups = prefs.getString('groups');
final String? _groups = prefs.getString('groups');
if (_groups != null) {
setState(() {
_groupList = List.from(Group.decode(_groups));
@ -44,9 +45,9 @@ class _GroupDetailsConversationState extends State<GroupDetailsConversation> {
// getting data from local storage FOR NOW
void _getContacts() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String _contacts = prefs.getString('contacts');
final String? _contacts = prefs.getString('contacts');
setState(() {
_contactsList = List.from(Contact.decode(_contacts));
_contactsList = List.from(Contact.decode(_contacts!));
});
}
@ -75,7 +76,7 @@ class _GroupDetailsConversationState extends State<GroupDetailsConversation> {
child: CircleAvatar(
radius: 70,
backgroundImage: widget.group.photo == ''
? const AssetImage('assets/dp.png')
? const AssetImage('assets/dp.png') as ImageProvider
: FileImage(File(widget.group.photo)),
),
),
@ -197,8 +198,7 @@ class _GroupDetailsConversationState extends State<GroupDetailsConversation> {
// get index of group in local
int index = 0;
index = _groupList
.indexWhere((group) => group.name == widget.group.name);
index = _groupList.indexWhere((group) => group.name == widget.group.name);
// add the full _members list to the group
Group _updatedGroup = Group(
@ -235,8 +235,7 @@ class _GroupDetailsConversationState extends State<GroupDetailsConversation> {
// get index of group in local
int index = 0;
index = _groupList
.indexWhere((group) => group.name == widget.group.name);
index = _groupList.indexWhere((group) => group.name == widget.group.name);
// new instance of group (updated)
Group _updatedGroup = Group(

View File

@ -9,7 +9,7 @@ import 'package:simplex_chat/model/group.dart';
import 'package:simplex_chat/widgets/custom_text_field.dart';
class AddGroupView extends StatefulWidget {
const AddGroupView({Key key}) : super(key: key);
const AddGroupView({Key? key}) : super(key: key);
@override
_AddGroupViewState createState() => _AddGroupViewState();
@ -18,7 +18,7 @@ class AddGroupView extends StatefulWidget {
class _AddGroupViewState extends State<AddGroupView> {
// Image Picker --> DP properties
final imgPicker = ImagePicker();
File image;
File? image;
String _groupPhotoPath = '';
bool _uploading = false;
bool _imageUploaded = false;
@ -43,16 +43,16 @@ class _AddGroupViewState extends State<AddGroupView> {
// getting data from local storage FOR NOW
void _getContacts() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final String _contacts = prefs.getString('contacts');
final String? _contacts = prefs.getString('contacts');
setState(() {
_contactsList = List.from(Contact.decode(_contacts));
_contactsList = List.from(Contact.decode(_contacts!));
});
}
String _userPhotoPath = '';
void _getUserPhoto() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String _photo = prefs.getString('photo${prefs.getString('displayName')}');
String? _photo = prefs.getString('photo${prefs.getString('displayName')}');
if (_photo != null) {
setState(() {
_userPhotoPath = _photo;
@ -147,8 +147,8 @@ class _AddGroupViewState extends State<AddGroupView> {
textEditingController: _displayNameController,
textInputType: TextInputType.name,
hintText: 'e.g College friends',
validatorFtn: (value) {
if (value.isEmpty) {
validatorFtn: (String? value) {
if (value!.isEmpty) {
return 'Group name cannot be empty';
}
return null;
@ -249,10 +249,9 @@ class _AddGroupViewState extends State<AddGroupView> {
child: FloatingActionButton(
heroTag: 'setup',
onPressed: () async {
if (_formKey.currentState.validate()) {
if (_formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
_addNewGroup(
_displayNameController.text.trim(),
_addNewGroup(_displayNameController.text.trim(),
_descController.text.trim());
_descController.clear();
_displayNameController.clear();
@ -400,7 +399,7 @@ class _AddGroupViewState extends State<AddGroupView> {
void _addNewGroup(String name, String desc) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<Group> _localList = [];
final String _local = prefs.getString('groups');
final String? _local = prefs.getString('groups');
if (_local != null) {
_localList = List.from(Group.decode(_local));
}

View File

@ -1,12 +1,11 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simplex_chat/app_routes.dart';
import 'package:simplex_chat/constants.dart';
import 'package:simplex_chat/providers/drawer_providers.dart';
class MyDrawer extends StatelessWidget {
const MyDrawer({Key key}) : super(key: key);
const MyDrawer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -100,7 +99,7 @@ class MyDrawer extends StatelessWidget {
int _count = 0;
Navigator.of(context).popUntil((route) => _count++ >= 2);
String _name = prefs.getString('displayName');
String? _name = prefs.getString('displayName');
await prefs.remove('displayName');
await prefs.remove('fullName');
await prefs.remove('photo$_name');

View File

@ -1,7 +1,10 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simplex_chat/constants.dart';
import 'package:simplex_chat/providers/drawer_providers.dart';
import 'package:simplex_chat/views/contacts/conversations.dart';
@ -11,13 +14,16 @@ import 'package:simplex_chat/views/profile/profile_view.dart';
class HomeView extends StatefulWidget {
final double maxSlide;
const HomeView({Key key, this.maxSlide}) : super(key: key);
const HomeView({Key? key, required this.maxSlide}) : super(key: key);
@override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
String? _photo = '';
String? _displayName = '';
// views
final List<Widget> _views = [
const ProfileView(),
@ -25,43 +31,88 @@ class _HomeViewState extends State<HomeView> {
const Invitations(),
];
void _getUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_displayName = prefs.getString('displayName');
_photo = prefs.getString('photo$_displayName');
});
}
@override
void initState() {
_getUserData();
super.initState();
}
@override
Widget build(BuildContext context) {
final _drawerProviders = Provider.of<DrawerProvider>(context);
return WillPopScope(
onWillPop: _onWillPop,
child: SafeArea(
child: Scaffold(
drawer: const Drawer(
child: MyDrawer(),
),
body: Builder(builder: (context) {
child: Scaffold(
drawer: const Drawer(
child: MyDrawer(),
),
body: SafeArea(
child: Builder(builder: (context) {
return Stack(
children: [
_views[_drawerProviders.currentIndex],
Positioned(
top: MediaQuery.of(context).size.height * 0.03,
left: MediaQuery.of(context).size.width * 0.03,
child: _drawerProviders.currentIndex == 0
? InkWell(
_drawerProviders.currentIndex == 0
? Positioned(
top: MediaQuery.of(context).size.height * 0.017,
left: MediaQuery.of(context).size.width * 0.02,
child: InkWell(
onTap: () {
_drawerProviders.currentIndex = 1;
_getUserData();
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Icon(Icons.arrow_back),
),
)
: InkWell(
onTap: () {
Scaffold.of(context).openDrawer();
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SvgPicture.asset('assets/menu.svg'),
),
),
),
)
: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
onTap: () {
Scaffold.of(context).openDrawer();
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SvgPicture.asset('assets/menu.svg'),
),
),
const Spacer(),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text('Hi! $_displayName',
style: kSmallHeadingStyle),
const Text('Good day!'),
],
),
const SizedBox(width: 10.0),
GestureDetector(
onTap: () {
_drawerProviders.currentIndex = 0;
},
child: CircleAvatar(
backgroundImage: _photo!.isEmpty
? const AssetImage('assets/dp.png')
as ImageProvider
: FileImage(File(_photo!)),
),
)
],
),
),
],
);
}),

View File

@ -1,31 +1,16 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simplex_chat/constants.dart';
class Invitations extends StatefulWidget {
const Invitations({Key key}) : super(key: key);
const Invitations({Key? key}) : super(key: key);
@override
State<Invitations> createState() => _InvitationsState();
}
class _InvitationsState extends State<Invitations> {
String _photo = '';
String _displayName = '';
void _getUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_displayName = prefs.getString('displayName');
_photo = prefs.getString('photo$_displayName');
});
}
@override
void initState() {
_getUserData();
super.initState();
}
@ -37,25 +22,7 @@ class _InvitationsState extends State<Invitations> {
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text('Hi! $_displayName', style: kSmallHeadingStyle),
const Text('Good day!'),
],
),
const SizedBox(width: 10.0),
CircleAvatar(
backgroundImage: _photo.isEmpty
? const AssetImage('assets/dp.png') as ImageProvider
: FileImage(File(_photo)),
),
],
),
const SizedBox(height: 15.0),
const SizedBox(height: 40.0),
Row(
children: const [
Icon(Icons.inventory_outlined, color: kPrimaryColor),

View File

@ -4,7 +4,7 @@ import 'package:simplex_chat/app_routes.dart';
import 'package:simplex_chat/constants.dart';
class IntroView extends StatelessWidget {
const IntroView({Key key}) : super(key: key);
const IntroView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -7,7 +7,7 @@ import 'package:simplex_chat/constants.dart';
import 'package:simplex_chat/widgets/custom_text_field.dart';
class ProfileView extends StatefulWidget {
const ProfileView({Key key}) : super(key: key);
const ProfileView({Key? key}) : super(key: key);
@override
_ProfileViewState createState() => _ProfileViewState();
@ -21,8 +21,8 @@ class _ProfileViewState extends State<ProfileView> {
// Image Picker --> DP properties
final imgPicker = ImagePicker();
File image;
String _photo = '';
File? image;
String? _photo = '';
bool _uploading = false;
// image buttons options
@ -34,8 +34,8 @@ class _ProfileViewState extends State<ProfileView> {
Icons.camera_alt_rounded
];
String _displayName = '';
String _fullName = '';
String? _displayName = '';
String? _fullName = '';
void _getUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
@ -44,8 +44,8 @@ class _ProfileViewState extends State<ProfileView> {
_displayName = prefs.getString('displayName');
_photo = prefs.getString('photo$_displayName');
});
_displayNameController.text = _displayName;
if (_fullName != null) _fullNameController.text = _fullName;
_displayNameController.text = _displayName!;
if (_fullName != null) _fullNameController.text = _fullName!;
}
@override
@ -85,7 +85,7 @@ class _ProfileViewState extends State<ProfileView> {
_photo != ''
? CircleAvatar(
radius: 100.0,
backgroundImage: FileImage(File(_photo)),
backgroundImage: FileImage(File(_photo!)),
)
: const CircleAvatar(
radius: 100.0,
@ -127,7 +127,7 @@ class _ProfileViewState extends State<ProfileView> {
textInputType: TextInputType.name,
hintText: 'e.g John',
validatorFtn: (value) {
if (value.isEmpty) {
if (value!.isEmpty) {
return 'Display name cannot be empty';
}
return null;
@ -156,8 +156,8 @@ class _ProfileViewState extends State<ProfileView> {
floatingActionButton: FloatingActionButton(
heroTag: 'save',
onPressed: () async {
if (_formKey.currentState.validate()) {
FocusManager.instance.primaryFocus.unfocus();
if (_formKey.currentState!.validate()) {
FocusManager.instance.primaryFocus!.unfocus();
await _createProfile();
const snackBar = SnackBar(
backgroundColor: Colors.green,
@ -179,7 +179,7 @@ class _ProfileViewState extends State<ProfileView> {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('displayName', _displayNameController.text.trim());
await prefs.setString('fullName', _fullNameController.text.trim());
await prefs.setString('photo${_displayNameController.text.trim()}', _photo);
await prefs.setString('photo${_displayNameController.text.trim()}', _photo!);
debugPrint(prefs.getString('photo'));
}

View File

@ -4,7 +4,7 @@ import 'package:simplex_chat/constants.dart';
import 'package:simplex_chat/widgets/custom_btn.dart';
class ScanInvitationView extends StatelessWidget {
const ScanInvitationView({Key key}) : super(key: key);
const ScanInvitationView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -8,7 +8,7 @@ import 'package:simplex_chat/views/home/home_view.dart';
import 'package:simplex_chat/widgets/custom_text_field.dart';
class SetupProfileView extends StatefulWidget {
const SetupProfileView({Key key}) : super(key: key);
const SetupProfileView({Key? key}) : super(key: key);
@override
_SetupProfileViewState createState() => _SetupProfileViewState();
@ -22,7 +22,7 @@ class _SetupProfileViewState extends State<SetupProfileView> {
// Image Picker --> DP properties
final imgPicker = ImagePicker();
File image;
File? image;
String photoUrl = '';
bool _uploading = false;
bool _imageUploaded = false;
@ -63,7 +63,7 @@ class _SetupProfileViewState extends State<SetupProfileView> {
_imageUploaded
? CircleAvatar(
radius: 100.0,
backgroundImage: FileImage(image),
backgroundImage: FileImage(image!),
)
: const CircleAvatar(
radius: 100.0,
@ -105,7 +105,7 @@ class _SetupProfileViewState extends State<SetupProfileView> {
textInputType: TextInputType.name,
hintText: 'e.g John',
validatorFtn: (value) {
if (value.isEmpty) {
if (value!.isEmpty) {
return 'Display name cannot be empty';
}
return null;
@ -136,7 +136,7 @@ class _SetupProfileViewState extends State<SetupProfileView> {
child: FloatingActionButton(
heroTag: 'setup',
onPressed: () async {
if (_formKey.currentState.validate()) {
if (_formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
await _createProfile();

View File

@ -5,7 +5,7 @@ import 'package:simplex_chat/app_routes.dart';
import 'package:simplex_chat/constants.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({Key key}) : super(key: key);
const SplashScreen({Key? key}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();

View File

@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
class CustomButton extends StatelessWidget {
const CustomButton(
{@required this.width,
@required this.height,
@required this.onPressed,
@required this.color,
@required this.child,
Key key})
{required this.width,
required this.height,
required this.onPressed,
required this.color,
required this.child,
Key? key})
: super(key: key);
final double width;
final double height;

View File

@ -3,40 +3,17 @@ import 'package:flutter/material.dart';
class CustomTextField extends StatefulWidget {
final TextEditingController textEditingController;
final TextInputType textInputType;
final FocusNode node;
final String hintText;
final bool isPassword;
final IconData icon;
final Color iconColor;
final Color passIconColor;
final IconData trailing;
final void Function() trailingCallBack;
final Function(String) onChangeFtn;
final void Function() onEditComplete;
final String Function(String) validatorFtn;
final Function(String) onFieldSubmit;
final String errorText;
final String? Function(String?)? validatorFtn;
const CustomTextField({
Key key,
@required this.textEditingController,
@required this.textInputType,
this.trailing,
this.trailingCallBack,
this.node,
@required this.hintText,
this.icon,
this.iconColor,
this.passIconColor,
this.isPassword = false,
this.onChangeFtn,
this.onEditComplete,
Key? key,
required this.textEditingController,
required this.textInputType,
required this.hintText,
this.validatorFtn,
this.onFieldSubmit,
this.errorText,
}) : super(key: key);
@override
@ -64,10 +41,7 @@ class _CustomTextFieldState extends State<CustomTextField> {
controller: widget.textEditingController,
textInputAction: TextInputAction.done,
keyboardType: widget.textInputType,
onChanged: widget.onChangeFtn,
onEditingComplete: widget.onEditComplete,
decoration: InputDecoration(
errorText: widget.errorText,
contentPadding: const EdgeInsets.symmetric(horizontal: 15.0),
hintText: widget.hintText,
hintStyle: Theme.of(context).textTheme.caption,
@ -86,7 +60,6 @@ class _CustomTextFieldState extends State<CustomTextField> {
),
),
validator: widget.validatorFtn,
onFieldSubmitted: widget.onFieldSubmit,
),
);
}

View File

@ -3,10 +3,10 @@ import 'package:simplex_chat/constants.dart';
class MessageBubble extends StatefulWidget {
const MessageBubble({
Key key,
this.sender,
this.text,
this.isUser,
Key? key,
required this.sender,
required this.text,
required this.isUser,
}) : super(key: key);
final String sender;
final String text;

View File

@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.10.0 <3.0.0"
sdk: ">=2.12.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions