diff --git a/lib/router.dart b/lib/router.dart index bce7ee0..ee1d2ed 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -26,16 +26,52 @@ import 'package:solian/widgets/layouts/two_column.dart'; abstract class SolianRouter { static final router = GoRouter( routes: [ - GoRoute( - path: '/', - name: 'explore', - builder: (context, state) => const ExploreScreen(), - ), GoRoute( path: '/notification', name: 'notification', builder: (context, state) => const NotificationScreen(), ), + ShellRoute( + pageBuilder: (context, state, child) => defaultPageBuilder( + context, + state, + SolianTheme.isLargeScreen(context) + ? TwoColumnLayout( + sideChild: const ExplorePostScreen(), + mainChild: child, + ) + : child, + ), + routes: [ + GoRoute( + path: '/', + name: 'explore', + builder: (context, state) => + !SolianTheme.isLargeScreen(context) ? const ExplorePostScreen() : const PageEmptyWidget(), + ), + GoRoute( + path: '/posts/publish/moments', + name: 'posts.moments.editor', + builder: (context, state) => MomentEditorScreen(editing: state.extra as Post?), + ), + GoRoute( + path: '/posts/publish/comments', + name: 'posts.comments.editor', + builder: (context, state) { + final args = state.extra as CommentPostArguments; + return CommentEditorScreen(editing: args.editing, related: args.related); + }, + ), + GoRoute( + path: '/posts/:dataset/:alias', + name: 'posts.screen', + builder: (context, state) => PostScreen( + alias: state.pathParameters['alias'] as String, + dataset: state.pathParameters['dataset'] as String, + ), + ), + ], + ), ShellRoute( pageBuilder: (context, state, child) => defaultPageBuilder( context, @@ -81,52 +117,45 @@ abstract class SolianRouter { ), ], ), - GoRoute( - path: '/account', - name: 'account', - builder: (context, state) => const AccountScreen(), - ), - GoRoute( - path: '/posts/publish/moments', - name: 'posts.moments.editor', - builder: (context, state) => MomentEditorScreen(editing: state.extra as Post?), - ), - GoRoute( - path: '/posts/publish/comments', - name: 'posts.comments.editor', - builder: (context, state) { - final args = state.extra as CommentPostArguments; - return CommentEditorScreen(editing: args.editing, related: args.related); - }, - ), - GoRoute( - path: '/posts/:dataset/:alias', - name: 'posts.screen', - builder: (context, state) => PostScreen( - alias: state.pathParameters['alias'] as String, - dataset: state.pathParameters['dataset'] as String, - ), - ), - GoRoute( - path: '/auth/sign-in', - name: 'auth.sign-in', - builder: (context, state) => SignInScreen(), - ), - GoRoute( - path: '/auth/sign-up', - name: 'auth.sign-up', - builder: (context, state) => SignUpScreen(), - ), - GoRoute( - path: '/account/friend', - name: 'account.friend', - builder: (context, state) => const FriendScreen(), - ), - GoRoute( - path: '/account/personalize', - name: 'account.personalize', - builder: (context, state) => const PersonalizeScreen(), - ), + ShellRoute( + pageBuilder: (context, state, child) => defaultPageBuilder( + context, + state, + SolianTheme.isLargeScreen(context) + ? TwoColumnLayout( + sideChild: const AccountScreen(), + mainChild: child, + ) + : child, + ), + routes: [ + GoRoute( + path: '/account', + name: 'account', + builder: (context, state) => + !SolianTheme.isLargeScreen(context) ? const AccountScreen() : const PageEmptyWidget(), + ), + GoRoute( + path: '/auth/sign-in', + name: 'auth.sign-in', + builder: (context, state) => SignInScreen(), + ), + GoRoute( + path: '/auth/sign-up', + name: 'auth.sign-up', + builder: (context, state) => SignUpScreen(), + ), + GoRoute( + path: '/account/friend', + name: 'account.friend', + builder: (context, state) => const FriendScreen(), + ), + GoRoute( + path: '/account/personalize', + name: 'account.personalize', + builder: (context, state) => const PersonalizeScreen(), + ), + ]), ], ); diff --git a/lib/screens/account.dart b/lib/screens/account.dart index 552475c..d520de3 100644 --- a/lib/screens/account.dart +++ b/lib/screens/account.dart @@ -2,73 +2,30 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:solian/providers/auth.dart'; import 'package:solian/router.dart'; -import 'package:solian/screens/account/friend.dart'; -import 'package:solian/screens/account/personalize.dart'; import 'package:solian/widgets/account/account_avatar.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:solian/widgets/empty.dart'; import 'package:solian/widgets/scaffold.dart'; -class AccountScreen extends StatefulWidget { +class AccountScreen extends StatelessWidget { const AccountScreen({super.key}); - @override - State createState() => _AccountScreenState(); -} - -class _AccountScreenState extends State { - String? _title; - String? _selectedTab; - @override Widget build(BuildContext context) { - final screenWidth = MediaQuery.of(context).size.width; - final isLargeScreen = screenWidth >= 600; - - Widget renderContent() { - switch (_selectedTab) { - case 'account.friend': - return const FriendScreenWidget(); - case 'account.personalize': - return const PersonalizeScreenWidget(); - default: - return const PageEmptyWidget(); - } - } - return IndentScaffold( - title: _title ?? AppLocalizations.of(context)!.account, + title: AppLocalizations.of(context)!.account, noSafeArea: true, fixedAppBarColor: true, - child: isLargeScreen - ? Row( - children: [ - Flexible( - flex: 2, - child: AccountScreenWidget( - onSelect: (item, title) { - setState(() { - _selectedTab = item; - _title = title; - }); - }, - ), - ), - const VerticalDivider(thickness: 0.3, width: 0.3), - Flexible(flex: 4, child: renderContent()), - ], - ) - : AccountScreenWidget( - onSelect: (item, _) { - SolianRouter.router.pushNamed(item); - }, - ), + child: AccountScreenWidget( + onSelect: (item) { + SolianRouter.router.pushNamed(item); + }, + ), ); } } class AccountScreenWidget extends StatefulWidget { - final Function(String item, String title) onSelect; + final Function(String item) onSelect; const AccountScreenWidget({super.key, required this.onSelect}); @@ -105,7 +62,7 @@ class _AccountScreenWidgetState extends State { leading: const Icon(Icons.color_lens), title: Text(AppLocalizations.of(context)!.personalize), onTap: () { - widget.onSelect('account.personalize', AppLocalizations.of(context)!.personalize); + widget.onSelect('account.personalize'); }, ), ListTile( @@ -113,7 +70,7 @@ class _AccountScreenWidgetState extends State { leading: const Icon(Icons.diversity_1), title: Text(AppLocalizations.of(context)!.friend), onTap: () { - widget.onSelect('account.friend', AppLocalizations.of(context)!.friend); + widget.onSelect('account.friend'); }, ), ListTile( diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index e1f8d49..19a7bb9 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -6,85 +6,50 @@ import 'package:solian/models/pagination.dart'; import 'package:solian/models/post.dart'; import 'package:solian/providers/auth.dart'; import 'package:solian/router.dart'; -import 'package:solian/screens/posts/screen.dart'; import 'package:solian/utils/service_url.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:http/http.dart' as http; -import 'package:solian/widgets/empty.dart'; +import 'package:solian/utils/theme.dart'; import 'package:solian/widgets/scaffold.dart'; import 'package:solian/widgets/notification_notifier.dart'; import 'package:solian/widgets/posts/post.dart'; -class ExploreScreen extends StatefulWidget { - const ExploreScreen({super.key}); - - @override - State createState() => _ExploreScreenState(); -} - -class _ExploreScreenState extends State { - Post? _selectedPost; +class ExplorePostScreen extends StatelessWidget { + const ExplorePostScreen({super.key}); @override Widget build(BuildContext context) { - final screenWidth = MediaQuery.of(context).size.width; - final isLargeScreen = screenWidth >= 600; - return IndentScaffold( noSafeArea: true, - fixedAppBarColor: isLargeScreen, + fixedAppBarColor: SolianTheme.isLargeScreen(context), appBarActions: const [NotificationButton()], title: AppLocalizations.of(context)!.explore, - child: isLargeScreen - ? Row( - children: [ - Flexible( - flex: 2, - child: ExploreScreenWidget( - onSelect: (item) { - setState(() => _selectedPost = item); - }, - ), - ), - const VerticalDivider(thickness: 0.3, width: 0.3), - Flexible( - flex: 4, - child: _selectedPost == null - ? const PageEmptyWidget() - : PostScreenWidget( - key: Key('p${_selectedPost!.id}'), - dataset: _selectedPost!.dataset, - alias: _selectedPost!.alias, - ), - ), - ], - ) - : ExploreScreenWidget( - onSelect: (item) { - SolianRouter.router.pushNamed( - 'posts.screen', - pathParameters: { - 'alias': item.alias, - 'dataset': item.dataset, - }, - ); - }, - ), + child: ExplorePostWidget( + onSelect: (item) { + SolianRouter.router.pushNamed( + 'posts.screen', + pathParameters: { + 'alias': item.alias, + 'dataset': item.dataset, + }, + ); + }, + ), ); } } -class ExploreScreenWidget extends StatefulWidget { +class ExplorePostWidget extends StatefulWidget { final Function(Post item) onSelect; - const ExploreScreenWidget({super.key, required this.onSelect}); + const ExplorePostWidget({super.key, required this.onSelect}); @override - State createState() => _ExploreScreenWidgetState(); + State createState() => _ExplorePostWidgetState(); } -class _ExploreScreenWidgetState extends State { +class _ExplorePostWidgetState extends State { final PagingController _pagingController = PagingController(firstPageKey: 0); final http.Client _client = http.Client(); diff --git a/lib/widgets/posts/post.dart b/lib/widgets/posts/post.dart index b0797dc..333a239 100644 --- a/lib/widgets/posts/post.dart +++ b/lib/widgets/posts/post.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:solian/models/post.dart'; +import 'package:solian/utils/theme.dart'; import 'package:solian/widgets/account/account_avatar.dart'; import 'package:solian/widgets/posts/comment_list.dart'; import 'package:solian/widgets/posts/content/article.dart'; @@ -87,16 +88,13 @@ class _PostItemState extends State { Widget renderAttachments() { if (widget.item.modelType == 'article') return Container(); - final screenWidth = MediaQuery.of(context).size.width; - final isLargeScreen = screenWidth >= 600; - if (widget.item.attachments != null && widget.item.attachments!.isNotEmpty) { return Padding( padding: const EdgeInsets.only(top: 8), child: AttachmentList( items: widget.item.attachments!, provider: 'interactive', - noTag: isLargeScreen && widget.brief, + noTag: SolianTheme.isLargeScreen(context) && widget.brief, ), ); } else {