Skip to content

Instantly share code, notes, and snippets.

@OberdanBrito
Created December 30, 2022 19:41
Show Gist options
  • Save OberdanBrito/c6eae8e8b4a749a71adb6aa9dd0769c7 to your computer and use it in GitHub Desktop.
Save OberdanBrito/c6eae8e8b4a749a71adb6aa9dd0769c7 to your computer and use it in GitHub Desktop.
Página para gestão de contatos do dispositivo. Através desta é possível adicionar, remover, pesquisar e criar uma lista de convidados
// ignore_for_file: depend_on_referenced_packages, unnecessary_import
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:gestor_commons/data/data.dart';
import 'package:gestor_commons/images.dart';
import 'package:gestor_commons/theme.dart';
import 'package:intl/intl.dart';
import 'package:quicasa_contacts/data/schedule.dart';
import 'package:quicasa_contacts/types.dart';
import 'contact_view.dart';
import 'data/contacts.dart';
import 'data/groups.dart';
import 'data/groups_itens.dart';
import 'data/profile_type.dart';
import 'sync.dart';
class MultipleData {
List<ApContact> contacts;
List<Groups> groups;
MultipleData({required this.contacts, required this.groups});
}
class ContactsManagerPage extends StatefulWidget {
final Map<String, dynamic> client;
final AppTheme theme;
const ContactsManagerPage({super.key, required this.client, required this.theme});
@override
ContactsManagerState createState() => ContactsManagerState();
}
class ContactsManagerState extends State<ContactsManagerPage> {
final db = DataBaseHelper.db;
late AppWidgets global = AppWidgets(theme: widget.theme);
String _state = 'list contacts';
late MultipleData multipleData;
Future _onSelectItem(context, contact, index) async {
var schendule = await db.queryRow('schedule', 'contact', contact.id);
if (schendule.isNotEmpty) {
contact.schedule = Schedule.fromMap(schendule);
}
Navigator.of(context)
.push(MaterialPageRoute(
builder: (_) => ContactPage(
contact: contact,
client: widget.client,
theme: widget.theme,
)))
.then((val) => _checkLocalData());
}
Widget _showPhoto(photo) {
Widget contactphoto = Icon(FontAwesomeIcons.user, size: 24, color: widget.theme.grey);
if (photo != "") {
contactphoto = Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: MemoryImage(Images.dataFromBase64String(photo)),
fit: BoxFit.cover,
),
));
}
return CircleAvatar(
backgroundColor: Colors.grey[300],
child: Center(
child: contactphoto,
),
);
}
Widget _showName(String name, Color color) {
return Row(
children: <Widget>[
Expanded(
child: Text(name,
style: TextStyle(color: color),
softWrap: false,
maxLines: 1,
overflow: TextOverflow.ellipsis))
],
);
}
Widget _showType(contactType) {
ContactProfileType peopleType = Types.list.where((element) => element.id == contactType).first;
return global.iconText(peopleType.text, Icon(peopleType.icon), peopleType.color);
}
Widget _showAccess(String? date) {
String nextaccess = '';
if (date != null && date != "") {
nextaccess = DateFormat.yMd().format(DateTime.parse(date).toLocal());
}
return Text(nextaccess);
}
Widget _listContacts(List<ApContact> list) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
ApContact contact = list[index];
Color? background = Colors.white;
Color color = Colors.black54;
if (contact.blocked == 'true') {
background = Colors.red[50];
color = Colors.red;
}
return ListTile(
onTap: () => _onSelectItem(context, contact, index),
tileColor: background,
leading: _showPhoto(contact.photo),
title: _showName(contact.displayname, color),
subtitle: _showType(contact.peopletype),
trailing: _showAccess(contact.scheduleto),
);
},
childCount: list.length,
),
);
}
Widget _makeListContent() {
return Container(
color: Colors.white,
child: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
snap: false,
floating: true,
expandedHeight: multipleData.groups.isNotEmpty ? 150.0 : 0,
backgroundColor: Colors.white,
title: global.titlePage(leftText: 'Meus ', centerText: 'Contatos'),
leading: global.backButton(context),
),
_listContacts(multipleData.contacts)
],
),
);
}
Widget _awaitLoadStart() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Aguarde enquanto\nbuscamos os seus contatos',
textAlign: TextAlign.center,
),
SizedBox(
width: 100,
height: 100,
child: Stack(
alignment: Alignment.center,
children: [
Icon(FontAwesomeIcons.heart, size: 32, color: widget.theme.secundary),
SizedBox(
height: 50,
width: 50,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(widget.theme.primary),
strokeWidth: 5,
),
)
],
),
)
],
),
);
}
Widget _prepareList(Future<MultipleData>? future) {
return FutureBuilder<MultipleData>(
future: future,
builder: (BuildContext context, AsyncSnapshot<MultipleData> snapshot) {
if (snapshot.hasData) {
multipleData = snapshot.data!;
return _makeListContent();
} else {
return _awaitLoadStart();
}
},
);
}
Widget _optionAdd() {
return FloatingActionButton(
onPressed: () {
if (_state == 'get permissions') {
_prepareTables();
}
},
child: const Icon(Icons.add),
);
}
Widget _makeListEmpty() {
return Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Padding(
padding: const EdgeInsets.all(10),
child: Icon(FontAwesomeIcons.heart, size: 32, color: widget.theme.secundary),
),
const Text(
'Sua lista de contatos\nestá vazia!',
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 24),
textAlign: TextAlign.center,
),
const Padding(
padding: EdgeInsets.only(top: 20, left: 30, right: 30),
child: Text(
'Para o seu conforto, você pode sincronizar os contatos do seu celular aqui mesmo!',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: TextButton.icon(
onPressed: () {
_prepareTables();
_getDeviceContacts();
setState(() {
_state = 'list contacts';
});
},
icon: const Icon(Icons.sync),
label: const Text(
"Sincronizar meus contatos",
style: TextStyle(fontSize: 15),
))),
const Padding(
padding: EdgeInsets.only(top: 20, left: 30, right: 30),
child: Text(
'Ou aperte no botão (+) abaixo\npara adicionar um novo contato',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
),
]),
);
}
Future _checkLocalData() async {
bool exists = await db.tableExist('contacts');
if (exists == false) {
setState(() {
_state = 'get permissions';
});
}
}
Future<void> _prepareTables() async {
await db.create('contacts', ApContact.model);
await db.create('schedule', Schedule.model);
await db.create('groups', Groups.model);
await db.create('groupsitens', GroupsItens.model);
}
Future<MultipleData> _getDeviceContacts() async {
List<ApContact> contacts = [];
List<Map<String, dynamic>> devicecontacts = await DeviceContacts.fetchContacts();
await Future.forEach(devicecontacts, (row) async {
await db.insert('contacts', row);
contacts.add(ApContact.fromMap(row));
});
return MultipleData(contacts: contacts, groups: []);
}
Future<MultipleData> _getLocalContacts() async {
List<ApContact> contacts = [];
List<Groups> groups = [];
List<Map<String, dynamic>> contactrows = await db.query(
'SELECT id, displayname, peopletype, registrationdate, scheduleto, photo FROM contacts ORDER BY displayname;');
Future.forEach(contactrows, (row) => {contacts.add(ApContact.fromMap(row))});
List<Map<String, dynamic>> grouprows = await db.queryAllRows('groups');
Future.forEach(grouprows, (rows) => {groups.add(Groups.fromMap(rows))});
return MultipleData(contacts: contacts, groups: groups);
}
@override
void initState() {
super.initState();
_checkLocalData();
}
@override
Widget build(BuildContext context) {
Widget showitem;
Widget? floatingActionButton;
switch (_state) {
case 'get permissions':
showitem = _makeListEmpty();
floatingActionButton = _optionAdd();
break;
case 'list contacts':
default:
showitem = _prepareList(_getLocalContacts());
floatingActionButton = _optionAdd();
break;
}
return Scaffold(
floatingActionButton: floatingActionButton,
body: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: showitem,
));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment