Compare commits
2 Commits
43242de659
...
b913c6a432
| Author | SHA1 | Date | |
|---|---|---|---|
| b913c6a432 | |||
| 977cc2e524 |
189
lib/router.dart
189
lib/router.dart
@@ -17,48 +17,48 @@ import 'package:solian/screens/social.dart';
|
||||
import 'package:solian/screens/posts/post_publish.dart';
|
||||
import 'package:solian/shells/basic_shell.dart';
|
||||
import 'package:solian/shells/nav_shell.dart';
|
||||
import 'package:solian/shells/title_shell.dart';
|
||||
import 'package:solian/theme.dart';
|
||||
import 'package:solian/widgets/sidebar/empty_placeholder.dart';
|
||||
|
||||
abstract class AppRouter {
|
||||
static GoRouter instance = GoRouter(
|
||||
routes: [
|
||||
ShellRoute(
|
||||
builder: (context, state, child) =>
|
||||
NavShell(state: state, showAppBar: false, child: child),
|
||||
builder: (context, state, child) => NavShell(
|
||||
state: state,
|
||||
showAppBar: false,
|
||||
showSidebar: false,
|
||||
child: child,
|
||||
),
|
||||
routes: [
|
||||
ShellRoute(
|
||||
builder: (context, state, child) => BasicShell(
|
||||
state: state,
|
||||
sidebarFirst: true,
|
||||
showAppBar: false,
|
||||
sidebar: const SocialScreen(),
|
||||
child: child,
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
name: 'social',
|
||||
builder: (context, state) => const SocialScreen(),
|
||||
builder: (context, state) =>
|
||||
SolianTheme.isExtraLargeScreen(context)
|
||||
? const EmptyPagePlaceholder()
|
||||
: const SocialScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/chat',
|
||||
name: 'chat',
|
||||
builder: (context, state) => const ChatScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/realms',
|
||||
name: 'realms',
|
||||
builder: (context, state) => const RealmListScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/account',
|
||||
name: 'account',
|
||||
builder: (context, state) => const AccountScreen(),
|
||||
),
|
||||
],
|
||||
),
|
||||
ShellRoute(
|
||||
builder: (context, state, child) =>
|
||||
BasicShell(state: state, child: child),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/posts/view/:alias',
|
||||
name: 'postDetail',
|
||||
builder: (context, state) => PostDetailScreen(
|
||||
builder: (context, state) => TitleShell(
|
||||
showAppBar: SolianTheme.isExtraLargeScreen(context),
|
||||
state: state,
|
||||
child: PostDetailScreen(
|
||||
alias: state.pathParameters['alias']!,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: '/posts/publish',
|
||||
@@ -73,44 +73,24 @@ abstract class AppRouter {
|
||||
);
|
||||
},
|
||||
),
|
||||
ShellRoute(
|
||||
builder: (context, state, child) =>
|
||||
BasicShell(state: state, child: child),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/account/friend',
|
||||
name: 'accountFriend',
|
||||
builder: (context, state) => const FriendScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/account/personalize',
|
||||
name: 'accountPersonalize',
|
||||
builder: (context, state) => const PersonalizeScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
builder: (context, state) => const AboutScreen(),
|
||||
),
|
||||
],
|
||||
),
|
||||
ShellRoute(
|
||||
builder: (context, state, child) =>
|
||||
BasicShell(state: state, child: child),
|
||||
builder: (context, state, child) => BasicShell(
|
||||
state: state,
|
||||
sidebarFirst: true,
|
||||
showAppBar: false,
|
||||
sidebar: const ChatScreen(),
|
||||
child: child,
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/chat/:alias/detail',
|
||||
name: 'channelDetail',
|
||||
builder: (context, state) {
|
||||
final arguments = state.extra as ChannelDetailArguments;
|
||||
return ChannelDetailScreen(
|
||||
channel: arguments.channel,
|
||||
profile: arguments.profile,
|
||||
realm: state.uri.queryParameters['realm'] ?? 'global',
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
path: '/chat',
|
||||
name: 'chat',
|
||||
builder: (context, state) =>
|
||||
SolianTheme.isExtraLargeScreen(context)
|
||||
? const EmptyPagePlaceholder()
|
||||
: const ChatScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/chat/organize',
|
||||
@@ -133,19 +113,52 @@ abstract class AppRouter {
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/chat/:alias/detail',
|
||||
name: 'channelDetail',
|
||||
builder: (context, state) {
|
||||
final arguments = state.extra as ChannelDetailArguments;
|
||||
return TitleShell(
|
||||
showAppBar: SolianTheme.isExtraLargeScreen(context),
|
||||
state: state,
|
||||
child: ChannelDetailScreen(
|
||||
channel: arguments.channel,
|
||||
profile: arguments.profile,
|
||||
realm: state.uri.queryParameters['realm'] ?? 'global',
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
ShellRoute(
|
||||
builder: (context, state, child) =>
|
||||
BasicShell(state: state, child: child),
|
||||
builder: (context, state, child) => BasicShell(
|
||||
state: state,
|
||||
sidebarFirst: true,
|
||||
showAppBar: false,
|
||||
sidebar: const RealmListScreen(),
|
||||
child: child,
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/realms',
|
||||
name: 'realms',
|
||||
builder: (context, state) =>
|
||||
SolianTheme.isExtraLargeScreen(context)
|
||||
? const EmptyPagePlaceholder()
|
||||
: const RealmListScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/realms/:alias/detail',
|
||||
name: 'realmDetail',
|
||||
builder: (context, state) => RealmDetailScreen(
|
||||
builder: (context, state) => TitleShell(
|
||||
showAppBar: SolianTheme.isExtraLargeScreen(context),
|
||||
state: state,
|
||||
child: RealmDetailScreen(
|
||||
realm: state.extra as Realm,
|
||||
alias: state.pathParameters['alias']!,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: '/realm/organize',
|
||||
@@ -167,5 +180,55 @@ abstract class AppRouter {
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
ShellRoute(
|
||||
builder: (context, state, child) => BasicShell(
|
||||
state: state,
|
||||
sidebarFirst: true,
|
||||
showAppBar: false,
|
||||
sidebar: const AccountScreen(),
|
||||
child: child,
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/account',
|
||||
name: 'account',
|
||||
builder: (context, state) =>
|
||||
SolianTheme.isExtraLargeScreen(context)
|
||||
? const EmptyPagePlaceholder()
|
||||
: const AccountScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/account/friend',
|
||||
name: 'accountFriend',
|
||||
builder: (context, state) => TitleShell(
|
||||
showAppBar: SolianTheme.isExtraLargeScreen(context),
|
||||
state: state,
|
||||
child: const FriendScreen(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/account/personalize',
|
||||
name: 'accountPersonalize',
|
||||
builder: (context, state) => TitleShell(
|
||||
showAppBar: SolianTheme.isExtraLargeScreen(context),
|
||||
state: state,
|
||||
child: const PersonalizeScreen(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
builder: (context, state) => TitleShell(
|
||||
showAppBar: SolianTheme.isExtraLargeScreen(context),
|
||||
state: state,
|
||||
child: const AboutScreen(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class AboutScreen extends StatelessWidget {
|
||||
|
||||
return Material(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@@ -64,6 +66,7 @@ class AboutScreen extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,26 +5,62 @@ 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';
|
||||
import 'package:solian/widgets/sidebar/sidebar_placeholder.dart';
|
||||
|
||||
class BasicShell extends StatelessWidget {
|
||||
final bool showAppBar;
|
||||
final GoRouterState state;
|
||||
final Widget child;
|
||||
|
||||
const BasicShell({super.key, required this.child, required this.state});
|
||||
final bool sidebarFirst;
|
||||
final Widget? sidebar;
|
||||
|
||||
const BasicShell({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.state,
|
||||
this.showAppBar = true,
|
||||
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();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
appBar: showAppBar
|
||||
? AppBar(
|
||||
title: AppBarTitle(state.topRoute?.name?.tr ?? 'page'.tr),
|
||||
centerTitle: false,
|
||||
toolbarHeight: SolianTheme.toolbarHeight(context),
|
||||
leading: canPop ? const PrevPageButton() : null,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
body: child,
|
||||
)
|
||||
: null,
|
||||
body: SolianTheme.isLargeScreen(context)
|
||||
? Row(
|
||||
children: sidebarFirst
|
||||
? buildContent(context).reversed.toList()
|
||||
: buildContent(context),
|
||||
)
|
||||
: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,39 @@ import 'package:solian/widgets/sidebar/sidebar_placeholder.dart';
|
||||
|
||||
class NavShell extends StatelessWidget {
|
||||
final bool showAppBar;
|
||||
final bool showSidebar;
|
||||
final GoRouterState state;
|
||||
final Widget child;
|
||||
|
||||
final bool sidebarFirst;
|
||||
final Widget? sidebar;
|
||||
|
||||
const NavShell({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.state,
|
||||
this.showAppBar = true,
|
||||
this.showSidebar = true,
|
||||
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();
|
||||
@@ -43,17 +66,12 @@ class NavShell extends StatelessWidget {
|
||||
children: [
|
||||
const AppNavigationRail(),
|
||||
const VerticalDivider(thickness: 0.3, width: 1),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: child,
|
||||
),
|
||||
if (SolianTheme.isExtraLargeScreen(context))
|
||||
const VerticalDivider(thickness: 0.3, width: 1),
|
||||
if (SolianTheme.isExtraLargeScreen(context))
|
||||
const Flexible(
|
||||
flex: 1,
|
||||
child: SidebarPlaceholder(),
|
||||
),
|
||||
if (showSidebar && sidebarFirst)
|
||||
...buildContent(context).reversed
|
||||
else if (showSidebar)
|
||||
...buildContent(context)
|
||||
else
|
||||
Expanded(child: child),
|
||||
],
|
||||
)
|
||||
: child,
|
||||
|
||||
38
lib/shells/title_shell.dart
Normal file
38
lib/shells/title_shell.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
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 TitleShell extends StatelessWidget {
|
||||
final bool showAppBar;
|
||||
final GoRouterState state;
|
||||
final Widget child;
|
||||
|
||||
const TitleShell({
|
||||
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: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class SolianMessages extends Translations {
|
||||
'postInRealm': 'In realm @realm',
|
||||
'postDetail': 'Post',
|
||||
'postReplies': 'Replies',
|
||||
'postPublishing': 'Post post',
|
||||
'postPublishing': 'Post a post',
|
||||
'postIdentityNotify': 'You will post this post as',
|
||||
'postContentPlaceholder': 'What\'s happened?!',
|
||||
'postReaction': 'Reactions of the Post',
|
||||
@@ -202,8 +202,6 @@ class SolianMessages extends Translations {
|
||||
'callParticipantVideoOff': 'Turn Off Participant Video',
|
||||
'callParticipantVideoOn': 'Turn On Participant Video',
|
||||
'callAlreadyOngoing': 'A call is already ongoing',
|
||||
'sidebarPlaceholder':
|
||||
'Your screen is really too large, so we had to leave some space here to prevent the layout from being too messy. In the future, we will add some small widgets here for wealthy users like you to enjoy, but for now, it will stay this way.',
|
||||
'badge': 'Badge',
|
||||
'badges': 'Badges',
|
||||
'badgeGrantAt': 'Badge awarded on @date',
|
||||
@@ -417,8 +415,6 @@ class SolianMessages extends Translations {
|
||||
'callParticipantVideoOff': '静音参与者',
|
||||
'callParticipantVideoOn': '解除静音参与者',
|
||||
'callAlreadyOngoing': '当前正在进行一则通话',
|
||||
'sidebarPlaceholder':
|
||||
'你的屏幕真的太大啦,我们只好空出一块地方好让布局不那么混乱,未来我们会在此处加入一下小挂件来供你这样的富人玩乐,但现在就这样吧。',
|
||||
'badge': '徽章',
|
||||
'badges': '徽章',
|
||||
'badgeGrantAt': '徽章颁发于 @date',
|
||||
|
||||
15
lib/widgets/sidebar/empty_placeholder.dart
Normal file
15
lib/widgets/sidebar/empty_placeholder.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EmptyPagePlaceholder extends StatelessWidget {
|
||||
const EmptyPagePlaceholder({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Center(
|
||||
child: Image.asset('assets/logo.png', width: 80, height: 80),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class SidebarPlaceholder extends StatelessWidget {
|
||||
const SidebarPlaceholder({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 280),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.menu_open, size: 48),
|
||||
const SizedBox(height: 8),
|
||||
Text('sidebarPlaceholder'.tr, textAlign: TextAlign.center),
|
||||
],
|
||||
),
|
||||
return Material(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: const Center(
|
||||
child: Icon(Icons.menu_open, size: 50),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user