improve mobile ui

This commit is contained in:
wgh19
2024-05-15 09:01:27 +08:00
parent f8c3514956
commit c60caad531
13 changed files with 97 additions and 65 deletions

View File

@@ -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),
)));
}

View File

@@ -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;
}

View File

@@ -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<SimpleController>(
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<SystemUiOverlayStyle>(
value: const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.transparent,
statusBarColor: Colors.transparent),
child: StateBuilder<SimpleController>(
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);
});
}),
);
}
}

View File

@@ -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<Illust> 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,
),

View File

@@ -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<Illust> 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,
),

View File

@@ -88,8 +88,8 @@ class _IllustPageState extends State<IllustPage> {
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),
);
}

View File

@@ -130,7 +130,14 @@ class _ImagePageState extends State<ImagePage> 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<ImagePage> 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)]);
}
}),
],

View File

@@ -85,7 +85,8 @@ class _OneRankingPageState extends MultiPageLoadingState<_OneRankingPage, Illust
Widget buildContent(BuildContext context, final List<Illust> 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,
),

View File

@@ -69,7 +69,8 @@ class _RecommendationArtworksPageState extends MultiPageLoadingState<_Recommenda
Widget buildContent(BuildContext context, final List<Illust> 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,
),

View File

@@ -172,7 +172,8 @@ class _TrendingTagsViewState extends LoadingState<_TrendingTagsView, List<Trendi
@override
Widget buildContent(BuildContext context, List<TrendingTag> 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<SearchSettings> {
)
).toList(),
)),
SizedBox(height: context.padding.bottom,)
],
),
);
@@ -386,7 +388,8 @@ class _SearchResultPageState extends MultiPageLoadingState<SearchResultPage, Ill
},
childCount: data.length,
),
).sliverPaddingHorizontal(8)
).sliverPaddingHorizontal(8),
SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom),)
],
);
}
@@ -440,7 +443,8 @@ class _SearchUserResultPageState extends MultiPageLoadingState<SearchUserResultP
),
maxCrossAxisExtent: 520,
itemHeight: 114,
).sliverPaddingHorizontal(8)
).sliverPaddingHorizontal(8),
SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom),)
],
);
}

View File

@@ -24,6 +24,7 @@ class _SettingsPageState extends State<SettingsPage> {
SliverTitleBar(title: "Settings".tl),
buildHeader("Account".tl),
buildAccount(),
SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom)),
],
),
);

View File

@@ -34,6 +34,7 @@ class _UserInfoPageState extends LoadingState<UserInfoPage, UserDetails> {
buildInformation(),
SliverToBoxAdapter(child: buildHeader("Artworks"),),
_UserArtworks(data.id.toString(), key: ValueKey(data.id),),
SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom)),
],
),
);