1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-12-26 04:48:51 +00:00

Get latest posts from server

This commit is contained in:
Pierre HUBERT 2019-05-10 19:15:11 +02:00
parent 8d188373ce
commit ddbea1727b
9 changed files with 301 additions and 3 deletions

14
lib/enums/post_kind.dart Normal file
View File

@ -0,0 +1,14 @@
/// Different kinds of posts
///
/// @author Pierre HUBERT
enum PostKind {
TEXT,
IMAGE,
WEB_LINK,
PDF,
MOVIE,
COUNTDOWN,
SURVEY,
YOUTUBE
}

View File

@ -0,0 +1,5 @@
/// Post visibility level
///
/// @author Pierre HUBERT
enum PostVisibilityLevel { PUBLIC, FRIENDS, USER, GROUP_MEMBERS }

View File

@ -0,0 +1,5 @@
/// User access levels
///
/// @author Pierre HUBERT
enum UserAccessLevels { NONE, BASIC, INTERMEDIATE, FULL}

View File

@ -0,0 +1,82 @@
import 'package:comunic/enums/post_kind.dart';
import 'package:comunic/enums/post_visibility_level.dart';
import 'package:comunic/enums/user_access_levels.dart';
import 'package:comunic/lists/posts_list.dart';
import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/post.dart';
/// Posts helper
///
/// @author Pierre HUBERT
const _APIPostsVisibilityLevelMap = {
"public": PostVisibilityLevel.PUBLIC,
"friends": PostVisibilityLevel.FRIENDS,
"private": PostVisibilityLevel.USER,
"members": PostVisibilityLevel.GROUP_MEMBERS
};
const _APIPostsKindsMap = {
"text": PostKind.TEXT,
"image": PostKind.IMAGE,
"weblink": PostKind.WEB_LINK,
"pdf": PostKind.PDF,
"movie": PostKind.MOVIE,
"countdown": PostKind.COUNTDOWN,
"survey": PostKind.SURVEY,
"youtube": PostKind.YOUTUBE
};
const _APIUserAccessMap = {
"no-access": UserAccessLevels.NONE,
"basic": UserAccessLevels.BASIC,
"intermediate": UserAccessLevels.INTERMEDIATE,
"full": UserAccessLevels.FULL
};
class PostsHelper {
/// Get the list of latest posts. Return the list of posts or null in case of
/// failure
Future<PostsList> getLatest() async {
final response = await APIRequest(
uri: "posts/get_latest",
needLogin: true,
).exec();
if (response.code != 200) return null;
try {
// Parse & return the list of posts
return PostsList()..addAll(response.getArray().map((f) => _apiToPost(f)));
} catch (e) {
print(e.toString());
return null;
}
}
/// Turn an API entry into a [Post] object
Post _apiToPost(Map<String, dynamic> map) {
return Post(
id: map["ID"],
userID: map["userID"],
userPageID: map["user_page_id"],
groupID: map["group_id"],
timeSent: map["post_time"],
content: map["content"],
visibilityLevel: _APIPostsVisibilityLevelMap[map["visibility_level"]],
kind: _APIPostsKindsMap[map["kind"]],
fileSize: map["file_size"],
fileType: map["file_type"],
filePath: map["file_path"],
fileURL: map["file_path_url"],
timeEnd: map["time_end"],
linkURL: map["link_url"],
linkTitle: map["link_title"],
linkDescription: map["link_description"],
linkImage: map["link_image"],
likes: map["likes"],
userLikes: map["userlike"],
access: _APIUserAccessMap[map["user_access"]],
);
}
}

View File

@ -51,6 +51,12 @@ class UsersHelper {
return list;
}
/// Get users information from a given [Set]
Future<UsersList> getList(Set<int> users,
{bool forceDownload = false}) async {
return await getUsersInfo(users.toList());
}
/// Get users information
///
/// If [forceDownload] is set to true, the data will always be retrieved from

39
lib/lists/posts_list.dart Normal file
View File

@ -0,0 +1,39 @@
import 'dart:collection';
import 'package:comunic/models/post.dart';
/// Posts List
///
/// Contains method to easily process a list of posts
///
/// @author Pierre HUBERT
class PostsList extends ListBase<Post> {
List<Post> _list = List();
int get length => _list.length;
set length(int l) => _list.length = l;
@override
Post operator [](int index) => _list[index];
@override
void operator []=(int index, Post value) => _list[index] = value;
// Get the list of users ID in this set
Set<int> get usersID {
Set<int> set = Set();
forEach((p) {
set.add(p.userID);
if(p.userPageID != null && p.userPageID > 0)
set.add(p.userPageID);
});
return set;
}
}

64
lib/models/post.dart Normal file
View File

@ -0,0 +1,64 @@
import 'package:comunic/enums/post_kind.dart';
import 'package:comunic/enums/post_visibility_level.dart';
import 'package:comunic/enums/user_access_levels.dart';
import 'package:meta/meta.dart';
/// Single post information
///
/// @author Pierre HUBERT
class Post {
final int id;
final int userID;
final int userPageID;
final int groupID;
final int timeSent;
final String content;
final PostVisibilityLevel visibilityLevel;
final PostKind kind;
final int fileSize;
final String fileType;
final String filePath;
final String fileURL;
final int timeEnd;
final String linkURL;
final String linkTitle;
final String linkDescription;
final String linkImage;
final int likes;
final bool userLikes;
final UserAccessLevels access;
Post({
@required this.id,
@required this.userID,
@required this.userPageID,
@required this.groupID,
@required this.timeSent,
@required this.content,
@required this.visibilityLevel,
@required this.kind,
@required this.fileSize,
@required this.fileType,
@required this.filePath,
@required this.fileURL,
@required this.timeEnd,
@required this.linkURL,
@required this.linkTitle,
@required this.linkDescription,
@required this.linkImage,
@required this.likes,
@required this.userLikes,
@required this.access,
}) : assert(id != null),
assert(userID != null),
assert(userPageID != 0 || groupID != 0),
assert(timeSent != null),
assert(kind != PostKind.TEXT || content != null),
assert(visibilityLevel != null),
assert(kind != null),
assert(kind != PostKind.COUNTDOWN || timeEnd != null),
assert(likes != null),
assert(userLikes != null),
assert(access != null);
}

View File

@ -1,3 +1,10 @@
import 'package:comunic/helpers/posts_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/posts_list.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/ui/screens/conversation_screen.dart';
import 'package:comunic/ui/tiles/post_tile.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
@ -11,10 +18,59 @@ class NewestPostsScreen extends StatefulWidget {
}
class _NewestPostsScreenState extends State<NewestPostsScreen> {
// Helpers
final PostsHelper _postsHelper = PostsHelper();
final UsersHelper _usersHelper = UsersHelper();
// Class members
PostsList _list;
UsersList _users;
ErrorLevel _error = ErrorLevel.NONE;
set error(ErrorLevel err) => setState(() => _error = err);
@override
void didChangeDependencies() {
super.didChangeDependencies();
_loadPostsList();
}
void _loadError() =>
error = _list == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR;
Future<void> _loadPostsList() async {
final list = await _postsHelper.getLatest();
if (list == null) return _loadError();
final users = await _usersHelper.getList(list.usersID);
if (users == null) return _loadError();
setState(() {
_list = list;
_users = users;
});
}
Widget _buildErrorCard() {
return buildErrorCard(tr("Could not get the list of posts !"));
}
Widget _buildListView() {
return ListView.builder(
itemCount: _list.length,
itemBuilder: (c, i) => PostTile(
post: _list[i],
usersInfo: _users,
),
);
}
@override
Widget build(BuildContext context) {
return buildCenteredProgressBar();
if (_error == ErrorLevel.MAJOR) return _buildErrorCard();
if (_list == null) return buildCenteredProgressBar();
return _buildListView();
}
}
}

View File

@ -0,0 +1,27 @@
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/post.dart';
import 'package:flutter/material.dart';
/// Single posts tile
///
/// @author Pierre HUBERT
class PostTile extends StatelessWidget {
final Post post;
final UsersList usersInfo;
const PostTile({
Key key,
@required this.post,
@required this.usersInfo,
}) : assert(post != null),
assert(usersInfo != null),
super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
leading: Text("a post"),
);
}
}