Skip to content

Commit

Permalink
added WhatsApp icon beside WhatsApp numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
richtwin567 committed Jul 26, 2020
1 parent 9a7e989 commit 5c39550
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 65 deletions.
Binary file added assets/images/contact/WhatsApp_flat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ class MyApp extends StatelessWidget {
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
//primaryColor: Color.fromRGBO(23, 37, 90, 1.0),
primaryColor: Colors.blue[900],
accentColor: Color.fromRGBO(243, 191, 18, 1.0),
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.white, opacity: 1.0),
fontFamily: 'Montserrat',
appBarTheme: AppBarTheme(textTheme: TextTheme(headline6: TextStyle(fontSize: 20.0, fontFamily: 'Montserrat', fontWeight: FontWeight.bold))),



// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'dart:convert';
class GetContacts {
static Future<String> getContactsDjangoApi(dynamic query) async {
String queryString = query.toString();
String contactUrl = 'http:https://192.168.100.76:8000/contact/?search=$queryString';
String contactUrl = 'http:https://192.168.100.76:8000/contact/?$queryString';

http.Response response = await http.get(Uri.encodeFull(contactUrl));

Expand Down
36 changes: 25 additions & 11 deletions lib/screens/contact_screen/local_widgets/contact_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,54 @@ class ContactTile extends StatelessWidget {
/// The subtitle for this ContactTile.
final String subtitle;

/// The route to the page that the Navigator should push when this tile is tapped.
/// The route to the page that the Navigator should push when this tile is
/// tapped instead of calling a [tapFunc].
/// Must be a named route.
final String namedRoute;

/// The data to be passed to the next page when this tile is tapped
/// The data to be passed to the next page when this tile is tapped.
final dynamic arguments;

/// The function to call when this tile is tapped instead of navigating to a
/// [namedRoute].
final GestureTapCallback tapFunc;

/// Creates a contact tile.
///
/// A contact tile has a [title] and [subtitle].
/// When tapped, this tile will navigate to the page defined by the [namedRoute]
/// If a [namedRoute] is provided, when tapped, this tile will navigate to
/// the page defined by the [namedRoute]
/// and pass its [arguments], if given, to that page.
/// The [arguments] would be the information for this contact.
/// If a [tapFunc] is provided, the tile will execute that function when tapped.
/// **Either one [tapFunc] or one [namedRoute] must be passed, not both.**
ContactTile(
{Key key,
@required this.title,
@required this.subtitle,
@required this.namedRoute,
this.namedRoute,
this.tapFunc,
this.arguments})
: super(key: key);
: assert((namedRoute == null && tapFunc != null) ||
(namedRoute != null && tapFunc == null)),
super(key: key);

@override
Widget build(BuildContext context) {
return ContactCard(
child: ListTile(
contentPadding: EdgeInsets.fromLTRB(16.0, 10.0, 16.0, 10.0),
onTap: () {
arguments != null
? Navigator.pushNamed(context, namedRoute, arguments: arguments)
: Navigator.pushNamed(context, namedRoute);
},
onTap: namedRoute != null
? () {
arguments != null
? Navigator.pushNamed(context, namedRoute,
arguments: arguments)
: Navigator.pushNamed(context, namedRoute);
}
: tapFunc,
title: Text(title),
subtitle: Text(subtitle),
trailing: Icon(Icons.chevron_right),
));
}
} // ContactTile definition
} // ContactTile definition
60 changes: 38 additions & 22 deletions lib/screens/contact_screen/pages/contact_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,45 @@ class ContactDetailPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
final dynamic contactDetails = ModalRoute.of(context).settings.arguments;
final ContactCard contactMethods = _contactDetailList(contactDetails);
final ContactCard contactInfo = _aboutContactList(contactDetails);
final mq = MediaQuery.of(context);
print(mq.size.height / 2);
print(mq.size.width / 2);
print(mq.size.aspectRatio);
print(mq.devicePixelRatio);
print(mq);
final dynamic contactDetails = ModalRoute.of(context).settings.arguments;
final ContactCard contactMethods = _contactDetailList(contactDetails, mq, context);
final ContactCard contactInfo = _aboutContactList(contactDetails, mq);

return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
//TODO: investigate: are these actions feasible?
actions: <Widget>[
IconButton(icon: Icon(Icons.share), onPressed: null),
IconButton(icon: Icon(Icons.save), onPressed: null)
IconButton(
icon: Icon(Icons.share,
color: Theme.of(context).iconTheme.color),
onPressed: null),
IconButton(
icon: Icon(Icons.save,
color: Theme.of(context).iconTheme.color),
onPressed: null)
],
floating: false,
pinned: true,
snap: false,
expandedHeight: mq.size.height/3.5 ,
expandedHeight: mq.size.height / 2.5,
flexibleSpace: FlexibleSpaceBar(
background: CustomPaint(
painter: ContactDetailSvg(
offsetX: mq.size.width / mq.devicePixelRatio,
offsetY: (mq.size.height/mq.devicePixelRatio)/3.5,
scale: (mq.devicePixelRatio/ mq.size.aspectRatio),
offsetX: mq.size.width /
(mq.devicePixelRatio / mq.size.aspectRatio) *
1.5,
offsetY: (mq.size.height /
(mq.devicePixelRatio / mq.size.aspectRatio) *
1.5) /
2.5,
scale:
(mq.devicePixelRatio / mq.size.aspectRatio) * 1.5,
color: Colors.blue[800])),
title: Padding(
padding: EdgeInsets.only(right: 70.0),
padding: EdgeInsets.only(right: mq.size.width / 4),
child: Text(
contactDetails['name'],
maxLines: 1,
Expand All @@ -62,15 +69,23 @@ class ContactDetailPage extends StatelessWidget {
));
}

ContactCard _contactDetailList(final dynamic data) {
ContactCard _contactDetailList(final dynamic data, final MediaQueryData mq, BuildContext context) {
List<dynamic> phoneNums =
List<dynamic>.generate(data['phone_contact_set'].length, (i) {
Icon icon =
i == 0 ? Icon(Icons.phone) : Icon(Icons.phone, color: Colors.white);
return ListTile(
var icon;
if (data['phone_contact_set'][i]['platforms'] == 'WHATSAPP') {
icon = Image.asset('assets/images/contact/WhatsApp_flat.png',width: IconTheme.of(context).size,);
return ListTile(
leading: icon,
onTap: () => openUrl('tel:' + data['phone_contact_set'][i]['phone']),
title: Text(data['phone_contact_set'][i]['phone']));
} else {
icon = Icon(Icons.phone);
return ListTile(
leading: icon,
onTap: () => openUrl('tel:' + data['phone_contact_set'][i]['phone']),
title: Text(data['phone_contact_set'][i]['phone']));
}
});

List<dynamic> iconifiedList = [
Expand Down Expand Up @@ -100,13 +115,13 @@ class ContactDetailPage extends StatelessWidget {
}

return ContactCard(
margin: EdgeInsets.symmetric(horizontal: 10.0),
margin: EdgeInsets.symmetric(horizontal: mq.size.width / 18),
child: Column(
children: <Widget>[...iconifiedList],
));
}

ContactCard _aboutContactList(final dynamic data) {
ContactCard _aboutContactList(final dynamic data, final MediaQueryData mq) {
List<dynamic> iconifiedList;
if (data['website'] != '' || data['description'] != '') {
iconifiedList = [
Expand All @@ -133,7 +148,8 @@ class ContactDetailPage extends StatelessWidget {
iconifiedList.removeWhere((element) => element == null);

return ContactCard(
margin: EdgeInsets.fromLTRB(10.0, 25.0, 10.0, 25.0),
margin: EdgeInsets.fromLTRB(mq.size.width / 18, mq.size.height / 22,
mq.size.width / 18, mq.size.height / 22),
child: Column(
children: <Widget>[...iconifiedList],
));
Expand Down
119 changes: 88 additions & 31 deletions lib/screens/contact_screen/pages/contacts_page_general.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:fst_app_flutter/screens/contact_screen/django_requests/handle_contacts.dart';
import 'package:fst_app_flutter/screens/contact_screen/local_widgets/contact_detail_image.dart';
import 'package:fst_app_flutter/screens/contact_screen/pages/contact_detail_page.dart';
import 'package:fst_app_flutter/screens/contact_screen/local_widgets/contact_widgets.dart';

Expand All @@ -14,31 +13,88 @@ class ContactPage extends StatefulWidget {
} // ContactPage definition

class _ContactPageState extends State<ContactPage> {
var _currentValue = '';
var _currentValue = 'search=';
var _extraParam = '';

static final List<String> _categories = [
'Emergency',
'Chemistry Department',
'Computing Department',
'Geography and Geology Department',
'Life Sciences Department',
'Mathematics Department',
'Physics Department',
'Other Contacts'
Chip _filterChips;
final List<dynamic> _categories = [
{'title': 'Emergency', 'queryParam': 'type', 'value': 'EMERGENCY'},
{
'title': 'Chemistry Department',
'queryParam': 'department',
'value': 'CHEM'
},
{
'title': 'Computing Department',
'queryParam': 'department',
'value': 'COMP'
},
{
'title': 'Geography and Geology Department',
'queryParam': 'department',
'value': 'GEO'
},
{
'title': 'Life Sciences Department',
'queryParam': 'department',
'value': 'LIFE'
},
{
'title': 'Mathematics Department',
'queryParam': 'department',
'value': 'MATH'
},
{
'title': 'Physics Department',
'queryParam': 'department',
'value': 'PHYS'
},
{
'title': 'Faculty Wide Contacts',
'queryParam': 'department',
'value': 'OTHER'
},
{'title': 'Other Contacts', 'queryParam': 'type', 'value': 'OTHER'},
];

final ListView _defaultView = ListView(
children: List<Widget>.generate(_categories.length, (index) {
return ContactTile(
title: _categories[index],
subtitle: 'See related contacts',
namedRoute: null);
}));

List<dynamic> _contacts = [];

@override
void initState() {
GetContacts.searchDjangoContacts('$_currentValue$_extraParam')
.then((data) => _contacts = data.toSet().toList());
super.initState();
}

@override
Widget build(BuildContext context) {
final ListView _defaultView = ListView(
children: List<Widget>.generate(_categories.length, (index) {
return ContactTile(
title: _categories[index]['title'],
subtitle: 'See related contacts',
namedRoute: null,
tapFunc: () {
setState(() {
var queryParam = _categories[index]['queryParam'];
var value = _categories[index]['value'];
_extraParam = '&$queryParam=$value';
_filterChips = Chip(
deleteIcon:
Icon(Icons.cancel, color: Theme.of(context).primaryColor),
label: Text(_categories[index]['title']),
onDeleted: () {
setState(() {
_extraParam = '';
_filterChips = null;
});
},
);
});
},
);
}));

return Scaffold(
appBar: AppBar(
title: Text('Contacts'),
Expand All @@ -53,11 +109,9 @@ class _ContactPageState extends State<ContactPage> {
children: <Widget>[
TextField(
onChanged: (value) {
_currentValue = value;
_currentValue = 'search=$value';
_contacts.clear();
setState(() {

});
setState(() {});
},
decoration: InputDecoration(
suffixIcon: Icon(Icons.search),
Expand All @@ -71,13 +125,19 @@ class _ContactPageState extends State<ContactPage> {
borderSide: BorderSide.none,
)),
),
Flexible(
child: ListTile(
title: _filterChips,
),
flex: 2),
Spacer(
flex: 2,
flex: 1,
),
Expanded(
flex: 30,
child: FutureBuilder(
future: GetContacts.searchDjangoContacts(_currentValue),
future: GetContacts.searchDjangoContacts(
'$_currentValue$_extraParam'),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
Expand All @@ -91,11 +151,10 @@ class _ContactPageState extends State<ContactPage> {
ConnectionState.done) {
if (snapshot.hasData) {
_contacts = snapshot.data.toSet().toList();
return _currentValue == ''
return _currentValue == 'search=' && _extraParam ==''
? _defaultView
: buildContactListView(_contacts);
} else if (!snapshot.hasData &&
!snapshot.hasError) {
} else if (!snapshot.hasData) {
return Center(child: Text('No matches found'));
} else {
return Center(child: Text('An error occured'));
Expand All @@ -117,9 +176,7 @@ Widget buildContactListView(List<dynamic> contacts) {
semanticChildCount: contacts.length,
itemBuilder: (BuildContext context, int index) {
return ContactTile(
title: contacts[index]['id'].toString() +
' ' +
contacts[index]['name'],
title: contacts[index]['name'],
subtitle: contacts[index]['description'],
namedRoute: ContactDetailPage.routeName,
arguments: contacts[index]);
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ flutter:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg

assets:
- assets/images/contact/WhatsApp_flat.png

# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
Expand Down

0 comments on commit 5c39550

Please sign in to comment.