other minor fixes to bottom bar
parent
a6b1b6eaa6
commit
bc5731f70c
|
@ -1,36 +0,0 @@
|
|||
import "package:rxdart/rxdart.dart";
|
||||
import "../services/conversation_manager.dart";
|
||||
|
||||
class BottomBusBloc {
|
||||
final _bottomBarBus = PublishSubject<Map<String, String>>();
|
||||
final conversationManager = ConversationManager();
|
||||
|
||||
BottomBusBloc() {
|
||||
_bottomBarBus.listen((data) => print(data));
|
||||
}
|
||||
|
||||
Observable<Map<String, String>> get bus => _bottomBarBus.stream;
|
||||
|
||||
publish(Map<String, String> message) async {
|
||||
_bottomBarBus.sink.add(message);
|
||||
}
|
||||
|
||||
Future<Map<String, String>> getCurrentState() async {
|
||||
final conversationId = await conversationManager.get();
|
||||
Map<String, String> response = {};
|
||||
if (conversationId == "") {
|
||||
response = {"state": "no_connection"};
|
||||
} else {
|
||||
response = {"state": "connection", "conversationId": conversationId};
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
_bottomBarBus.close();
|
||||
}
|
||||
}
|
||||
|
||||
// global instance for access throughout the app
|
||||
final bottomBusBloc = BottomBusBloc();
|
|
@ -1,7 +1,6 @@
|
|||
import "dart:async";
|
||||
import "dart:convert";
|
||||
import "dart:core";
|
||||
import "dart:ui";
|
||||
|
||||
import 'package:eventsource/eventsource.dart';
|
||||
import "package:rxdart/rxdart.dart";
|
||||
|
@ -57,8 +56,8 @@ class HeartbeatReceiverBloc {
|
|||
}
|
||||
}
|
||||
});
|
||||
}).catchError((e) => print(
|
||||
e)); // Add actual error handling logic for stopped connections
|
||||
}).catchError((e) =>
|
||||
{}); // Add actual error handling logic for stopped connections
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import "package:rxdart/rxdart.dart";
|
||||
|
||||
class MessageBloc {
|
||||
final _messageBus = PublishSubject<Map<String, String>>();
|
||||
|
||||
MessageBloc() {
|
||||
_messageBus.listen((data) => print("MESSAGE: $data"));
|
||||
}
|
||||
|
||||
Observable<Map<String, String>> get bus => _messageBus.stream;
|
||||
|
||||
publish(Map<String, String> message) async {
|
||||
_messageBus.sink.add(message);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
_messageBus.close();
|
||||
}
|
||||
}
|
||||
|
||||
// global instance for access throughout the app
|
||||
final messageBloc = MessageBloc();
|
|
@ -11,7 +11,6 @@ class HeartbeatApiProvider {
|
|||
|
||||
Future<void> ping({String status = ""}) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
print("GOT JWT: $jwt");
|
||||
await http.post("$baseUrlHeartbeat/ping",
|
||||
headers: {HttpHeaders.authorizationHeader: "Bearer $jwt"},
|
||||
body: jsonEncode({"status": status}));
|
||||
|
|
|
@ -1,72 +1,28 @@
|
|||
import "package:flutter/material.dart";
|
||||
|
||||
import "../../blocs/bottom_bus_bloc.dart";
|
||||
import "../../services/heartbeat_manager.dart";
|
||||
import "../../services/conversation_manager.dart";
|
||||
import "widgets/conversation_inactive_view.dart";
|
||||
import "widgets/conversation_active_view.dart";
|
||||
|
||||
class BottomBar extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _BottomBarState();
|
||||
}
|
||||
}
|
||||
class BottomBar extends StatelessWidget {
|
||||
final String conversationId;
|
||||
|
||||
class _BottomBarState extends State<BottomBar> {
|
||||
final bloc = bottomBusBloc;
|
||||
final conversationManager = ConversationManager();
|
||||
Map<String, String> initialState;
|
||||
final heartbeatSendManager = HeartbeatSendManager();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
bloc.getCurrentState().then((state) {
|
||||
setState(() {
|
||||
initialState = state;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Widget getWidgetForState(Map<String, String> message) {
|
||||
if (message["state"] == "no_connection") {
|
||||
return ConversationInactiveView();
|
||||
} else if (message["state"] == "connection") {
|
||||
return ConversationActiveView(conversationId: message["conversationId"]);
|
||||
} else {
|
||||
return ConversationInactiveView();
|
||||
}
|
||||
}
|
||||
BottomBar({this.conversationId});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double bottomPadding = MediaQuery.of(context).padding.bottom;
|
||||
|
||||
if (initialState == null) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
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 {
|
||||
return getWidgetForState(initialState);
|
||||
}
|
||||
})));
|
||||
padding: EdgeInsets.only(
|
||||
top: 20.0, left: 20.0, right: 20.0, bottom: 30.0 + bottomPadding),
|
||||
child: (conversationId == "")
|
||||
? ConversationInactiveView()
|
||||
: ConversationActiveView(conversationId: conversationId),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ import "../../widgets/user_avatar.dart";
|
|||
import "../../../resources/conversation_api_provider.dart";
|
||||
import "../../../models/user_model.dart";
|
||||
import "../../../models/conversation_model.dart";
|
||||
import "../../../blocs/bottom_bus_bloc.dart";
|
||||
import "../../../services/conversation_manager.dart";
|
||||
import "../../../blocs/message_bloc.dart";
|
||||
|
||||
class ConversationActiveView extends StatefulWidget {
|
||||
final String conversationId;
|
||||
|
@ -19,14 +18,19 @@ class ConversationActiveView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _ConversationActiveViewState extends State<ConversationActiveView> {
|
||||
final bus = bottomBusBloc;
|
||||
final bus = messageBloc;
|
||||
final conversationApiProvider = ConversationApiProvider();
|
||||
final conversationManager = ConversationManager();
|
||||
Conversation _conversation;
|
||||
List<Widget> _users;
|
||||
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
_getConversation();
|
||||
_getConversationMembers();
|
||||
}
|
||||
|
||||
_getConversation() {
|
||||
conversationApiProvider
|
||||
.fetchConversation(widget.conversationId)
|
||||
.then((conversation) {
|
||||
|
@ -36,10 +40,23 @@ class _ConversationActiveViewState extends State<ConversationActiveView> {
|
|||
});
|
||||
}
|
||||
|
||||
_getConversationMembers() {
|
||||
conversationApiProvider
|
||||
.fetchConversationMembers(widget.conversationId)
|
||||
.then((users) {
|
||||
setState(() {
|
||||
_users = users
|
||||
.map((user) =>
|
||||
UserAvatar(padding: EdgeInsets.only(right: 5.0), user: user))
|
||||
.toList();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_conversation == null) {
|
||||
return Container();
|
||||
if ((_conversation == null) || (_users == null)) {
|
||||
return SizedBox(height: 20, width: 20);
|
||||
}
|
||||
|
||||
return Container(
|
||||
|
@ -73,25 +90,14 @@ class _ConversationActiveViewState extends State<ConversationActiveView> {
|
|||
icon: Icon(Icons.close),
|
||||
onPressed: () async {
|
||||
// Call method to close connection
|
||||
await conversationManager.exit();
|
||||
await bus.publish({"state": "no_connection"});
|
||||
await bus.publish({"state": "disconnect"});
|
||||
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"))
|
||||
]),
|
||||
children: _users),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,22 @@ import "./widgets/top_bar.dart";
|
|||
import "./widgets/conversation_list.dart";
|
||||
import "./widgets/contact_list.dart";
|
||||
import "../bottom_bar/bottom_bar.dart";
|
||||
import "../../services/heartbeat_manager.dart";
|
||||
import "../../services/conversation_manager.dart";
|
||||
import "../../blocs/message_bloc.dart";
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
_HomeState createState() => _HomeState();
|
||||
}
|
||||
|
||||
class _HomeState extends State<Home> {
|
||||
final List<String> titleList = ["Conversations", "Contacts", "Settings"];
|
||||
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
final PageController controller = PageController();
|
||||
final heartbeatSendManager = HeartbeatSendManager();
|
||||
final conversationManager = ConversationManager();
|
||||
|
||||
int _pageNumber = 0;
|
||||
|
||||
|
@ -22,6 +27,8 @@ class _HomeState extends State<Home> {
|
|||
initState() {
|
||||
super.initState();
|
||||
controller.addListener(_updatePageNumber);
|
||||
|
||||
messageBloc.bus.listen((Map<String, String> data) => _processMessage(data));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -36,18 +43,43 @@ class _HomeState extends State<Home> {
|
|||
});
|
||||
}
|
||||
|
||||
_processMessage(Map<String, String> data) {
|
||||
if (data["state"] == "disconnect") {
|
||||
// Disconnect and change state
|
||||
_scaffoldKey.currentState.showBottomSheet<void>(
|
||||
(BuildContext context) => BottomBar(conversationId: ""));
|
||||
} else if (data["state"] == "connect") {
|
||||
// Connect and change state
|
||||
_scaffoldKey.currentState.showBottomSheet<void>((BuildContext context) =>
|
||||
BottomBar(conversationId: data["conversationId"]));
|
||||
} else {
|
||||
// show default
|
||||
_scaffoldKey.currentState.showBottomSheet<void>(
|
||||
(BuildContext context) => BottomBar(conversationId: ""));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> executeAfterBuild() async {
|
||||
final conversationId = await conversationManager.get();
|
||||
|
||||
_scaffoldKey.currentState.showBottomSheet<void>(
|
||||
(BuildContext context) => BottomBar(conversationId: conversationId));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
executeAfterBuild();
|
||||
|
||||
return Scaffold(
|
||||
key: widget._scaffoldKey,
|
||||
body: Column(children: <Widget>[
|
||||
TopBar(title: titleList[_pageNumber], pageNumber: _pageNumber),
|
||||
Expanded(
|
||||
child: PageView(controller: controller, children: <Widget>[
|
||||
ConversationList(),
|
||||
ContactList(),
|
||||
])),
|
||||
]),
|
||||
bottomSheet: BottomBar());
|
||||
key: _scaffoldKey,
|
||||
body: Column(children: <Widget>[
|
||||
TopBar(title: titleList[_pageNumber], pageNumber: _pageNumber),
|
||||
Expanded(
|
||||
child: PageView(controller: controller, children: <Widget>[
|
||||
ConversationList(),
|
||||
ContactList(),
|
||||
])),
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +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 "../../../services/conversation_manager.dart";
|
||||
import "../../../blocs/message_bloc.dart";
|
||||
|
||||
import "../../widgets/user_avatar.dart";
|
||||
|
||||
|
@ -21,8 +20,7 @@ class ConversationItem extends StatefulWidget {
|
|||
class _ConversationItemState extends State<ConversationItem> {
|
||||
final bloc;
|
||||
final Conversation conversation;
|
||||
final bus = bottomBusBloc;
|
||||
final conversationManager = ConversationManager();
|
||||
final bus = messageBloc;
|
||||
|
||||
_ConversationItemState({@required this.conversation})
|
||||
: bloc = ConversationMembersBloc(conversation.id);
|
||||
|
@ -41,54 +39,68 @@ class _ConversationItemState extends State<ConversationItem> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print("BUILDING");
|
||||
return ListTile(
|
||||
isThreeLine: true,
|
||||
onTap: () async {
|
||||
print("Press on ${conversation.id} triggered");
|
||||
await conversationManager.join(conversation.id);
|
||||
print("Gotten past the join");
|
||||
await 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),
|
||||
subtitle: Text("Mum I might have forgotten to close the windows",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.subtitle),
|
||||
trailing: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Text("1m ago",
|
||||
style: Theme.of(context).primaryTextTheme.body1.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).primaryColorDark)),
|
||||
StreamBuilder(
|
||||
stream: bloc.members,
|
||||
builder: (context, AsyncSnapshot<List<User>> snapshot) {
|
||||
print(snapshot.data);
|
||||
if (snapshot.hasData) {
|
||||
return membersBuilder(snapshot.data);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text(snapshot.error.toString());
|
||||
}
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}),
|
||||
]),
|
||||
);
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
elevation: 0,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
await bus.publish(
|
||||
{"state": "connect", "conversationId": conversation.id});
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 5.0, left: 20.0, right: 20.0, bottom: 5.0),
|
||||
child: Column(children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(conversation.title,
|
||||
style: Theme.of(context).textTheme.title),
|
||||
Spacer(),
|
||||
Text("1m ago",
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.body1
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).primaryColorDark)),
|
||||
]),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(
|
||||
"I might have forgotten to close the windows",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style:
|
||||
Theme.of(context).textTheme.subtitle)),
|
||||
StreamBuilder(
|
||||
stream: bloc.members,
|
||||
builder: (context,
|
||||
AsyncSnapshot<List<User>> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return membersBuilder(snapshot.data);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text(snapshot.error.toString());
|
||||
}
|
||||
return SizedBox(width: 18.0, height: 18.0);
|
||||
}),
|
||||
]))
|
||||
]))));
|
||||
}
|
||||
|
||||
Widget membersBuilder(List<User> data) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: data
|
||||
.map((user) => UserAvatar(
|
||||
radius: 15.0,
|
||||
padding: EdgeInsets.only(top: 10.0, left: 5.0),
|
||||
radius: 18.0,
|
||||
padding: EdgeInsets.only(top: 0.0, left: 5.0),
|
||||
user: user))
|
||||
.toList());
|
||||
}
|
||||
|
|
|
@ -29,16 +29,18 @@ class _ConversationListState extends State<ConversationList> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder(
|
||||
stream: bloc.conversations,
|
||||
builder: (context, AsyncSnapshot<List<Conversation>> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return buildList(snapshot.data);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text(snapshot.error.toString());
|
||||
}
|
||||
return Center(child: CircularProgressIndicator());
|
||||
});
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 10.0),
|
||||
child: StreamBuilder(
|
||||
stream: bloc.conversations,
|
||||
builder: (context, AsyncSnapshot<List<Conversation>> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return buildList(snapshot.data);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text(snapshot.error.toString());
|
||||
}
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}));
|
||||
}
|
||||
|
||||
Widget buildList(List<Conversation> data) {
|
||||
|
|
|
@ -24,7 +24,6 @@ class _UserAvatarState extends State<UserAvatar> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
print(widget.user.id);
|
||||
super.initState();
|
||||
bloc = HeartbeatReceiverBloc(widget.user.id);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue