Merge branch 'feat/adding-modified-eventsource-library' into WIP#feat#heartbeat-manager
commit
00134c05b8
|
@ -0,0 +1,3 @@
|
|||
[submodule "utility_packages/dart-eventsource"]
|
||||
path = utility_packages/dart-eventsource
|
||||
url = git@makerforce.io:beep/dart-eventsource.git
|
|
@ -17,7 +17,7 @@ class Routes {
|
|||
title: "Beep",
|
||||
theme: theme,
|
||||
routes: routes,
|
||||
home: Welcome(),
|
||||
home: Home(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import "package:rxdart/rxdart.dart";
|
||||
|
||||
class BottomBusBloc {
|
||||
final _bottomBarBus = PublishSubject<Map<String, String>>();
|
||||
Map<String, String> _lastMessage = {"state": "no_connection"};
|
||||
|
||||
BottomBusBloc() {
|
||||
_bottomBarBus.listen((data) => print(data));
|
||||
}
|
||||
|
||||
Observable<Map<String, String>> get bus => _bottomBarBus.stream;
|
||||
Map<String, String> get lastMessage => _lastMessage;
|
||||
|
||||
publish(Map<String, String> message) async {
|
||||
print(message);
|
||||
_lastMessage = message;
|
||||
_bottomBarBus.sink.add(message);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
_bottomBarBus.close();
|
||||
}
|
||||
}
|
||||
|
||||
// global instance for access throughout the app
|
||||
final bottomBusBloc = BottomBusBloc();
|
|
@ -1,17 +1,17 @@
|
|||
import "package:rxdart/rxdart.dart";
|
||||
|
||||
import "../resources/repository.dart";
|
||||
import "../resources/contact_api_provider.dart";
|
||||
import "../models/user_model.dart";
|
||||
|
||||
// TODO: SHOULD BE A INHERITED SCOPED BLOC Widget
|
||||
class ContactBloc {
|
||||
final _repository = Repository();
|
||||
final _provider = ContactApiProvider();
|
||||
final _contactsFetcher = PublishSubject<List<User>>();
|
||||
|
||||
Observable<List<User>> get contacts => _contactsFetcher.stream;
|
||||
|
||||
fetchContacts() async {
|
||||
List<User> contactList = await _repository.fetchContacts();
|
||||
List<User> contactList = await _provider.fetchContacts();
|
||||
_contactsFetcher.sink.add(contactList);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import "package:rxdart/rxdart.dart";
|
||||
|
||||
import "../resources/repository.dart";
|
||||
import "../resources/conversation_api_provider.dart";
|
||||
import "../models/user_model.dart";
|
||||
import "../models/conversation_model.dart";
|
||||
|
||||
class ConversationsBloc {
|
||||
final _repository = Repository();
|
||||
final _provider = ConversationApiProvider();
|
||||
final _conversationsFetcher = PublishSubject<List<Conversation>>();
|
||||
|
||||
Observable<List<Conversation>> get conversations =>
|
||||
_conversationsFetcher.stream;
|
||||
|
||||
fetchConversations() async {
|
||||
List<Conversation> conversationList =
|
||||
await _repository.fetchConversations();
|
||||
List<Conversation> conversationList = await _provider.fetchConversations();
|
||||
_conversationsFetcher.sink.add(conversationList);
|
||||
}
|
||||
|
||||
|
@ -24,7 +23,7 @@ class ConversationsBloc {
|
|||
|
||||
class ConversationMembersBloc {
|
||||
final String conversationId;
|
||||
final _repository = Repository();
|
||||
final _provider = ConversationApiProvider();
|
||||
final _membersFetcher = PublishSubject<List<User>>();
|
||||
|
||||
ConversationMembersBloc(this.conversationId);
|
||||
|
@ -33,7 +32,7 @@ class ConversationMembersBloc {
|
|||
|
||||
fetchMembers() async {
|
||||
List<User> memberList =
|
||||
await _repository.fetchConversationMembers(conversationId);
|
||||
await _provider.fetchConversationMembers(conversationId);
|
||||
_membersFetcher.sink.add(memberList);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
import "package:rxdart/rxdart.dart";
|
||||
import "package:flutter_webrtc/webrtc.dart";
|
||||
|
||||
import "../resources/conversation_api_provider.dart";
|
||||
import "../models/user_model.dart";
|
||||
import "../services/peer_manager.dart";
|
||||
import "../../settings.dart";
|
||||
|
||||
class VoiceConnection {
|
||||
final PeerManager _peerManager = PeerManager(globalUserId, "2");
|
||||
final _conversationApiProvider = ConversationApiProvider();
|
||||
final _bottomBarBus = PublishSubject<Map<String, dynamic>>();
|
||||
|
||||
VoiceConnection() {
|
||||
_bottomBarBus.listen((data) => print(data));
|
||||
_peerManager.initialize();
|
||||
}
|
||||
|
||||
Observable<Map<String, dynamic>> get bus => _bottomBarBus.stream;
|
||||
|
||||
publish(Map<String, dynamic> message) async {
|
||||
_bottomBarBus.sink.add(message);
|
||||
}
|
||||
|
||||
join(String conversationId) async {
|
||||
List<User> users =
|
||||
await _conversationApiProvider.fetchConversationMembers(conversationId);
|
||||
|
||||
// Add the users to the streams
|
||||
users.forEach((user) {
|
||||
_peerManager.addPeer(user.id);
|
||||
});
|
||||
|
||||
List<MediaStream> connectedStreams = _peerManager.streams;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
_bottomBarBus.close();
|
||||
}
|
||||
}
|
||||
|
||||
// global instance for access throughout the app
|
||||
final voiceConnection = VoiceConnection();
|
|
@ -1,20 +0,0 @@
|
|||
import "dart:async";
|
||||
|
||||
import "contact_api_provider.dart";
|
||||
import "conversation_api_provider.dart";
|
||||
|
||||
import "../models/user_model.dart";
|
||||
import "../models/conversation_model.dart";
|
||||
|
||||
class Repository {
|
||||
final contactApiProvider = ContactApiProvider();
|
||||
final conversationApiProvider = ConversationApiProvider();
|
||||
|
||||
Future<List<User>> fetchContacts() => contactApiProvider.fetchContacts();
|
||||
|
||||
Future<List<Conversation>> fetchConversations() =>
|
||||
conversationApiProvider.fetchConversations();
|
||||
|
||||
Future<List<User>> fetchConversationMembers(String id) =>
|
||||
conversationApiProvider.fetchConversationMembers(id);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
import "package:flutter/material.dart";
|
||||
|
||||
import "../../blocs/bottom_bus_bloc.dart";
|
||||
import "widgets/conversation_inactive_view.dart";
|
||||
import "widgets/conversation_active_view.dart";
|
||||
|
||||
class BottomBar extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _BottomBarState();
|
||||
}
|
||||
}
|
||||
|
||||
class _BottomBarState extends State<BottomBar> {
|
||||
final bloc = bottomBusBloc;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// bloc.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget getWidgetForState(Map<String, String> message) {
|
||||
if (message["state"] == "no_connection") {
|
||||
return ConversationInactiveView();
|
||||
} else if (message["state"] == "connection") {
|
||||
return ConversationActiveView(conversationName: message["title"]);
|
||||
} else {
|
||||
return ConversationInactiveView();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double bottomPadding = MediaQuery.of(context).padding.bottom;
|
||||
|
||||
return Material(
|
||||
type: MaterialType.canvas,
|
||||
elevation: 10.0,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(40.0), topRight: Radius.circular(40.0)),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 20.0,
|
||||
left: 20.0,
|
||||
right: 20.0,
|
||||
bottom: 30.0 + bottomPadding),
|
||||
child: StreamBuilder(
|
||||
stream: bloc.bus,
|
||||
builder:
|
||||
(context, AsyncSnapshot<Map<String, String>> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return getWidgetForState(snapshot.data);
|
||||
} else {
|
||||
final message = bloc.lastMessage;
|
||||
return getWidgetForState(message);
|
||||
}
|
||||
})));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
import "package:flutter/material.dart";
|
||||
|
||||
import "../../widgets/user_avatar.dart";
|
||||
import "../../../models/user_model.dart";
|
||||
import "../../../blocs/bottom_bus_bloc.dart";
|
||||
|
||||
class ConversationActiveView extends StatelessWidget {
|
||||
final String conversationName;
|
||||
final bus = bottomBusBloc;
|
||||
|
||||
ConversationActiveView({@required this.conversationName});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 22.0,
|
||||
height: 22.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).indicatorColor,
|
||||
shape: BoxShape.circle)),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 10.0),
|
||||
child: Text(conversationName,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.display1
|
||||
.copyWith(color: Theme.of(context).accentColor))),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
color: Theme.of(context).accentColor,
|
||||
icon: Icon(Icons.info),
|
||||
onPressed: () {
|
||||
print("Pressed info");
|
||||
}),
|
||||
IconButton(
|
||||
color: Theme.of(context).accentColor,
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
// Call method to close connection
|
||||
bus.publish({"state": "no_connection"});
|
||||
print("Pressed close");
|
||||
}),
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
UserAvatar(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
user: User("1", "Isaac", "Tay", "+65 91043593")),
|
||||
UserAvatar(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
user: User("1", "Isaac", "Tay", "+65 91043593")),
|
||||
UserAvatar(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
user: User("1", "Rui", "Juidfsdf", "+65 91043593"))
|
||||
]),
|
||||
]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import "package:flutter/material.dart";
|
||||
|
||||
import "../../widgets/user_avatar.dart";
|
||||
import "../../../models/user_model.dart";
|
||||
|
||||
class ConversationInactiveView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
UserAvatar(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
user: User("1", "Isaac", "Tay", "+65 91043593")),
|
||||
UserAvatar(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
user: User("1", "Isaac", "Tay", "+65 91043593")),
|
||||
UserAvatar(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
user: User("1", "Isaac", "Tay", "+65 91043593"))
|
||||
]));
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import "package:flutter/material.dart";
|
|||
import "./widgets/top_bar.dart";
|
||||
import "./widgets/conversation_list.dart";
|
||||
import "./widgets/contact_list.dart";
|
||||
import "./widgets/bottom_bar.dart";
|
||||
import "../bottom_bar/bottom_bar.dart";
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
@override
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
import "package:flutter/material.dart";
|
||||
import 'package:flutter_webrtc/webrtc.dart';
|
||||
|
||||
import "../../../blocs/voice_connection_bloc.dart";
|
||||
|
||||
class BottomBar extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _BottomBarState();
|
||||
}
|
||||
}
|
||||
|
||||
class _BottomBarState extends State<BottomBar> {
|
||||
final double barHeight = 80.0;
|
||||
final _renderer = new RTCVideoRenderer();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
initRenderers();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
initRenderers() async {
|
||||
await _renderer.initialize();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
type: MaterialType.canvas,
|
||||
elevation: 10.0,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(40.0), topRight: Radius.circular(40.0)),
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 20.0),
|
||||
width: 22.0,
|
||||
height: 22.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).indicatorColor,
|
||||
shape: BoxShape.circle)),
|
||||
Text("Family Chat",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.display1
|
||||
.copyWith(color: Theme.of(context).accentColor)),
|
||||
Spacer(),
|
||||
Container(
|
||||
child: RTCVideoView(_renderer),
|
||||
width: 0,
|
||||
height: 0,
|
||||
),
|
||||
IconButton(
|
||||
color: Theme.of(context).accentColor,
|
||||
icon: Icon(Icons.info),
|
||||
onPressed: () {
|
||||
print("Pressed");
|
||||
}),
|
||||
IconButton(
|
||||
color: Theme.of(context).accentColor,
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
print("Pressed close");
|
||||
voiceConnection
|
||||
.join("c-6f2ba396fb53961ff8a6ba9c5d286a25");
|
||||
}),
|
||||
])));
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ import "package:flutter/material.dart";
|
|||
import "../../../models/user_model.dart";
|
||||
import "../../../models/conversation_model.dart";
|
||||
import "../../../blocs/conversation_bloc.dart";
|
||||
import "../../../blocs/bottom_bus_bloc.dart";
|
||||
|
||||
import "../../widgets/user_avatar.dart";
|
||||
|
||||
|
@ -19,6 +20,7 @@ class ConversationItem extends StatefulWidget {
|
|||
class _ConversationItemState extends State<ConversationItem> {
|
||||
final bloc;
|
||||
final Conversation conversation;
|
||||
final bus = bottomBusBloc;
|
||||
|
||||
_ConversationItemState({@required this.conversation})
|
||||
: bloc = ConversationMembersBloc(conversation.id);
|
||||
|
@ -39,7 +41,8 @@ class _ConversationItemState extends State<ConversationItem> {
|
|||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
isThreeLine: true,
|
||||
onTap: () => {},
|
||||
onTap: () =>
|
||||
bus.publish({"state": "connection", "title": conversation.title}),
|
||||
contentPadding:
|
||||
EdgeInsets.only(top: 0.0, left: 20.0, right: 20.0, bottom: 0.0),
|
||||
title: Text(conversation.title, style: Theme.of(context).textTheme.title),
|
||||
|
|
|
@ -11,12 +11,12 @@ dependencies:
|
|||
json_annotation: ^2.0.0
|
||||
rxdart: ^0.20.0
|
||||
http: ^0.12.0+1
|
||||
eventsource: ^0.2.1
|
||||
flutter_webrtc: ^0.1.0
|
||||
pin_code_text_field: ^1.1.3
|
||||
flutter_svg: ^0.10.3
|
||||
shared_preferences: ^0.5.1
|
||||
sqflite: ^1.1.0
|
||||
eventsource:
|
||||
path: ./utility_packages/dart-eventsource
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 5ab96112ea37e1120e0ee815c3dfa38843b1a34d
|
Loading…
Reference in New Issue