1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-26 06:49:22 +00:00

Cache the list of friends

This commit is contained in:
Pierre HUBERT 2019-05-04 19:35:03 +02:00
parent 62125d7c3d
commit 67a6befc02
6 changed files with 100 additions and 12 deletions

View File

@ -46,3 +46,13 @@ abstract class ConversationsMessagesTableContract {
static const C_MESSAGE = "message"; static const C_MESSAGE = "message";
static const C_IMAGE_URL = "image_url"; static const C_IMAGE_URL = "image_url";
} }
/// Friends table contract
abstract class FriendsListTableContract {
static const TABLE_NAME = "friends";
static const C_ID = BaseTableContract.C_ID;
static const C_ACCEPTED = "accepted";
static const C_LAST_ACTIVE = "last_active";
static const C_FOLLOWING = "following";
static const C_CAN_POST_TEXTS = "can_post_texts";
}

View File

@ -45,6 +45,10 @@ abstract class DatabaseHelper {
await db.execute( await db.execute(
"DROP TABLE IF EXISTS ${ConversationsMessagesTableContract.TABLE_NAME}"); "DROP TABLE IF EXISTS ${ConversationsMessagesTableContract.TABLE_NAME}");
// Drop friends list table
await db.execute(
"DROP TABLE IF EXISTS ${FriendsListTableContract.TABLE_NAME}");
// Initialize database again // Initialize database again
await _initializeDatabase(db, newVersion); await _initializeDatabase(db, newVersion);
} }
@ -82,5 +86,14 @@ abstract class DatabaseHelper {
"${ConversationsMessagesTableContract.C_MESSAGE} TEXT, " "${ConversationsMessagesTableContract.C_MESSAGE} TEXT, "
"${ConversationsMessagesTableContract.C_IMAGE_URL} TEXT" "${ConversationsMessagesTableContract.C_IMAGE_URL} TEXT"
")"); ")");
// Friends list table
await db.execute("CREATE TABLE ${FriendsListTableContract.TABLE_NAME} ("
"${FriendsListTableContract.C_ID} INTEGER PRIMARY KEY, "
"${FriendsListTableContract.C_ACCEPTED} INTEGER, "
"${FriendsListTableContract.C_LAST_ACTIVE} INTEGER, "
"${FriendsListTableContract.C_FOLLOWING} INTEGER, "
"${FriendsListTableContract.C_CAN_POST_TEXTS} INTEGER"
")");
} }
} }

View File

@ -0,0 +1,15 @@
import 'package:comunic/helpers/database/database_contract.dart';
import 'package:comunic/helpers/database/model_database_helper.dart';
import 'package:comunic/models/friend.dart';
/// Friends database helper
///
/// @author Pierre HUBERT
class FriendsDatabaseHelper extends ModelDatabaseHelper<Friend> {
@override
Friend initializeFromMap(Map<String, dynamic> map) => Friend.fromMap(map);
@override
String tableName() => FriendsListTableContract.TABLE_NAME;
}

View File

@ -1,17 +1,22 @@
import 'package:comunic/helpers/database/friends_database_helper.dart';
import 'package:comunic/lists/friends_list.dart'; import 'package:comunic/lists/friends_list.dart';
import 'package:comunic/models/api_request.dart'; import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/friend.dart'; import 'package:comunic/models/friend.dart';
import 'package:meta/meta.dart';
/// Friends helper /// Friends helper
/// ///
/// @author Pierre HUBERT /// @author Pierre HUBERT
class FriendsHelper { class FriendsHelper {
/// Get the list of friends of the user
final FriendsDatabaseHelper _friendsDatabaseHelper = FriendsDatabaseHelper();
/// Get the list of friends of the user from the server
/// ///
/// Returns the list of friends in case of success, or null if an error /// Returns the list of friends in case of success, or null if an error
/// occurred /// occurred
Future<FriendsList> downloadList() async { Future<FriendsList> _downloadList() async {
final response = await APIRequest( final response = await APIRequest(
uri: "friends/getList", uri: "friends/getList",
needLogin: true, needLogin: true,
@ -36,9 +41,23 @@ class FriendsHelper {
), ),
); );
// Save the list of friends
_friendsDatabaseHelper.clearTable();
_friendsDatabaseHelper.insertAll(list);
return list; return list;
} }
/// Get the list, either from an online or an offline source
Future<FriendsList> getList({@required bool online}) async {
if(online)
return await _downloadList();
else
return FriendsList()..addAll(await _friendsDatabaseHelper.getAll());
}
/// Respond to friendship request /// Respond to friendship request
Future<bool> respondRequest(int friendID, bool accept) async { Future<bool> respondRequest(int friendID, bool accept) async {
final response = await APIRequest( final response = await APIRequest(

View File

@ -1,3 +1,5 @@
import 'package:comunic/helpers/database/database_contract.dart';
import 'package:comunic/models/cache_model.dart';
import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/date_utils.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
@ -5,15 +7,14 @@ import 'package:meta/meta.dart';
/// ///
/// @author Pierre HUBERT /// @author Pierre HUBERT
class Friend { class Friend extends CacheModel implements Comparable<Friend> {
final int id;
final bool accepted; final bool accepted;
final int lastActive; final int lastActive;
final bool following; final bool following;
final bool canPostTexts; final bool canPostTexts;
Friend({ const Friend({
@required this.id, @required int id,
@required this.accepted, @required this.accepted,
@required this.lastActive, @required this.lastActive,
@required this.following, @required this.following,
@ -22,8 +23,29 @@ class Friend {
assert(accepted != null), assert(accepted != null),
assert(lastActive != null), assert(lastActive != null),
assert(following != null), assert(following != null),
assert(canPostTexts != null); assert(canPostTexts != null),
super(id: id);
/// Check out whether friend is connected or not /// Check out whether friend is connected or not
bool get isConnected => time() - 30 < lastActive; bool get isConnected => time() - 30 < lastActive;
@override
int compareTo(Friend other) => other.lastActive.compareTo(lastActive);
@override
Map<String, dynamic> toMap() => {
FriendsListTableContract.C_ID: id.toString(),
FriendsListTableContract.C_ACCEPTED: accepted ? 1 : 0,
FriendsListTableContract.C_LAST_ACTIVE: lastActive,
FriendsListTableContract.C_FOLLOWING: following ? 1 : 0,
FriendsListTableContract.C_CAN_POST_TEXTS: canPostTexts ? 1 : 0
};
Friend.fromMap(Map<String, dynamic> map)
: assert(map != null),
accepted = map[FriendsListTableContract.C_ACCEPTED] == 1,
lastActive = map[FriendsListTableContract.C_LAST_ACTIVE],
following = map[FriendsListTableContract.C_FOLLOWING] == 1,
canPostTexts = map[FriendsListTableContract.C_CAN_POST_TEXTS] == 1,
super.fromMap(map);
} }

View File

@ -47,7 +47,13 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_loadList(); _getList();
}
/// Initialize list retrieving
Future<void> _getList() async {
await _loadList(false);
await _loadList(true);
} }
/// Refresh the list of friends /// Refresh the list of friends
@ -56,11 +62,14 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
} }
/// Load the list of friends /// Load the list of friends
Future<void> _loadList() async { Future<void> _loadList(bool online) async {
error = _ErrorsLevel.NONE; error = _ErrorsLevel.NONE;
// Get the list of friends // Get the list of friends
final list = await _friendsHelper.downloadList(); final list = await _friendsHelper.getList(online: online);
// Check if there is no cache yet
if(!online && list.isEmpty) return;
// Check for errors // Check for errors
if (list == null) return _gotError(); if (list == null) return _gotError();
@ -73,7 +82,7 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
// Apply new information // Apply new information
setState(() { setState(() {
_friendsList = list; _friendsList = list..sort();
_usersInfo = users; _usersInfo = users;
}); });
error = _ErrorsLevel.NONE; error = _ErrorsLevel.NONE;
@ -107,7 +116,7 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
Expanded( Expanded(
child: RefreshIndicator( child: RefreshIndicator(
key: _refreshIndicatorKey, key: _refreshIndicatorKey,
onRefresh: _loadList, onRefresh: () => _loadList(true),
child: ListView.builder( child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(), physics: AlwaysScrollableScrollPhysics(),
itemCount: _friendsList.length, itemCount: _friendsList.length,