mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 04:49:21 +00:00
Get and show the list of conversations
This commit is contained in:
parent
d10df9dd7a
commit
7666af0975
5
lib/enums/load_error_level.dart
Normal file
5
lib/enums/load_error_level.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/// Load error level
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
enum LoadErrorLevel {MINOR, MAJOR, NONE}
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:comunic/helpers/account_credentials_helper.dart';
|
||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/models/api_response.dart';
|
import 'package:comunic/models/api_response.dart';
|
||||||
import 'package:comunic/models/config.dart';
|
import 'package:comunic/models/config.dart';
|
||||||
@ -23,7 +24,12 @@ class APIHelper {
|
|||||||
request.addString("serviceToken", config().serviceToken);
|
request.addString("serviceToken", config().serviceToken);
|
||||||
|
|
||||||
//Add user tokens (if required)
|
//Add user tokens (if required)
|
||||||
if (request.needLogin) throw "Can add user tokens right now !";
|
if (request.needLogin) {
|
||||||
|
final tokens = await AccountCredentialsHelper().get();
|
||||||
|
assert(tokens != null);
|
||||||
|
request.addString("userToken1", tokens.tokenOne);
|
||||||
|
request.addString("userToken2", tokens.tokenTwo);
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare request body
|
// Prepare request body
|
||||||
String requestBody = "";
|
String requestBody = "";
|
||||||
|
36
lib/helpers/conversations_helper.dart
Normal file
36
lib/helpers/conversations_helper.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:comunic/models/api_request.dart';
|
||||||
|
import 'package:comunic/models/conversation.dart';
|
||||||
|
|
||||||
|
/// Conversation helper
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationsHelper {
|
||||||
|
/// Download the list of conversations from the server
|
||||||
|
Future<List<Conversation>> downloadList() async {
|
||||||
|
final response =
|
||||||
|
await APIRequest(uri: "conversations/getList", needLogin: true).exec();
|
||||||
|
|
||||||
|
if (response.code != 200) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<Conversation> list = List();
|
||||||
|
response.getArray().forEach((f) =>
|
||||||
|
list.add(Conversation(
|
||||||
|
id: f["ID"],
|
||||||
|
ownerID: f["ID_owner"],
|
||||||
|
lastActive: f["last_active"],
|
||||||
|
name: f["name"] == false ? null : f["name"],
|
||||||
|
following: f["following"] == 1,
|
||||||
|
sawLastMessage: f["saw_last_message"] == 1,
|
||||||
|
members: f["members"].map<int>((f) => int.parse(f)).toList(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
return list;
|
||||||
|
|
||||||
|
} on Exception catch(e){
|
||||||
|
print(e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:comunic/helpers/api_helper.dart';
|
||||||
|
import 'package:comunic/models/api_response.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
/// API Request model
|
/// API Request model
|
||||||
@ -11,12 +13,11 @@ class APIRequest {
|
|||||||
final bool needLogin;
|
final bool needLogin;
|
||||||
Map<String, String> args;
|
Map<String, String> args;
|
||||||
|
|
||||||
APIRequest({
|
APIRequest({@required this.uri, this.needLogin = false, this.args})
|
||||||
@required this.uri,
|
: assert(uri != null),
|
||||||
this.needLogin = false,
|
assert(needLogin != null) {
|
||||||
}) : assert(uri != null),
|
if (this.args == null) this.args = Map();
|
||||||
assert(needLogin != null),
|
}
|
||||||
args = Map();
|
|
||||||
|
|
||||||
void addString(String name, String value) => args[name] = value;
|
void addString(String name, String value) => args[name] = value;
|
||||||
|
|
||||||
@ -24,4 +25,7 @@ class APIRequest {
|
|||||||
|
|
||||||
void addBool(String name, bool value) =>
|
void addBool(String name, bool value) =>
|
||||||
args[name] = value ? "true" : "false";
|
args[name] = value ? "true" : "false";
|
||||||
|
|
||||||
|
/// Execute the request
|
||||||
|
Future<APIResponse> exec() async => APIHelper().exec(this);
|
||||||
}
|
}
|
||||||
|
30
lib/models/conversation.dart
Normal file
30
lib/models/conversation.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
/// Conversation model
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class Conversation {
|
||||||
|
final int id;
|
||||||
|
final int ownerID;
|
||||||
|
final int lastActive;
|
||||||
|
final String name;
|
||||||
|
final bool following;
|
||||||
|
final bool sawLastMessage;
|
||||||
|
final List<int> members;
|
||||||
|
|
||||||
|
const Conversation({
|
||||||
|
@required this.id,
|
||||||
|
@required this.ownerID,
|
||||||
|
@required this.lastActive,
|
||||||
|
@required this.name,
|
||||||
|
@required this.following,
|
||||||
|
@required this.sawLastMessage,
|
||||||
|
@required this.members,
|
||||||
|
}) : assert(id != null),
|
||||||
|
assert(ownerID != null),
|
||||||
|
assert(lastActive != null),
|
||||||
|
assert(following != null),
|
||||||
|
assert(sawLastMessage != null),
|
||||||
|
assert(members != null);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:comunic/ui/screens/conversations_screen.dart';
|
||||||
import 'package:comunic/ui/screens/menus_screen.dart';
|
import 'package:comunic/ui/screens/menus_screen.dart';
|
||||||
import 'package:comunic/ui/tiles/CustomBottomNavigationBarItem.dart';
|
import 'package:comunic/ui/tiles/CustomBottomNavigationBarItem.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -48,7 +49,7 @@ class _HomeRouteState extends State<HomeRoute> {
|
|||||||
Widget _buildBody(BuildContext context) {
|
Widget _buildBody(BuildContext context) {
|
||||||
switch (_currTab) {
|
switch (_currTab) {
|
||||||
case 0:
|
case 0:
|
||||||
return Text("Conversations");
|
return ConversationsScreen();
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return MenuScreen();
|
return MenuScreen();
|
||||||
|
87
lib/ui/screens/conversations_screen.dart
Normal file
87
lib/ui/screens/conversations_screen.dart
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import 'package:comunic/enums/load_error_level.dart';
|
||||||
|
import 'package:comunic/helpers/conversations_helper.dart';
|
||||||
|
import 'package:comunic/models/conversation.dart';
|
||||||
|
import 'package:comunic/ui/tiles/conversation_tile.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Conversations screen
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationsScreen extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _ConversationScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ConversationScreenState extends State<ConversationsScreen> {
|
||||||
|
final ConversationsHelper _conversationsHelper = ConversationsHelper();
|
||||||
|
List<Conversation> _list;
|
||||||
|
LoadErrorLevel _error = LoadErrorLevel.NONE;
|
||||||
|
bool _loading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
_loadConversations();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setError(LoadErrorLevel err) => setState(() => _error = err);
|
||||||
|
|
||||||
|
void setLoading(bool loading) => setState(() => _loading = loading);
|
||||||
|
|
||||||
|
void gotLoadingError() {
|
||||||
|
setLoading(false);
|
||||||
|
setError(_list == null ? LoadErrorLevel.MAJOR : LoadErrorLevel.MINOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load the list of conversations
|
||||||
|
Future<void> _loadConversations() async {
|
||||||
|
setError(LoadErrorLevel.NONE);
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
final list = await _conversationsHelper.downloadList();
|
||||||
|
|
||||||
|
if (list == null) return gotLoadingError();
|
||||||
|
|
||||||
|
//Save list
|
||||||
|
_list = list;
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build an error card
|
||||||
|
Widget _buildErrorCard() {
|
||||||
|
return buildErrorCard(
|
||||||
|
tr("Could not retrieve the list of conversations!"),
|
||||||
|
actions: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
onPressed: _loadConversations,
|
||||||
|
child: Text(
|
||||||
|
tr("Retry").toUpperCase(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_error == LoadErrorLevel.MAJOR) return _buildErrorCard();
|
||||||
|
if (_list == null) return buildCenteredProgressBar();
|
||||||
|
|
||||||
|
// Show the list of conversations
|
||||||
|
return ListView.builder(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return ConversationTile(
|
||||||
|
conversation: _list.elementAt(index),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: _list.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
55
lib/ui/tiles/conversation_tile.dart
Normal file
55
lib/ui/tiles/conversation_tile.dart
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import 'package:comunic/models/conversation.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Single conversation tile
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationTile extends StatelessWidget {
|
||||||
|
final Conversation conversation;
|
||||||
|
|
||||||
|
const ConversationTile({Key key, this.conversation}) : super(key: key);
|
||||||
|
|
||||||
|
_buildSubInformation(IconData icon, String content) {
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
size: 15.0,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
Text(" " + content),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(conversation.name == null ? "Unknown" : conversation.name),
|
||||||
|
leading: Icon(
|
||||||
|
conversation.sawLastMessage ? Icons.check_circle : Icons.lens,
|
||||||
|
color: conversation.sawLastMessage ? null : Colors.blue,
|
||||||
|
),
|
||||||
|
isThreeLine: true,
|
||||||
|
subtitle: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
_buildSubInformation(Icons.access_time, "time"), //TODO : improve the way the time is shown
|
||||||
|
_buildSubInformation(
|
||||||
|
Icons.group,
|
||||||
|
conversation.members.length == 1
|
||||||
|
? tr("1 member")
|
||||||
|
: tr(
|
||||||
|
"%num% members",
|
||||||
|
args: {
|
||||||
|
"num": conversation.members.length.toString(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,15 @@
|
|||||||
/// Translate a string
|
/// Translate a string
|
||||||
///
|
///
|
||||||
/// Translate a given [string] into the current language, if available
|
/// Translate a given [string] into the current language, if available
|
||||||
String tr(String string) {
|
///
|
||||||
|
/// Then apply the list of [args] to the string, each argument name is
|
||||||
|
/// surrounded by '%'
|
||||||
|
String tr(String string, {Map<String, String> args}) {
|
||||||
//TODO : create translation system
|
//TODO : create translation system
|
||||||
|
|
||||||
|
//Apply arguments
|
||||||
|
if(args != null)
|
||||||
|
args.forEach((key, value) => string = string.replaceAll("%$key%", value));
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ Widget buildLoadingPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build and return an error card
|
/// Build and return an error card
|
||||||
Widget buildErrorCard(String message) {
|
Widget buildErrorCard(String message, {List<Widget> actions}) {
|
||||||
return Card(
|
return Card(
|
||||||
elevation: 2.0,
|
elevation: 2.0,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
@ -39,6 +39,9 @@ Widget buildErrorCard(String message) {
|
|||||||
style: TextStyle(color: Colors.white),
|
style: TextStyle(color: Colors.white),
|
||||||
maxLines: null,
|
maxLines: null,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: actions == null ? <Widget>[] : actions,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user