diff --git a/lib/components/grid.dart b/lib/components/grid.dart index e2dc809..efb9016 100644 --- a/lib/components/grid.dart +++ b/lib/components/grid.dart @@ -1,4 +1,5 @@ import 'package:flutter/widgets.dart'; +import 'package:pixes/foundation/app.dart'; class SliverGridViewWithFixedItemHeight extends StatelessWidget { const SliverGridViewWithFixedItemHeight( @@ -22,7 +23,7 @@ class SliverGridViewWithFixedItemHeight extends StatelessWidget { maxCrossAxisExtent: maxCrossAxisExtent, childAspectRatio: calcChildAspectRatio(constraints.crossAxisExtent)), - ))); + ).sliverPadding(EdgeInsets.only(bottom: context.padding.bottom)))); } double calcChildAspectRatio(double width) { @@ -61,6 +62,7 @@ class GridViewWithFixedItemHeight extends StatelessWidget { calcChildAspectRatio(constraints.maxWidth)), itemBuilder: builder, itemCount: itemCount, + padding: EdgeInsets.only(bottom: context.padding.bottom), ))); } diff --git a/lib/foundation/navigation.dart b/lib/foundation/navigation.dart index 1c78a49..e040e45 100644 --- a/lib/foundation/navigation.dart +++ b/lib/foundation/navigation.dart @@ -16,4 +16,8 @@ extension Navigation on BuildContext { void showToast({required String message, IconData? icon}) { overlay.showToast(this, message: message, icon: icon); } + + Size get size => MediaQuery.of(this).size; + + EdgeInsets get padding => MediaQuery.of(this).padding; } diff --git a/lib/main.dart b/lib/main.dart index df09fa0..978d47a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import "package:fluent_ui/fluent_ui.dart"; +import "package:flutter/services.dart"; import "package:pixes/appdata.dart"; import "package:pixes/components/message.dart"; import "package:pixes/foundation/app.dart"; @@ -43,55 +44,61 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return StateBuilder( - init: SimpleController(), - tag: "MyApp", - builder: (controller) { - return FluentApp( - navigatorKey: App.rootNavigatorKey, - debugShowCheckedModeBanner: false, - title: 'pixes', - theme: FluentThemeData( - brightness: Brightness.light, - fontFamily: App.isWindows ? 'font' : null, - accentColor: AccentColor.swatch({ - 'darkest': SystemTheme.accentColor.darkest, - 'darker': SystemTheme.accentColor.darker, - 'dark': SystemTheme.accentColor.dark, - 'normal': SystemTheme.accentColor.accent, - 'light': SystemTheme.accentColor.light, - 'lighter': SystemTheme.accentColor.lighter, - 'lightest': SystemTheme.accentColor.lightest, - })), - darkTheme: FluentThemeData( - brightness: Brightness.dark, - fontFamily: App.isWindows ? 'font' : null, - accentColor: AccentColor.swatch({ - 'darkest': SystemTheme.accentColor.darkest, - 'darker': SystemTheme.accentColor.darker, - 'dark': SystemTheme.accentColor.dark, - 'normal': SystemTheme.accentColor.accent, - 'light': SystemTheme.accentColor.light, - 'lighter': SystemTheme.accentColor.lighter, - 'lightest': SystemTheme.accentColor.lightest, - })), - home: const MainPage(), - builder: (context, child) { - ErrorWidget.builder = (details) { - if (details.exception - .toString() - .contains("RenderFlex overflowed")) { - return const SizedBox.shrink(); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + return AnnotatedRegion( + value: const SystemUiOverlayStyle( + systemNavigationBarColor: Colors.transparent, + statusBarColor: Colors.transparent), + child: StateBuilder( + init: SimpleController(), + tag: "MyApp", + builder: (controller) { + return FluentApp( + navigatorKey: App.rootNavigatorKey, + debugShowCheckedModeBanner: false, + title: 'pixes', + theme: FluentThemeData( + brightness: Brightness.light, + fontFamily: App.isWindows ? 'font' : null, + accentColor: AccentColor.swatch({ + 'darkest': SystemTheme.accentColor.darkest, + 'darker': SystemTheme.accentColor.darker, + 'dark': SystemTheme.accentColor.dark, + 'normal': SystemTheme.accentColor.accent, + 'light': SystemTheme.accentColor.light, + 'lighter': SystemTheme.accentColor.lighter, + 'lightest': SystemTheme.accentColor.lightest, + })), + darkTheme: FluentThemeData( + brightness: Brightness.dark, + fontFamily: App.isWindows ? 'font' : null, + accentColor: AccentColor.swatch({ + 'darkest': SystemTheme.accentColor.darkest, + 'darker': SystemTheme.accentColor.darker, + 'dark': SystemTheme.accentColor.dark, + 'normal': SystemTheme.accentColor.accent, + 'light': SystemTheme.accentColor.light, + 'lighter': SystemTheme.accentColor.lighter, + 'lightest': SystemTheme.accentColor.lightest, + })), + home: const MainPage(), + builder: (context, child) { + ErrorWidget.builder = (details) { + if (details.exception + .toString() + .contains("RenderFlex overflowed")) { + return const SizedBox.shrink(); + } + Log.error("UI", "${details.exception}\n${details.stack}"); + return Text(details.exception.toString()); + }; + if (child == null) { + throw "widget is null"; } - Log.error("UI", "${details.exception}\n${details.stack}"); - return Text(details.exception.toString()); - }; - if (child == null) { - throw "widget is null"; - } - return OverlayWidget(child); - }); - }); + return OverlayWidget(child); + }); + }), + ); } } diff --git a/lib/pages/bookmarks.dart b/lib/pages/bookmarks.dart index 09a1ad2..ccf1efa 100644 --- a/lib/pages/bookmarks.dart +++ b/lib/pages/bookmarks.dart @@ -2,6 +2,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:pixes/components/segmented_button.dart'; import 'package:pixes/components/title_bar.dart'; +import 'package:pixes/foundation/app.dart'; import 'package:pixes/network/network.dart'; import 'package:pixes/utils/translation.dart'; @@ -65,7 +66,8 @@ class _OneBookmarkedPageState extends MultiPageLoadingState<_OneBookmarkedPage, Widget buildContent(BuildContext context, final List data) { return LayoutBuilder(builder: (context, constrains){ return MasonryGridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8) + + EdgeInsets.only(bottom: context.padding.bottom), gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 240, ), diff --git a/lib/pages/following_artworks.dart b/lib/pages/following_artworks.dart index a23cd8c..c949c19 100644 --- a/lib/pages/following_artworks.dart +++ b/lib/pages/following_artworks.dart @@ -1,6 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:pixes/components/title_bar.dart'; +import 'package:pixes/foundation/app.dart'; import 'package:pixes/utils/translation.dart'; import '../components/illust_widget.dart'; @@ -66,7 +67,8 @@ class _OneFollowingPageState extends MultiPageLoadingState<_OneFollowingPage, Il Widget buildContent(BuildContext context, final List data) { return LayoutBuilder(builder: (context, constrains){ return MasonryGridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8) + + EdgeInsets.only(bottom: context.padding.bottom), gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 240, ), diff --git a/lib/pages/illust_detail_page.dart b/lib/pages/illust_detail_page.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/pages/illust_page.dart b/lib/pages/illust_page.dart index 6917129..3f51c8e 100644 --- a/lib/pages/illust_page.dart +++ b/lib/pages/illust_page.dart @@ -88,8 +88,8 @@ class _IllustPageState extends State { downloadFile = DownloadManager().getImage(widget.illust.id, index); } if (index == widget.illust.images.length) { - return const SizedBox( - height: _kBottomBarHeight, + return SizedBox( + height: _kBottomBarHeight + context.padding.bottom, ); } var imageWidth = width; @@ -174,7 +174,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ late final AnimationController animationController; double get minValue => pageHeight - widgetHeight; - double get maxValue => pageHeight - _kBottomBarHeight; + double get maxValue => pageHeight - _kBottomBarHeight - context.padding.bottom; @override void initState() { @@ -200,7 +200,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ void _handlePointerMove(DragUpdateDetails details) { var offset = details.primaryDelta ?? 0; final minValue = pageHeight - widgetHeight; - final maxValue = pageHeight - _kBottomBarHeight; + final maxValue = pageHeight - _kBottomBarHeight - context.padding.bottom; var top = animationController.value * (maxValue - minValue) + minValue; top = (top + offset).clamp(minValue, maxValue); animationController.value = (top - minValue) / (maxValue - minValue); @@ -292,7 +292,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ buildTags(), buildMoreActions(), SelectableText("${"Artwork ID".tl}: ${widget.illust.id}\n${"Artist ID".tl}: ${widget.illust.author.id}", style: TextStyle(color: ColorScheme.of(context).outline),).paddingLeft(4), - const SizedBox(height: 8,) + SizedBox(height: 8 + context.padding.bottom,) ], ), ), @@ -361,7 +361,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ borderRadius: BorderRadius.circular(8), child: SizedBox( height: double.infinity, - width: showUserName ? 246 : 128, + width: showUserName ? 246 : 136, child: Row( children: [ SizedBox( @@ -866,7 +866,7 @@ class _CommentsPageState extends MultiPageLoadingState<_CommentsPage, Comment> { }); }, ).paddingVertical(8).paddingHorizontal(12), - ), + ).paddingBottom(context.padding.bottom), ); } diff --git a/lib/pages/image_page.dart b/lib/pages/image_page.dart index 55d781e..858f5d2 100644 --- a/lib/pages/image_page.dart +++ b/lib/pages/image_page.dart @@ -130,7 +130,14 @@ class _ImagePageState extends State with WindowListener { MenuFlyoutItem(text: Text("Share".tl), onPressed: () async{ var file = await getFile(); if(file != null){ - var ext = file.path.split('.').last; + var fileName = file.path.split('/').last; + String ext; + if(!file.path.split('.').last.contains('.')){ + ext = 'jpg'; + fileName += '.jpg'; + } else { + ext = file.path.split('.').last; + } var mediaType = switch(ext){ 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', @@ -139,7 +146,7 @@ class _ImagePageState extends State with WindowListener { 'webp' => 'image/webp', _ => 'application/octet-stream' }; - Share.shareXFiles([XFile(file.path, mimeType: mediaType, name: file.path.split('/').last)]); + Share.shareXFiles([XFile(file.path, mimeType: mediaType, name: fileName)]); } }), ], diff --git a/lib/pages/ranking.dart b/lib/pages/ranking.dart index 6c2b7b8..99a31aa 100644 --- a/lib/pages/ranking.dart +++ b/lib/pages/ranking.dart @@ -85,7 +85,8 @@ class _OneRankingPageState extends MultiPageLoadingState<_OneRankingPage, Illust Widget buildContent(BuildContext context, final List data) { return LayoutBuilder(builder: (context, constrains){ return MasonryGridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8) + + EdgeInsets.only(bottom: context.padding.bottom), gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 240, ), diff --git a/lib/pages/recommendation_page.dart b/lib/pages/recommendation_page.dart index 6b9de18..6ed1030 100644 --- a/lib/pages/recommendation_page.dart +++ b/lib/pages/recommendation_page.dart @@ -69,7 +69,8 @@ class _RecommendationArtworksPageState extends MultiPageLoadingState<_Recommenda Widget buildContent(BuildContext context, final List data) { return LayoutBuilder(builder: (context, constrains){ return MasonryGridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8) + + EdgeInsets.only(bottom: context.padding.bottom), gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 240, ), diff --git a/lib/pages/search_page.dart b/lib/pages/search_page.dart index 3ff86cf..8d6db13 100644 --- a/lib/pages/search_page.dart +++ b/lib/pages/search_page.dart @@ -172,7 +172,8 @@ class _TrendingTagsViewState extends LoadingState<_TrendingTagsView, List data) { return MasonryGridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 8.0), + padding: const EdgeInsets.symmetric(horizontal: 8.0) + + EdgeInsets.only(bottom: context.padding.bottom), gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 240, ), @@ -336,6 +337,7 @@ class _SearchSettingsState extends State { ) ).toList(), )), + SizedBox(height: context.padding.bottom,) ], ), ); @@ -386,7 +388,8 @@ class _SearchResultPageState extends MultiPageLoadingState { SliverTitleBar(title: "Settings".tl), buildHeader("Account".tl), buildAccount(), + SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom)), ], ), ); diff --git a/lib/pages/user_info_page.dart b/lib/pages/user_info_page.dart index d4c5237..272f85f 100644 --- a/lib/pages/user_info_page.dart +++ b/lib/pages/user_info_page.dart @@ -34,6 +34,7 @@ class _UserInfoPageState extends LoadingState { buildInformation(), SliverToBoxAdapter(child: buildHeader("Artworks"),), _UserArtworks(data.id.toString(), key: ValueKey(data.id),), + SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom)), ], ), );