From 7fb27ba6b6c1358d0577830d59228bc4513207a3 Mon Sep 17 00:00:00 2001 From: Eli <88557639+lishaduck@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:41:20 -0500 Subject: [PATCH] chore: extract out post widget wip chore: extract out post widget --- packages/app/lib/src/app/wrapper_page.dart | 1 + .../features/home/presentation/home/feed.dart | 52 +----- .../features/home/presentation/home/post.dart | 148 ++++++++++++++++++ 3 files changed, 153 insertions(+), 48 deletions(-) create mode 100644 packages/app/lib/src/features/home/presentation/home/post.dart diff --git a/packages/app/lib/src/app/wrapper_page.dart b/packages/app/lib/src/app/wrapper_page.dart index f3f2b32..392786f 100644 --- a/packages/app/lib/src/app/wrapper_page.dart +++ b/packages/app/lib/src/app/wrapper_page.dart @@ -30,6 +30,7 @@ class WrapperPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + print('wrapper page is building'); return AutoTabsScaffold( routes: const [ // TODO(MattsAttack): fix bar. diff --git a/packages/app/lib/src/features/home/presentation/home/feed.dart b/packages/app/lib/src/features/home/presentation/home/feed.dart index 6d10c97..d017be0 100644 --- a/packages/app/lib/src/features/home/presentation/home/feed.dart +++ b/packages/app/lib/src/features/home/presentation/home/feed.dart @@ -1,6 +1,4 @@ /// This library contains a widget that displays a feed of posts. -// ignore_for_file: prefer_expression_function_bodies - library; import 'package:flutter/foundation.dart'; @@ -10,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../application/feed_service.dart'; import '../../domain/feed_entity.dart'; import '../../domain/post_entity.dart'; +import 'post.dart'; /// {@template our_democracy.features.home.presentation.home.feed} /// An infinite loading list of posts. @@ -28,7 +27,7 @@ class Feed extends ConsumerWidget { // Maybe change to scaffold with floating action button and list view as child return ListView.builder( shrinkWrap: true, - prototypeItem: _Post( + prototypeItem: Post( post: PostEntity( headline: '', description: '', @@ -42,13 +41,13 @@ class Feed extends ConsumerWidget { final response = ref.watch(singlePostProvider(feed, index)); return switch (response) { - AsyncData(:final value) when value != null => _Post(post: value), + AsyncData(:final value) when value != null => Post(post: value), // If we run out of items, return null. AsyncData() => null, // If there's an error, display it as another post. - AsyncError(:final error) => _Post( + AsyncError(:final error) => Post( post: PostEntity( headline: 'Error', description: error.toString(), @@ -74,46 +73,3 @@ class Feed extends ConsumerWidget { } // coverage:ignore-end } - -class _Post extends StatelessWidget { - const _Post({ - required this.post, - // Temporary ignore, see . - // ignore: unused_element - super.key, - }); - final PostEntity post; - - @override - Widget build(BuildContext context) { - return Card( - child: ListTile( - leading: switch (post.image) { - // If the image is an BucketFile, figure out how to get the image from the API. - // Will need to be cached in Riverpod. Probably store it in the entity. - // But, deserialization shouldn't need to know about the API. - // This'll be tricky. For now, I think we make a dummy image. - final String _ => Image.network( - 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/991px-Placeholder_view_vector.svg.png', - ), - // final BucketFile image => Image.memory(image), - // Else, return null. - null => null, - }, - title: Text(post.headline), - subtitle: Text(post.description), - // isThreeLine: true, - // minVerticalPadding: 100, - // TODO(MattsAttack): add in on tap functionality to click on post - ), - ); - } - - // coverage:ignore-start - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(DiagnosticsProperty('post', post)); - } - // coverage:ignore-end -} diff --git a/packages/app/lib/src/features/home/presentation/home/post.dart b/packages/app/lib/src/features/home/presentation/home/post.dart new file mode 100644 index 0000000..bf98ad3 --- /dev/null +++ b/packages/app/lib/src/features/home/presentation/home/post.dart @@ -0,0 +1,148 @@ +// ignore_for_file: prefer_expression_function_bodies, prefer_const_constructors + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import '../../../../gen/assets.gen.dart'; +import '../../domain/post_entity.dart'; + +class Post extends StatelessWidget { + const Post({ + required this.post, + // Temporary ignore, see . + // ignore: unused_element + super.key, + }); + + final PostEntity post; + + @override + Widget build(BuildContext context) { + print('trying to build post!'); + return Card( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: 100, // Todo edit to scale based on required height + margin: EdgeInsets.all(4), + padding: EdgeInsets.all(4), + child: Column( + children: [ + // Have sections of post in here. Poster info and post content + _PosterInfo(post: post), + Divider(color: Colors.white), //TODObase on theme + _PostBody(post: post), + ], + ), + ), + ); + } + + // coverage:ignore-start + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('post', post)); + } + // coverage:ignore-end +} + +class _PosterInfo extends StatelessWidget { + const _PosterInfo({required this.post, super.key}); + + final PostEntity post; + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Expanded( + child: Row( + children: [ + CircleAvatar( + backgroundImage: AssetImage(Assets.pictures.kid.path), + ), // Possible bug here, + Padding(padding: EdgeInsets.all(4)), + Text(post.author), // Get user name instead of id + Padding(padding: EdgeInsets.all(4)), + Text(post.timestamp.toString()), + ], + ), + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('post', post)); + } +} + +class _PostBody extends StatelessWidget { + const _PostBody({required this.post, super.key}); + + final PostEntity post; + + @override + Widget build(BuildContext context) { + // TODO: implement build + // final day = post.timestamp.day; + // final month = post.timestamp.month; + // final year = post.timestamp.year; + // final time = DateFormat.Hms().format(post.timestamp); + + return Expanded( + child: Row( + children: [ + CircleAvatar( + backgroundImage: AssetImage(Assets.pictures.kid.path), + ), // Possible bug here, + Padding(padding: EdgeInsets.all(4)), + Text(post.author), // Get user name instead of id + Padding(padding: EdgeInsets.all(4)), + // Text('$time , $month $day, $year'), + ], + ), + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('post', post)); + } +} +// // child: Row( +// // children: [ +// // Image.network( +// // 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/991px-Placeholder_view_vector.svg.png', +// // ), +// // Column( +// // children: [ +// // const Text(''), +// // Text(post.headline), +// // Text(post.description), +// // ], +// // ), +// child: ListTile( +// // leading: switch (post.image) { +// // // If the image is an BucketFile, figure out how to get the image from the API. +// // // Will need to be cached in Riverpod. Probably store it in the entity. +// // // But, deserialization shouldn't need to know about the API. +// // // This'll be tricky. For now, I think we make a dummy image. +// // final String _ => Image.network( +// // 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/991px-Placeholder_view_vector.svg.png', +// // ), +// // // final BucketFile image => Image.memory(image), +// // // Else, return null. +// // null => null, +// // }, +// leading: Image.network( +// 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/991px-Placeholder_view_vector.svg.png', +// ), +// title: Text(post.headline), +// subtitle: Text(post.description), +// // isThreeLine: true, +// // minVerticalPadding: 100, +// // TODO(MattsAttack): add in on tap functionality to click on post +// ), +// // ], +// // ),