✨ Better post list
This commit is contained in:
parent
66ddfea68d
commit
343b84e3e1
@ -40,20 +40,12 @@ abstract class AppRouter {
|
||||
);
|
||||
|
||||
static final ShellRoute _feedRoute = ShellRoute(
|
||||
builder: (context, state, child) => BasicShell(
|
||||
state: state,
|
||||
sidebarFirst: true,
|
||||
showAppBar: false,
|
||||
sidebar: const FeedScreen(),
|
||||
child: child,
|
||||
),
|
||||
builder: (context, state, child) => child,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
name: 'feed',
|
||||
builder: (context, state) => SolianTheme.isExtraLargeScreen(context)
|
||||
? const EmptyPagePlaceholder()
|
||||
: const FeedScreen(),
|
||||
builder: (context, state) => const FeedScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/posts/view/:alias',
|
||||
|
@ -3,6 +3,7 @@ import 'package:get/get.dart';
|
||||
import 'package:solian/exts.dart';
|
||||
import 'package:solian/models/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_replies.dart';
|
||||
|
||||
@ -47,21 +48,29 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: PostItem(
|
||||
item: item!,
|
||||
isClickable: true,
|
||||
isFullDate: true,
|
||||
isShowReply: false,
|
||||
child: CenteredContainer(
|
||||
child: PostItem(
|
||||
item: item!,
|
||||
isClickable: true,
|
||||
isFullDate: true,
|
||||
isShowReply: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(thickness: 0.3, height: 0.3),
|
||||
SliverToBoxAdapter(
|
||||
child: const Divider(thickness: 0.3, height: 1)
|
||||
.paddingOnly(top: 4),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: Text(
|
||||
'postReplies'.tr,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 16),
|
||||
child: CenteredContainer(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'postReplies'.tr,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
PostReplyList(item: item!),
|
||||
SliverToBoxAdapter(
|
||||
|
43
lib/shells/centered_shell.dart
Normal file
43
lib/shells/centered_shell.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
22
lib/widgets/centered_container.dart
Normal file
22
lib/widgets/centered_container.dart
Normal 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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import 'package:get/get.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:solian/models/post.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_item.dart';
|
||||
|
||||
@ -27,29 +28,31 @@ class PostListWidget extends StatelessWidget {
|
||||
builderDelegate: PagedChildBuilderDelegate<Post>(
|
||||
itemBuilder: (context, item, index) {
|
||||
return RepaintBoundary(
|
||||
child: GestureDetector(
|
||||
child: PostItem(
|
||||
key: Key('p${item.alias}'),
|
||||
item: item,
|
||||
isShowEmbed: isShowEmbed,
|
||||
isClickable: isNestedClickable,
|
||||
).paddingSymmetric(vertical: 8),
|
||||
onTap: () {
|
||||
if (!isClickable) return;
|
||||
AppRouter.instance.pushNamed(
|
||||
'postDetail',
|
||||
pathParameters: {'alias': item.alias},
|
||||
);
|
||||
},
|
||||
onLongPress: () {
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) => PostAction(item: item),
|
||||
).then((value) {
|
||||
if (value != null) controller.refresh();
|
||||
});
|
||||
},
|
||||
child: CenteredContainer(
|
||||
child: GestureDetector(
|
||||
child: PostItem(
|
||||
key: Key('p${item.alias}'),
|
||||
item: item,
|
||||
isShowEmbed: isShowEmbed,
|
||||
isClickable: isNestedClickable,
|
||||
).paddingSymmetric(vertical: 8),
|
||||
onTap: () {
|
||||
if (!isClickable) return;
|
||||
AppRouter.instance.pushNamed(
|
||||
'postDetail',
|
||||
pathParameters: {'alias': item.alias},
|
||||
);
|
||||
},
|
||||
onLongPress: () {
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) => PostAction(item: item),
|
||||
).then((value) {
|
||||
if (value != null) controller.refresh();
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -83,6 +83,12 @@ PODS:
|
||||
- WebRTC-SDK (= 114.5735.10)
|
||||
- macos_window_utils (1.0.0):
|
||||
- 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/decode (= 2.30910.0)
|
||||
- nanopb/encode (= 2.30910.0)
|
||||
@ -96,14 +102,13 @@ PODS:
|
||||
- PromisesObjC (2.4.0)
|
||||
- protocol_handler_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- screen_brightness_macos (0.1.0):
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (8.29.0)
|
||||
- sentry_flutter (8.3.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (= 8.29.0)
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- sqflite (0.0.3):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
@ -111,9 +116,6 @@ PODS:
|
||||
- FlutterMacOS
|
||||
- url_launcher_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- video_player_avfoundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- wakelock_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- WebRTC-SDK (114.5735.10)
|
||||
@ -131,15 +133,17 @@ DEPENDENCIES:
|
||||
- irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`)
|
||||
- livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/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`)
|
||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- 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`)
|
||||
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
|
||||
- super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/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`)
|
||||
|
||||
SPEC REPOS:
|
||||
@ -181,24 +185,28 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos
|
||||
macos_window_utils:
|
||||
: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:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||
path_provider_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
||||
protocol_handler_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/protocol_handler_macos/macos
|
||||
screen_brightness_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos
|
||||
sentry_flutter:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
|
||||
shared_preferences_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
|
||||
sqflite:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin
|
||||
super_native_extensions:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos
|
||||
url_launcher_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||
video_player_avfoundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin
|
||||
wakelock_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
|
||||
|
||||
@ -222,18 +230,20 @@ SPEC CHECKSUMS:
|
||||
irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478
|
||||
livekit_client: 9b39e0f1b8e1a8ec794bb72a4f9bbfc28c959ece
|
||||
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
||||
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
||||
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
||||
media_kit_video: c75b07f14d59706c775778e4dd47dd027de8d1e5
|
||||
nanopb: 438bc412db1928dac798aa6fd75726007be04262
|
||||
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
protocol_handler_macos: d10a6c01d6373389ffd2278013ab4c47ed6d6daa
|
||||
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
|
||||
Sentry: 016de45ee5ce5fca2a829996f1bfafeb5e62e8b4
|
||||
sentry_flutter: 5fb57c5b7e6427a9dc1fedde4269eb65823982d4
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||
super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3
|
||||
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
|
||||
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
|
||||
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
|
||||
WebRTC-SDK: 8c0edd05b880a39648118192c252667ea06dea51
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user