4
2
Fork 0

adding BLoC architecture - closes #4

pull/31/head
Sudharshan S. 2019-02-15 15:54:19 +08:00
parent b196cf6aa8
commit 6ad7c60e32
Signed by: sudharshan
GPG Key ID: C861C97AAF3D9559
7 changed files with 75 additions and 11 deletions

View File

@ -0,0 +1,21 @@
import "package:rxdart/rxdart.dart";
import "../resources/repository.dart";
import "../models/user_model.dart";
class ContactBloc {
final _repository = Repository();
final _contactsFetcher = PublishSubject<List<User>>();
Observable<List<User>> get allContacts => _contactsFetcher.stream;
fetchAllContacts() async {
List<User> contactList = await _repository.fetchContacts();
_contactsFetcher.sink.add(contactList);
}
dispose() {
_contactsFetcher.close();
}
}
final bloc = ContactBloc();

View File

@ -1,10 +1,10 @@
import "package:json_annotation/json_annotation.dart";
part 'user.g.dart';
part 'user_model.g.dart';
@JsonSerializable()
class User {
final int id;
final String id;
@JsonKey(name: 'first_name')
final String firstName;

View File

@ -0,0 +1,17 @@
import "dart:async";
import "package:http/http.dart" show Client;
import "dart:convert";
import "../models/user_model.dart";
class ContactApiProvider {
Client client = Client();
Future<List<User>> fetchContactList() async {
final response = await client.get(
"http://localhost:10200/user/u-3d19fb283ddb14fb5c15191438b5b69a/contact");
return jsonDecode(response.body)
.map<User>((user) => User.fromJson(user))
.toList();
}
}

View File

@ -0,0 +1,9 @@
import "dart:async";
import "contact_api_provider.dart";
import "../models/user_model.dart";
class Repository {
final contactApiProvider = ContactApiProvider();
Future<List<User>> fetchContacts() => contactApiProvider.fetchContactList();
}

View File

@ -42,7 +42,7 @@ class _HomeState extends State<Home> {
Expanded(
child: PageView(controller: controller, children: <Widget>[
ConversationList(items: List<String>.generate(4, (i) => "Item $i")),
ContactList(items: List<String>.generate(5, (i) => "Item $i")),
ContactList(),
ConversationList(items: List<String>.generate(6, (i) => "Item $i"))
]))
]),

View File

@ -1,8 +1,13 @@
import "package:flutter/material.dart";
import "../../models/user_model.dart";
import "user_avatar.dart";
class ContactItem extends StatelessWidget {
final User user;
ContactItem({@required this.user});
@override
Widget build(BuildContext context) {
return ListTile(
@ -17,11 +22,11 @@ class ContactItem extends StatelessWidget {
color: Theme.of(context).primaryColorDark)),
UserAvatar(
active: true,
name: "SU",
name: user.firstName[0] + user.lastName[0],
radius: 22.0,
padding: EdgeInsets.only(left: 20.0))
]),
title: Text("Ambrose Chua",
title: Text(user.firstName + " " + user.lastName,
style: Theme.of(context).textTheme.display2,
overflow: TextOverflow.ellipsis),
subtitle: Text("Last seen just now",

View File

@ -1,19 +1,31 @@
import "package:flutter/material.dart";
import '../../models/user_model.dart';
import '../../blocs/contact_bloc.dart';
import "contact_item.dart";
class ContactList extends StatelessWidget {
final List<String> items;
ContactList({Key key, @required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
bloc.fetchAllContacts();
return StreamBuilder(
stream: bloc.allContacts,
builder: (context, AsyncSnapshot<List<User>> snapshot) {
if (snapshot.hasData) {
return buildList(snapshot);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(child: CircularProgressIndicator());
});
}
Widget buildList(AsyncSnapshot<List<User>> snapshot) {
return ListView.builder(
padding: EdgeInsets.only(top: 0.0),
itemCount: items.length,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ContactItem();
return ContactItem(user: snapshot.data[index]);
},
);
}