🐛 Fix title bar on macOS don't centered

This commit is contained in:
LittleSheep 2025-02-23 01:06:24 +08:00
parent 2188b8b2e2
commit 0424f98eb5
3 changed files with 153 additions and 70 deletions

View File

@ -43,8 +43,10 @@ class ExploreScreen extends StatefulWidget {
// Cuz the global key make the selected category not update to child widget when the category is changed. // Cuz the global key make the selected category not update to child widget when the category is changed.
SnPostCategory? _selectedCategory; SnPostCategory? _selectedCategory;
class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProviderStateMixin { class _ExploreScreenState extends State<ExploreScreen>
late final TabController _tabController = TabController(length: 4, vsync: this); with SingleTickerProviderStateMixin {
late final TabController _tabController =
TabController(length: 4, vsync: this);
final _fabKey = GlobalKey<ExpandableFabState>(); final _fabKey = GlobalKey<ExpandableFabState>();
final _listKeys = List.generate(4, (_) => GlobalKey<_PostListWidgetState>()); final _listKeys = List.generate(4, (_) => GlobalKey<_PostListWidgetState>());
@ -57,7 +59,10 @@ class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProvider
final sn = context.read<SnNetworkProvider>(); final sn = context.read<SnNetworkProvider>();
final resp = await sn.client.get('/cgi/co/categories?take=100'); final resp = await sn.client.get('/cgi/co/categories?take=100');
setState(() { setState(() {
_categories.addAll(resp.data.map((e) => SnPostCategory.fromJson(e)).cast<SnPostCategory>() ?? []); _categories.addAll(resp.data
.map((e) => SnPostCategory.fromJson(e))
.cast<SnPostCategory>() ??
[]);
}); });
} catch (err) { } catch (err) {
if (mounted) context.showErrorDialog(err); if (mounted) context.showErrorDialog(err);
@ -94,20 +99,27 @@ class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProvider
type: ExpandableFabType.up, type: ExpandableFabType.up,
childrenAnimation: ExpandableFabAnimation.none, childrenAnimation: ExpandableFabAnimation.none,
overlayStyle: ExpandableFabOverlayStyle( overlayStyle: ExpandableFabOverlayStyle(
color: Theme.of(context).colorScheme.surface.withAlpha((255 * 0.5).round()), color: Theme.of(context)
.colorScheme
.surface
.withAlpha((255 * 0.5).round()),
), ),
openButtonBuilder: RotateFloatingActionButtonBuilder( openButtonBuilder: RotateFloatingActionButtonBuilder(
child: const Icon(Symbols.add, size: 28), child: const Icon(Symbols.add, size: 28),
fabSize: ExpandableFabSize.regular, fabSize: ExpandableFabSize.regular,
foregroundColor: Theme.of(context).floatingActionButtonTheme.foregroundColor, foregroundColor:
backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, Theme.of(context).floatingActionButtonTheme.foregroundColor,
backgroundColor:
Theme.of(context).floatingActionButtonTheme.backgroundColor,
shape: const CircleBorder(), shape: const CircleBorder(),
), ),
closeButtonBuilder: DefaultFloatingActionButtonBuilder( closeButtonBuilder: DefaultFloatingActionButtonBuilder(
child: const Icon(Symbols.close, size: 28), child: const Icon(Symbols.close, size: 28),
fabSize: ExpandableFabSize.regular, fabSize: ExpandableFabSize.regular,
foregroundColor: Theme.of(context).floatingActionButtonTheme.foregroundColor, foregroundColor:
backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, Theme.of(context).floatingActionButtonTheme.foregroundColor,
backgroundColor:
Theme.of(context).floatingActionButtonTheme.backgroundColor,
shape: const CircleBorder(), shape: const CircleBorder(),
), ),
children: [ children: [
@ -241,13 +253,18 @@ class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProvider
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Icon(Symbols.globe, size: 20, color: Theme.of(context).appBarTheme.foregroundColor), Icon(Symbols.globe,
size: 20,
color: Theme.of(context)
.appBarTheme
.foregroundColor),
const Gap(8), const Gap(8),
Flexible( Flexible(
child: Text( child: Text(
'postChannelGlobal', 'postChannelGlobal',
maxLines: 1, maxLines: 1,
).tr().textColor(Theme.of(context).appBarTheme.foregroundColor), ).tr().textColor(
Theme.of(context).appBarTheme.foregroundColor),
), ),
], ],
), ),
@ -257,14 +274,19 @@ class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProvider
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Icon(Symbols.group, size: 20, color: Theme.of(context).appBarTheme.foregroundColor), Icon(Symbols.group,
size: 20,
color: Theme.of(context)
.appBarTheme
.foregroundColor),
const Gap(8), const Gap(8),
Flexible( Flexible(
child: Text( child: Text(
'postChannelFriends', 'postChannelFriends',
maxLines: 1, maxLines: 1,
textAlign: TextAlign.center, textAlign: TextAlign.center,
).tr().textColor(Theme.of(context).appBarTheme.foregroundColor), ).tr().textColor(
Theme.of(context).appBarTheme.foregroundColor),
), ),
], ],
), ),
@ -274,13 +296,18 @@ class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProvider
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Icon(Symbols.subscriptions, size: 20, color: Theme.of(context).appBarTheme.foregroundColor), Icon(Symbols.subscriptions,
size: 20,
color: Theme.of(context)
.appBarTheme
.foregroundColor),
const Gap(8), const Gap(8),
Flexible( Flexible(
child: Text( child: Text(
'postChannelFollowing', 'postChannelFollowing',
maxLines: 1, maxLines: 1,
).tr().textColor(Theme.of(context).appBarTheme.foregroundColor), ).tr().textColor(
Theme.of(context).appBarTheme.foregroundColor),
), ),
], ],
), ),
@ -290,13 +317,18 @@ class _ExploreScreenState extends State<ExploreScreen> with SingleTickerProvider
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Icon(Symbols.workspaces, size: 20, color: Theme.of(context).appBarTheme.foregroundColor), Icon(Symbols.workspaces,
size: 20,
color: Theme.of(context)
.appBarTheme
.foregroundColor),
const Gap(8), const Gap(8),
Flexible( Flexible(
child: Text( child: Text(
'postChannelRealm', 'postChannelRealm',
maxLines: 1, maxLines: 1,
).tr().textColor(Theme.of(context).appBarTheme.foregroundColor), ).tr().textColor(
Theme.of(context).appBarTheme.foregroundColor),
), ),
], ],
), ),
@ -341,7 +373,11 @@ class _PostListWidget extends StatefulWidget {
final bool withRealm; final bool withRealm;
final Function onClearFilter; final Function onClearFilter;
const _PostListWidget({super.key, this.channel, this.withRealm = false, required this.onClearFilter}); const _PostListWidget(
{super.key,
this.channel,
this.withRealm = false,
required this.onClearFilter});
@override @override
State<_PostListWidget> createState() => _PostListWidgetState(); State<_PostListWidget> createState() => _PostListWidgetState();
@ -420,11 +456,13 @@ class _PostListWidgetState extends State<_PostListWidget> {
content: Text( content: Text(
'postFilterWithCategory'.tr(args: [ 'postFilterWithCategory'.tr(args: [
'postCategory${_selectedCategory!.alias.capitalize()}'.trExists() 'postCategory${_selectedCategory!.alias.capitalize()}'.trExists()
? 'postCategory${_selectedCategory!.alias.capitalize()}'.tr() ? 'postCategory${_selectedCategory!.alias.capitalize()}'
.tr()
: _selectedCategory!.name, : _selectedCategory!.name,
]), ]),
), ),
leading: Icon(kCategoryIcons[_selectedCategory!.alias] ?? Symbols.question_mark), leading: Icon(kCategoryIcons[_selectedCategory!.alias] ??
Symbols.question_mark),
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Symbols.clear), icon: const Icon(Symbols.clear),
@ -486,7 +524,8 @@ class _PostListWidgetState extends State<_PostListWidget> {
itemCount: _posts.length, itemCount: _posts.length,
isLoading: _isBusy, isLoading: _isBusy,
centerLoading: true, centerLoading: true,
hasReachedMax: _postCount != null && _posts.length >= _postCount!, hasReachedMax:
_postCount != null && _posts.length >= _postCount!,
onFetchData: _fetchPosts, onFetchData: _fetchPosts,
itemBuilder: (context, idx) { itemBuilder: (context, idx) {
return OpenablePostItem( return OpenablePostItem(
@ -526,7 +565,9 @@ class _PostCategoryPickerPopup extends StatelessWidget {
children: [ children: [
const Icon(Symbols.category, size: 24), const Icon(Symbols.category, size: 24),
const Gap(16), const Gap(16),
Text('postCategory').tr().textStyle(Theme.of(context).textTheme.titleLarge!), Text('postCategory')
.tr()
.textStyle(Theme.of(context).textTheme.titleLarge!),
], ],
).padding(horizontal: 20, top: 16, bottom: 12), ).padding(horizontal: 20, top: 16, bottom: 12),
ListTile( ListTile(
@ -539,40 +580,46 @@ class _PostCategoryPickerPopup extends StatelessWidget {
}, },
), ),
const Divider(height: 1), const Divider(height: 1),
GridView.count( Expanded(
crossAxisCount: 4, child: GridView.count(
shrinkWrap: true, crossAxisCount: 4,
physics: const NeverScrollableScrollPhysics(), shrinkWrap: true,
childAspectRatio: 1, physics: const NeverScrollableScrollPhysics(),
children: categories childAspectRatio: 1,
.map( children: categories
(ele) => InkWell( .map(
onTap: () { (ele) => InkWell(
_selectedCategory = ele; onTap: () {
Navigator.pop(context, ele); _selectedCategory = ele;
}, Navigator.pop(context, ele);
child: Column( },
crossAxisAlignment: CrossAxisAlignment.center, child: Column(
mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center,
children: [ mainAxisSize: MainAxisSize.min,
Icon( children: [
kCategoryIcons[ele.alias] ?? Symbols.question_mark, Icon(
color: selected == ele ? Theme.of(context).colorScheme.primary : null, kCategoryIcons[ele.alias] ?? Symbols.question_mark,
), color: selected == ele
const Gap(4), ? Theme.of(context).colorScheme.primary
Text( : null,
'postCategory${ele.alias.capitalize()}'.trExists() ),
? 'postCategory${ele.alias.capitalize()}'.tr() const Gap(4),
: ele.name, Text(
) 'postCategory${ele.alias.capitalize()}'.trExists()
.textStyle(Theme.of(context).textTheme.titleMedium!) ? 'postCategory${ele.alias.capitalize()}'.tr()
.textColor(selected == ele ? Theme.of(context).colorScheme.primary : null), : ele.name,
], )
.textStyle(Theme.of(context).textTheme.titleMedium!)
.textColor(selected == ele
? Theme.of(context).colorScheme.primary
: null),
],
),
), ),
), )
) .toList(),
.toList(), ),
), ),
], ],
); );

View File

@ -61,7 +61,9 @@ class AppScaffold extends StatelessWidget {
isRoot: true, isRoot: true,
child: Column( child: Column(
children: [ children: [
IgnorePointer(child: SizedBox(height: appBar != null ? appBarHeight + safeTop : 0)), IgnorePointer(
child: SizedBox(
height: appBar != null ? appBarHeight + safeTop : 0)),
if (body != null) Expanded(child: body!), if (body != null) Expanded(child: body!),
], ],
), ),
@ -107,11 +109,19 @@ class AppRootScaffold extends StatelessWidget {
final isCollapseDrawer = cfg.drawerIsCollapsed; final isCollapseDrawer = cfg.drawerIsCollapsed;
final isExpandedDrawer = cfg.drawerIsExpanded; final isExpandedDrawer = cfg.drawerIsExpanded;
final routeName = GoRouter.of(context).routerDelegate.currentConfiguration.last.route.name; final routeName = GoRouter.of(context)
final isShowBottomNavigation = NavigationProvider.kShowBottomNavScreen.contains(routeName) .routerDelegate
? ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE) .currentConfiguration
: false; .last
final isPopable = !NavigationProvider.kAllDestination.map((ele) => ele.screen).contains(routeName); .route
.name;
final isShowBottomNavigation =
NavigationProvider.kShowBottomNavScreen.contains(routeName)
? ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE)
: false;
final isPopable = !NavigationProvider.kAllDestination
.map((ele) => ele.screen)
.contains(routeName);
final innerWidget = isCollapseDrawer final innerWidget = isCollapseDrawer
? body ? body
@ -126,7 +136,9 @@ class AppRootScaffold extends StatelessWidget {
), ),
), ),
), ),
child: isExpandedDrawer ? AppNavigationDrawer(elevation: 0) : AppRailNavigation(), child: isExpandedDrawer
? AppNavigationDrawer(elevation: 0)
: AppRailNavigation(),
), ),
Expanded(child: body), Expanded(child: body),
], ],
@ -150,7 +162,8 @@ class AppRootScaffold extends StatelessWidget {
children: [ children: [
Column( Column(
children: [ children: [
if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) if (!kIsWeb &&
(Platform.isWindows || Platform.isLinux || Platform.isMacOS))
WindowTitleBarBox( WindowTitleBarBox(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@ -164,12 +177,19 @@ class AppRootScaffold extends StatelessWidget {
child: MoveWindow( child: MoveWindow(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: Platform.isMacOS ? MainAxisAlignment.center : MainAxisAlignment.start, mainAxisAlignment: Platform.isMacOS
? MainAxisAlignment.center
: MainAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
'Solar Network', 'Solar Network',
style: GoogleFonts.spaceGrotesk(), style: GoogleFonts.spaceGrotesk(),
textAlign: !kIsWeb
? Platform.isMacOS
? TextAlign.center
: null
: null,
).padding(horizontal: 12, vertical: 5), ).padding(horizontal: 12, vertical: 5),
), ),
if (!Platform.isMacOS) if (!Platform.isMacOS)
@ -179,9 +199,12 @@ class AppRootScaffold extends StatelessWidget {
Expanded(child: MoveWindow()), Expanded(child: MoveWindow()),
Row( Row(
children: [ children: [
MinimizeWindowButton(colors: windowButtonColor), MinimizeWindowButton(
MaximizeWindowButton(colors: windowButtonColor), colors: windowButtonColor),
CloseWindowButton(colors: windowButtonColor), MaximizeWindowButton(
colors: windowButtonColor),
CloseWindowButton(
colors: windowButtonColor),
], ],
), ),
], ],
@ -194,16 +217,28 @@ class AppRootScaffold extends StatelessWidget {
Expanded(child: innerWidget), Expanded(child: innerWidget),
], ],
), ),
Positioned(top: safeTop > 0 ? safeTop : 16, right: 8, child: NotifyIndicator()), Positioned(
top: safeTop > 0 ? safeTop : 16,
right: 8,
child: NotifyIndicator()),
if (ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE)) if (ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE))
Positioned(bottom: safeBottom > 0 ? safeBottom : 16, left: 0, right: 0, child: ConnectionIndicator()) Positioned(
bottom: safeBottom > 0 ? safeBottom : 16,
left: 0,
right: 0,
child: ConnectionIndicator())
else else
Positioned(top: safeTop > 0 ? safeTop : 16, left: 0, right: 0, child: ConnectionIndicator()), Positioned(
top: safeTop > 0 ? safeTop : 16,
left: 0,
right: 0,
child: ConnectionIndicator()),
], ],
), ),
drawer: !isExpandedDrawer ? AppNavigationDrawer() : null, drawer: !isExpandedDrawer ? AppNavigationDrawer() : null,
drawerEdgeDragWidth: isPopable ? 0 : null, drawerEdgeDragWidth: isPopable ? 0 : null,
bottomNavigationBar: isShowBottomNavigation ? AppBottomNavigationBar() : null, bottomNavigationBar:
isShowBottomNavigation ? AppBottomNavigationBar() : null,
); );
} }
} }

View File

@ -59,6 +59,7 @@
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES" debugDocumentVersioning = "YES"
debugServiceExtension = "internal" debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES"> allowLocationSimulation = "YES">
<BuildableProductRunnable <BuildableProductRunnable
runnableDebuggingMode = "0"> runnableDebuggingMode = "0">