Better post list

This commit is contained in:
LittleSheep 2024-07-06 21:14:19 +08:00
parent 66ddfea68d
commit 343b84e3e1
7 changed files with 137 additions and 147 deletions

View File

@ -40,20 +40,12 @@ abstract class AppRouter {
); );
static final ShellRoute _feedRoute = ShellRoute( static final ShellRoute _feedRoute = ShellRoute(
builder: (context, state, child) => BasicShell( builder: (context, state, child) => child,
state: state,
sidebarFirst: true,
showAppBar: false,
sidebar: const FeedScreen(),
child: child,
),
routes: [ routes: [
GoRoute( GoRoute(
path: '/', path: '/',
name: 'feed', name: 'feed',
builder: (context, state) => SolianTheme.isExtraLargeScreen(context) builder: (context, state) => const FeedScreen(),
? const EmptyPagePlaceholder()
: const FeedScreen(),
), ),
GoRoute( GoRoute(
path: '/posts/view/:alias', path: '/posts/view/:alias',

View File

@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:solian/exts.dart'; import 'package:solian/exts.dart';
import 'package:solian/models/post.dart'; import 'package:solian/models/post.dart';
import 'package:solian/providers/content/post.dart'; import 'package:solian/providers/content/post.dart';
import 'package:solian/widgets/centered_container.dart';
import 'package:solian/widgets/posts/post_item.dart'; import 'package:solian/widgets/posts/post_item.dart';
import 'package:solian/widgets/posts/post_replies.dart'; import 'package:solian/widgets/posts/post_replies.dart';
@ -47,6 +48,7 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
SliverToBoxAdapter( SliverToBoxAdapter(
child: CenteredContainer(
child: PostItem( child: PostItem(
item: item!, item: item!,
isClickable: true, isClickable: true,
@ -54,15 +56,22 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
isShowReply: false, isShowReply: false,
), ),
), ),
const SliverToBoxAdapter(
child: Divider(thickness: 0.3, height: 0.3),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: const Divider(thickness: 0.3, height: 1)
.paddingOnly(top: 4),
),
SliverToBoxAdapter(
child: CenteredContainer(
child: Align(
alignment: Alignment.centerLeft,
child: Text( child: Text(
'postReplies'.tr, 'postReplies'.tr,
style: Theme.of(context).textTheme.headlineSmall, style: Theme.of(context).textTheme.headlineSmall,
).paddingOnly(left: 24, right: 24, top: 16), ).paddingOnly(left: 24, right: 24, top: 16),
), ),
),
),
PostReplyList(item: item!), PostReplyList(item: item!),
SliverToBoxAdapter( SliverToBoxAdapter(
child: SizedBox(height: MediaQuery.of(context).padding.bottom), child: SizedBox(height: MediaQuery.of(context).padding.bottom),

View File

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:go_router/go_router.dart';
import 'package:solian/router.dart';
import 'package:solian/theme.dart';
import 'package:solian/widgets/app_bar_title.dart';
import 'package:solian/widgets/prev_page.dart';
class CenteredShell extends StatelessWidget {
final bool showAppBar;
final GoRouterState state;
final Widget child;
const CenteredShell({
super.key,
required this.child,
required this.state,
this.showAppBar = true,
});
@override
Widget build(BuildContext context) {
final canPop = AppRouter.instance.canPop();
return Scaffold(
appBar: showAppBar
? AppBar(
title: AppBarTitle(state.topRoute?.name?.tr ?? 'page'.tr),
centerTitle: false,
toolbarHeight: SolianTheme.toolbarHeight(context),
leading: canPop ? const PrevPageButton() : null,
automaticallyImplyLeading: false,
)
: null,
body: Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 640),
child: child,
),
),
);
}
}

View File

@ -1,89 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/router.dart';
import 'package:solian/theme.dart';
import 'package:solian/widgets/navigation/app_navigation.dart';
import 'package:solian/widgets/prev_page.dart';
import 'package:solian/widgets/navigation/app_navigation_bottom_bar.dart';
import 'package:solian/widgets/navigation/app_navigation_rail.dart';
import 'package:solian/widgets/sidebar/sidebar_placeholder.dart';
class NavShell extends StatelessWidget {
final bool showAppBar;
final bool showSidebar;
final bool showNavigation;
final bool? showBottomNavigation;
final Widget child;
final bool sidebarFirst;
final Widget? sidebar;
const NavShell({
super.key,
required this.child,
this.showAppBar = true,
this.showSidebar = true,
this.showNavigation = true,
this.showBottomNavigation,
this.sidebarFirst = false,
this.sidebar,
});
List<Widget> buildContent(BuildContext context) {
return [
Flexible(
flex: 2,
child: child,
),
if (SolianTheme.isExtraLargeScreen(context))
const VerticalDivider(thickness: 0.3, width: 1),
if (SolianTheme.isExtraLargeScreen(context))
Flexible(
flex: 1,
child: sidebar ?? const SidebarPlaceholder(),
),
];
}
@override
Widget build(BuildContext context) {
final canPop = AppRouter.instance.canPop();
final routeName =
AppRouter.instance.routerDelegate.currentConfiguration.last.route.name;
final showBottom = showBottomNavigation ??
AppNavigation.destinationPages.contains(routeName);
return Scaffold(
appBar: showAppBar
? AppBar(
title: Text(routeName ?? 'page'.tr),
centerTitle: false,
titleSpacing: canPop ? null : 24,
elevation: SolianTheme.isLargeScreen(context) ? 1 : 0,
leading: canPop ? const PrevPageButton() : null,
automaticallyImplyLeading: false,
)
: null,
bottomNavigationBar: (SolianTheme.isLargeScreen(context) ||
!(showNavigation && showBottom))
? null
: const AppNavigationBottomBar(),
body: SolianTheme.isLargeScreen(context)
? Row(
children: [
if (showNavigation) const AppNavigationRail(),
if (showNavigation)
const VerticalDivider(thickness: 0.3, width: 1),
if (showSidebar && sidebarFirst)
...buildContent(context).reversed
else if (showSidebar)
...buildContent(context)
else
Expanded(child: child),
],
)
: child,
);
}
}

View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
class CenteredContainer extends StatelessWidget {
final Widget child;
final double maxWidth;
const CenteredContainer({
super.key,
required this.child,
this.maxWidth = 720,
});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
constraints: BoxConstraints(maxWidth: maxWidth),
child: child,
),
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:solian/models/post.dart'; import 'package:solian/models/post.dart';
import 'package:solian/router.dart'; import 'package:solian/router.dart';
import 'package:solian/widgets/centered_container.dart';
import 'package:solian/widgets/posts/post_action.dart'; import 'package:solian/widgets/posts/post_action.dart';
import 'package:solian/widgets/posts/post_item.dart'; import 'package:solian/widgets/posts/post_item.dart';
@ -27,6 +28,7 @@ class PostListWidget extends StatelessWidget {
builderDelegate: PagedChildBuilderDelegate<Post>( builderDelegate: PagedChildBuilderDelegate<Post>(
itemBuilder: (context, item, index) { itemBuilder: (context, item, index) {
return RepaintBoundary( return RepaintBoundary(
child: CenteredContainer(
child: GestureDetector( child: GestureDetector(
child: PostItem( child: PostItem(
key: Key('p${item.alias}'), key: Key('p${item.alias}'),
@ -51,6 +53,7 @@ class PostListWidget extends StatelessWidget {
}); });
}, },
), ),
),
); );
}, },
), ),

View File

@ -83,6 +83,12 @@ PODS:
- WebRTC-SDK (= 114.5735.10) - WebRTC-SDK (= 114.5735.10)
- macos_window_utils (1.0.0): - macos_window_utils (1.0.0):
- FlutterMacOS - FlutterMacOS
- media_kit_libs_macos_video (1.0.4):
- FlutterMacOS
- media_kit_native_event_loop (1.0.0):
- FlutterMacOS
- media_kit_video (0.0.1):
- FlutterMacOS
- nanopb (2.30910.0): - nanopb (2.30910.0):
- nanopb/decode (= 2.30910.0) - nanopb/decode (= 2.30910.0)
- nanopb/encode (= 2.30910.0) - nanopb/encode (= 2.30910.0)
@ -96,14 +102,13 @@ PODS:
- PromisesObjC (2.4.0) - PromisesObjC (2.4.0)
- protocol_handler_macos (0.0.1): - protocol_handler_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- screen_brightness_macos (0.1.0):
- FlutterMacOS
- Sentry/HybridSDK (8.29.0) - Sentry/HybridSDK (8.29.0)
- sentry_flutter (8.3.0): - sentry_flutter (8.3.0):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- Sentry/HybridSDK (= 8.29.0) - Sentry/HybridSDK (= 8.29.0)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite (0.0.3): - sqflite (0.0.3):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
@ -111,9 +116,6 @@ PODS:
- FlutterMacOS - FlutterMacOS
- url_launcher_macos (0.0.1): - url_launcher_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- video_player_avfoundation (0.0.1):
- Flutter
- FlutterMacOS
- wakelock_plus (0.0.1): - wakelock_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
- WebRTC-SDK (114.5735.10) - WebRTC-SDK (114.5735.10)
@ -131,15 +133,17 @@ DEPENDENCIES:
- irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`)
- livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`) - livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`)
- macos_window_utils (from `Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos`) - macos_window_utils (from `Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos`)
- media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`)
- media_kit_native_event_loop (from `Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos`)
- media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- protocol_handler_macos (from `Flutter/ephemeral/.symlinks/plugins/protocol_handler_macos/macos`) - protocol_handler_macos (from `Flutter/ephemeral/.symlinks/plugins/protocol_handler_macos/macos`)
- screen_brightness_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos`)
- sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`) - sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
- super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`)
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`) - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
SPEC REPOS: SPEC REPOS:
@ -181,24 +185,28 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos :path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos
macos_window_utils: macos_window_utils:
:path: Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos :path: Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos
media_kit_libs_macos_video:
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos
media_kit_native_event_loop:
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos
media_kit_video:
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos
package_info_plus: package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation: path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
protocol_handler_macos: protocol_handler_macos:
:path: Flutter/ephemeral/.symlinks/plugins/protocol_handler_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/protocol_handler_macos/macos
screen_brightness_macos:
:path: Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos
sentry_flutter: sentry_flutter:
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos :path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite: sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin :path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin
super_native_extensions: super_native_extensions:
:path: Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos :path: Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos
url_launcher_macos: url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
video_player_avfoundation:
:path: Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin
wakelock_plus: wakelock_plus:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
@ -222,18 +230,20 @@ SPEC CHECKSUMS:
irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478
livekit_client: 9b39e0f1b8e1a8ec794bb72a4f9bbfc28c959ece livekit_client: 9b39e0f1b8e1a8ec794bb72a4f9bbfc28c959ece
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663 macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
media_kit_video: c75b07f14d59706c775778e4dd47dd027de8d1e5
nanopb: 438bc412db1928dac798aa6fd75726007be04262 nanopb: 438bc412db1928dac798aa6fd75726007be04262
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
protocol_handler_macos: d10a6c01d6373389ffd2278013ab4c47ed6d6daa protocol_handler_macos: d10a6c01d6373389ffd2278013ab4c47ed6d6daa
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
Sentry: 016de45ee5ce5fca2a829996f1bfafeb5e62e8b4 Sentry: 016de45ee5ce5fca2a829996f1bfafeb5e62e8b4
sentry_flutter: 5fb57c5b7e6427a9dc1fedde4269eb65823982d4 sentry_flutter: 5fb57c5b7e6427a9dc1fedde4269eb65823982d4
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
WebRTC-SDK: 8c0edd05b880a39648118192c252667ea06dea51 WebRTC-SDK: 8c0edd05b880a39648118192c252667ea06dea51