Skip to content

Commit

Permalink
feat: chirp homepage design done
Browse files Browse the repository at this point in the history
  • Loading branch information
IamMuuo committed Aug 28, 2024
1 parent 9eae7e9 commit 02b8534
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 121 deletions.
36 changes: 5 additions & 31 deletions lib/tools/chirp/controllers/chirp_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,19 @@ import 'package:dartz/dartz.dart';
class ChirpController extends GetxController {
final PostService _service = PostService();
UserController userController = Get.find<UserController>();
RxList<Post> posts = RxList<Post>();
RxInt currentPage = 0.obs;
RxBool feedLoading = false.obs;
RxBool myPostsLoading = false.obs;
RxBool upvotedPostsLoading = false.obs;

@override
void onInit() {
super.onInit();
debugPrint("Chirp Controller Loaded");
}

Future<Either<String, List<Post>>> fetchPosts({
bool nextPage = false,
previousPage = false,
}) async {
feedLoading.value = true;

int page = 1;
// Loading posts comments

if (nextPage) {
page = currentPage.value;
} else if (previousPage && currentPage > 1) {
page = currentPage.value -= 1;
}
final result =
await _service.fetchPosts(userController.authHeaders, page: page);
feedLoading.value = false;
Future<Either<String, List<Post>>> fetchUserPosts() async {
final result = await _service.fetchUserPosts(
userController.authHeaders, userController.user.value!.id!);

return result.fold((l) {
return left(l);
}, (r) {
posts.value = r["posts"];
currentPage.value = r["nextPage"];
return right(posts);
return right(r);
});
}

// Loading posts comments
Future<Either<String, List<Comment>>> fetchPostComments(Post post) async {
final result =
await _service.fetchPostComments(userController.authHeaders, post.id);
Expand Down
28 changes: 27 additions & 1 deletion lib/tools/chirp/models/services/post_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class PostService with ChirpService {
}) async {
try {
final response = await http.get(
Uri.parse("${ChirpService.urlPrefix}/posts/all?pages=$page"),
Uri.parse("${ChirpService.urlPrefix}/posts/all?page=$page"),
headers: authHeaders,
);

Expand Down Expand Up @@ -71,6 +71,32 @@ class PostService with ChirpService {
}
}

Future<Either<String, List<Post>>> fetchUserPosts(
Map<String, String> authHeaders, String userID) async {
try {
final response = await http.get(
Uri.parse("${ChirpService.urlPrefix}/posts/user/$userID"),
headers: authHeaders,
);
if (response.statusCode == 200) {
final List<Map<String, dynamic>> rawData =
json.decode(response.body).cast<Map<String, dynamic>>();

final List<Post> comments =
rawData.map((e) => Post.fromJson(e)).toList().cast<Post>();

return right(comments);
}
return left(
json.decode(response.body)["error"],
);
} catch (e) {
return left(
"Encountered an error we did, check your connection you must, ${e.toString()}",
);
}
}

Future<Either<String, List<Comment>>> fetchPostComments(
Map<String, String> authHeaders,
String post, {
Expand Down
45 changes: 35 additions & 10 deletions lib/tools/chirp/pages/chirp_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,14 @@ class _ChirpHomePageState extends State<ChirpHomePage> {
@override
void initState() {
super.initState();
controller.fetchPosts().then((value) {
value.fold((l) {}, (r) {});
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.surfaceDim,
body: DefaultTabController(
length: 3,
length: 2,
child: CustomScrollView(
slivers: [
SliverAppBar(
Expand Down Expand Up @@ -77,9 +74,8 @@ class _ChirpHomePageState extends State<ChirpHomePage> {
snap: true,
bottom: const TabBar(
tabs: [
Tab(text: 'Feed'),
Tab(text: 'My Feed'),
Tab(text: "My Posts"),
Tab(text: "Upvoted"),
],
),
),
Expand All @@ -92,11 +88,40 @@ class _ChirpHomePageState extends State<ChirpHomePage> {
),
),
SliverFillRemaining(
hasScrollBody: true,
fillOverscroll: true,
child: TabBarView(children: [
FeedPage(),
Text("Holla"),
Text("Moma"),
])),
const FeedPage(),
FutureBuilder(
future: controller.fetchUserPosts(),
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return ListView.separated(
itemBuilder: (context, index) {
return const EmptyPostCard();
},
separatorBuilder: (context, index) =>
const SizedBox(
height: 4,
),
itemCount: 12);
}
return snapshot.data!.fold((l) {
return Center(
child: Text("Snap! $l"),
);
}, (r) {
return ListView.separated(
itemBuilder: (context, index) {
final post = r[index];
return PostCard(post: post);
},
separatorBuilder: (context, index) =>
const SizedBox(height: 2),
itemCount: r.length);
});
}),
])),
],
),
),
Expand Down
153 changes: 89 additions & 64 deletions lib/tools/chirp/pages/feed_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
import 'package:academia/exports/barrel.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
import '../widgets/widgets.dart';
import '../controllers/chirp_controller.dart';

class FeedPage extends StatefulWidget {
const FeedPage({super.key});
Expand All @@ -12,68 +10,95 @@ class FeedPage extends StatefulWidget {
}

class _FeedPageState extends State<FeedPage> {
final ChirpController controller = Get.find<ChirpController>();
bool pageLoading = true;
bool morePostsLoading = false;
List<Post> feedPosts = [];
int nextPage = 1;
bool hasMorePages = true;

final UserController userController = Get.find<UserController>();
final PostService _service = PostService();
@override
void initState() {
super.initState();
_service.fetchPosts(userController.authHeaders).then((value) {
value.fold((l) {
debugPrint(l);
}, (r) {
feedPosts.addAll(r["posts"]);
if (nextPage == r["nextPage"]) {
setState(() {
hasMorePages = false;
});
return;
}

nextPage = r["nextPage"];
setState(() {});
});
});
setState(() {
pageLoading = false;
});
}

@override
Widget build(BuildContext context) {
return RefreshIndicator(
child: Obx(
() => controller.feedLoading.value || true
? ListView.builder(
itemBuilder: (context, index) => EmptyPostCard(),
)
: Text("Loaded"),
),
onRefresh: () async {
Future.delayed(Duration(seconds: 5));
});
return pageLoading
? ListView.separated(
itemBuilder: (context, index) {
return const EmptyPostCard();
},
separatorBuilder: (context, index) => const SizedBox(
height: 4,
),
itemCount: 12)
: feedPosts.isEmpty
? const Center(
child: Text("No posts here yet"),
)
: ListView.separated(
itemBuilder: (context, index) {
if (index < feedPosts.length) {
final post = feedPosts[index];
return PostCard(post: post);
}
return hasMorePages
? morePostsLoading
? const LinearProgressIndicator()
: TextButton(
onPressed: fetchMorePosts,
child: const Text("Load more"),
)
: const Text("You have reached the end of feed!");
},
separatorBuilder: (context, index) => const SizedBox(height: 2),
itemCount: feedPosts.length + 1);
}

Future<void> fetchMorePosts() async {
setState(() {
morePostsLoading = true;
});

_service
.fetchPosts(userController.authHeaders, page: nextPage)
.then((value) {
value.fold((l) {
debugPrint(l);
}, (r) {
feedPosts.addAll(r["posts"]);
setState(() {});
if (nextPage == r["nextPage"]) {
hasMorePages = false;
return;
}
nextPage = r["nextPage"];
});
});

setState(() {
morePostsLoading = false;
});
}
}
// Obx(
// () => controller.isLoading.value
// ? SingleChildScrollView(
// child: Column(
// children: [
// Lottie.asset("assets/lotties/fetching.json"),
// const SizedBox(height: 22),
// Text(
// "Fetching posts",
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.headlineSmall,
// ),
// ],
// ),
// )
// : RefreshIndicator(
// onRefresh: () async {
// await controller.fetchPosts();
// },
// child: controller.posts.isEmpty
// ? SingleChildScrollView(
// child: Column(
// children: [
// Lottie.asset("assets/lotties/empty.json"),
// Text(
// "Argh snap! We couldn't find posts at the moment. Please try again later",
// textAlign: TextAlign.center,
// style: Theme.of(context)
// .textTheme
// .headlineSmall,
// ),
// ],
// ),
// )
// : ListView.separated(
// itemBuilder: (context, index) {
// final data = controller.posts[index];
// return PostCard(post: data);
// },
// separatorBuilder: (context, index) =>
// const SizedBox(
// height: 8,
// child: Divider(thickness: 0.3),
// ),
// itemCount: controller.posts.length,
// ),
// ),
// ),
//
15 changes: 0 additions & 15 deletions lib/tools/chirp/pages/post_create_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,6 @@ class _PostCreatePageState extends State<PostCreatePage> {
},
icon: const Icon(Ionicons.close),
),
// actions: [
// IconButton(
// onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => ImageConfigScreen(
// onImagePicked: (file) {
// setState(() {
// imageFiles.add(file!);
// });
// },
// )));
// },
// icon: const Icon(Ionicons.attach_outline),
// ),
// ],
),
body: SafeArea(
minimum: const EdgeInsets.all(12),
Expand Down

0 comments on commit 02b8534

Please sign in to comment.