Merge branch 'feat/swipable-selectable-conversation-item' of beep/frontend_flutter into feat/refactor-code-and-user-management-logic
commit
afc3784840
|
@ -34,14 +34,6 @@ class ConversationApiProvider {
|
|||
return Conversation.fromJson(jsonDecode(response.body));
|
||||
}
|
||||
|
||||
void deleteConversation(String id) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
await http.delete("$baseUrlCore/user/conversation/$id", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<Conversation>> fetchConversations() async {
|
||||
final jwt = await loginManager.getToken();
|
||||
print("BASEURLCORE: $baseUrlCore");
|
||||
|
@ -76,6 +68,19 @@ class ConversationApiProvider {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> deleteConversation(String id) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
try {
|
||||
final responseBody =
|
||||
await http.delete("$baseUrlCore/user/conversation/$id", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> createConversationMember(
|
||||
String conversationId, String userId) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
|
|
|
@ -2,6 +2,7 @@ import "package:flutter/material.dart";
|
|||
|
||||
import "../../../models/conversation_model.dart";
|
||||
import "../../../blocs/conversation_bloc.dart";
|
||||
import "../../../resources/conversation_api_provider.dart";
|
||||
|
||||
import "../../widgets/conversation_item.dart";
|
||||
import "../../widgets/top_bar.dart";
|
||||
|
@ -18,6 +19,9 @@ class HomeView extends StatefulWidget {
|
|||
class _HomeViewState extends State<HomeView> {
|
||||
final searchController = TextEditingController();
|
||||
|
||||
List<Conversation> selectedConversations = [];
|
||||
bool editConversations = false;
|
||||
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
|
@ -37,22 +41,44 @@ class _HomeViewState extends State<HomeView> {
|
|||
title: "Conversations",
|
||||
search: SearchInput(
|
||||
controller: searchController, hintText: "Search for people"),
|
||||
children: <Widget>[
|
||||
SmallTextButton(
|
||||
text: "Edit",
|
||||
onClickCallback: () {
|
||||
print("hello");
|
||||
}),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add_comment),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, "conversation/new");
|
||||
}),
|
||||
]),
|
||||
children: (editConversations)
|
||||
? <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
setState(() => editConversations = false);
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
SmallTextButton(
|
||||
text: "Delete All",
|
||||
onClickCallback: () async {
|
||||
for (var conversation in selectedConversations) {
|
||||
await conversationApiProvider
|
||||
.deleteConversation(conversation.id);
|
||||
}
|
||||
setState(() {
|
||||
editConversations = false;
|
||||
});
|
||||
await conversationsBloc.fetchConversations();
|
||||
}),
|
||||
]
|
||||
: <Widget>[
|
||||
SmallTextButton(
|
||||
text: "Edit",
|
||||
onClickCallback: () {
|
||||
setState(() => editConversations = true);
|
||||
}),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add_comment),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, "conversation/new");
|
||||
}),
|
||||
]),
|
||||
Expanded(
|
||||
child:
|
||||
ListView(padding: EdgeInsets.only(top: 10.0), children: <Widget>[
|
||||
ListView(padding: EdgeInsets.only(top: 0.0), children: <Widget>[
|
||||
StreamBuilder(
|
||||
stream: conversationsBloc.conversations,
|
||||
builder: (context, AsyncSnapshot<List<Conversation>> snapshot) {
|
||||
|
@ -73,7 +99,17 @@ class _HomeViewState extends State<HomeView> {
|
|||
shrinkWrap: true,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ConversationItem(conversation: data[index]);
|
||||
return ConversationItem(
|
||||
conversation: data[index],
|
||||
slidable: !editConversations,
|
||||
selectable: editConversations,
|
||||
onSelectedCallback: (selected) {
|
||||
if (selected) {
|
||||
selectedConversations.add(data[index]);
|
||||
} else {
|
||||
selectedConversations.remove(data[index]);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ class _NewGroupInfoViewState extends State<NewGroupInfoView> {
|
|||
.createConversation(nameController.text, profile: _image);
|
||||
|
||||
for (var user in widget.users) {
|
||||
print(user);
|
||||
await conversationApiProvider.createConversationMember(
|
||||
conversation.id, user.id);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,27 @@
|
|||
import "package:flutter/material.dart";
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
|
||||
import "../../models/user_model.dart";
|
||||
import "../../models/conversation_model.dart";
|
||||
import "../../blocs/conversation_bloc.dart";
|
||||
import "../../blocs/message_bloc.dart";
|
||||
import "../../resources/conversation_api_provider.dart";
|
||||
|
||||
import "../widgets/image_avatar.dart";
|
||||
|
||||
typedef void OnSelectedCallback(bool state);
|
||||
|
||||
class ConversationItem extends StatefulWidget {
|
||||
final Conversation conversation;
|
||||
final bool slidable;
|
||||
final bool selectable;
|
||||
final OnSelectedCallback onSelectedCallback;
|
||||
|
||||
ConversationItem({@required this.conversation});
|
||||
ConversationItem(
|
||||
{@required this.conversation,
|
||||
this.slidable = false,
|
||||
this.selectable = false,
|
||||
this.onSelectedCallback});
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _ConversationItemState(conversation: conversation);
|
||||
|
@ -20,6 +31,8 @@ class ConversationItem extends StatefulWidget {
|
|||
class _ConversationItemState extends State<ConversationItem> {
|
||||
final bloc;
|
||||
final Conversation conversation;
|
||||
Widget _avatar;
|
||||
bool selected = false;
|
||||
|
||||
_ConversationItemState({@required this.conversation})
|
||||
: bloc = ConversationMembersBloc(conversation.id);
|
||||
|
@ -38,33 +51,53 @@ class _ConversationItemState extends State<ConversationItem> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
Widget item = Material(
|
||||
type: MaterialType.transparency,
|
||||
elevation: 1,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
await messageChannel.publish({
|
||||
"target": "home",
|
||||
"state": "connect",
|
||||
"conversationId": conversation.id
|
||||
});
|
||||
if (widget.selectable) {
|
||||
setState(() {
|
||||
selected = !selected;
|
||||
});
|
||||
widget.onSelectedCallback(selected);
|
||||
} else {
|
||||
await messageChannel.publish({
|
||||
"target": "home",
|
||||
"state": "connect",
|
||||
"conversationId": conversation.id
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 8.0, left: 10.0, right: 10.0, bottom: 8.0),
|
||||
top: 10.0, left: 10.0, right: 10.0, bottom: 10.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
(widget.selectable)
|
||||
? Checkbox(
|
||||
value: selected,
|
||||
activeColor: Theme.of(context).primaryColorDark,
|
||||
onChanged: (state) {
|
||||
setState(() {
|
||||
selected = !selected;
|
||||
});
|
||||
// print('Checkbox $selected');
|
||||
widget.onSelectedCallback(selected);
|
||||
})
|
||||
: Container(),
|
||||
StreamBuilder(
|
||||
stream: bloc.members,
|
||||
builder:
|
||||
(context, AsyncSnapshot<List<User>> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return avatarBuilder(snapshot.data);
|
||||
_avatar = avatarBuilder(snapshot.data);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text(snapshot.error.toString());
|
||||
}
|
||||
return SizedBox(width: 18.0, height: 18.0);
|
||||
return _avatar ??
|
||||
SizedBox(width: 18.0, height: 18.0);
|
||||
}),
|
||||
Expanded(
|
||||
child: Container(
|
||||
|
@ -94,6 +127,35 @@ class _ConversationItemState extends State<ConversationItem> {
|
|||
color: Theme.of(context).primaryColorDark)),
|
||||
])
|
||||
]))));
|
||||
|
||||
if (widget.slidable) {
|
||||
return Slidable(
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
actionExtentRatio: 0.18,
|
||||
showAllActionsThreshold: 0.5,
|
||||
movementDuration: Duration(milliseconds: 200),
|
||||
child: item,
|
||||
// actions: <Widget>[
|
||||
// IconSlideAction(
|
||||
// color: Colors.green,
|
||||
// icon: Icons.star,
|
||||
// onTap: () => print('Pin'))],
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
color: Colors.green, icon: Icons.star, onTap: () => print('Pin')),
|
||||
IconSlideAction(
|
||||
color: Colors.red,
|
||||
icon: Icons.delete,
|
||||
onTap: () async {
|
||||
await conversationApiProvider
|
||||
.deleteConversation(widget.conversation.id);
|
||||
await conversationsBloc.fetchConversations();
|
||||
})
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
Widget avatarBuilder(List<User> data) {
|
||||
|
|
|
@ -22,6 +22,7 @@ dependencies:
|
|||
unique_identifier: ^0.0.3
|
||||
contacts_service: ^0.2.8
|
||||
path_provider: ^1.1.0
|
||||
flutter_slidable: ^0.5.3
|
||||
image_jpeg: ^1.1.1
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue