improve ui

This commit is contained in:
nyne
2024-10-10 10:13:35 +08:00
parent df559e4cca
commit f228c7ee17
12 changed files with 126 additions and 105 deletions

View File

@@ -14,5 +14,7 @@
This Theme is only used starting with V2 of Flutter's Android embedding. --> This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item> <item name="android:windowBackground">?android:colorBackground</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style> </style>
</resources> </resources>

View File

@@ -296,7 +296,7 @@ class _FilledTabBarState extends State<FilledTabBar> {
padding: tabPadding, padding: tabPadding,
radius: tabRadius, radius: tabRadius,
); );
if (old != null) { if (old != null && old.offsets != null && old.itemHeight != null) {
painter!.update(old.offsets!, old.itemHeight!); painter!.update(old.offsets!, old.itemHeight!);
} }
} }

View File

@@ -262,6 +262,8 @@ class ContentDialog extends StatelessWidget {
insetPadding: context.width < 400 insetPadding: context.width < 400
? const EdgeInsets.symmetric(horizontal: 4) ? const EdgeInsets.symmetric(horizontal: 4)
: const EdgeInsets.symmetric(horizontal: 16), : const EdgeInsets.symmetric(horizontal: 16),
elevation: 2,
shadowColor: context.colorScheme.shadow,
child: IntrinsicWidth( child: IntrinsicWidth(
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints( constraints: BoxConstraints(

View File

@@ -127,15 +127,15 @@ class _NaviPaneState extends State<NaviPane>
} }
if (target == 1) { if (target == 1) {
StateController.find<NaviPaddingWidgetController>() StateController.find<NaviPaddingWidgetController>()
.setWithPadding(true, true); .setWithPadding(true, true, true);
controller.value = target; controller.value = target;
} else if (controller.value == 1 && target == 0) { } else if (controller.value == 1 && target == 0) {
StateController.findOrNull<NaviPaddingWidgetController>() StateController.findOrNull<NaviPaddingWidgetController>()
?.setWithPadding(false, false); ?.setWithPadding(false, false, false);
controller.value = target; controller.value = target;
} else { } else {
StateController.findOrNull<NaviPaddingWidgetController>() StateController.findOrNull<NaviPaddingWidgetController>()
?.setWithPadding(true, false); ?.setWithPadding(true, false, false);
controller.animateTo(target); controller.animateTo(target);
} }
animationTarget = target; animationTarget = target;
@@ -660,9 +660,13 @@ class NaviPaddingWidgetController extends StateController {
bool _withTopBarPadding = false; bool _withTopBarPadding = false;
void setWithPadding(bool withPadding, bool withAppbarPadding) { bool _withBottomBarPadding = false;
void setWithPadding(
bool withPadding, bool withAppbarPadding, bool withBottomBarPadding) {
_withPadding = withPadding; _withPadding = withPadding;
_withTopBarPadding = withAppbarPadding; _withTopBarPadding = withAppbarPadding;
_withBottomBarPadding = withBottomBarPadding;
update(); update();
} }
} }
@@ -683,8 +687,10 @@ class NaviPaddingWidget extends StatelessWidget {
(controller._withTopBarPadding (controller._withTopBarPadding
? _NaviPaneState._kTopBarHeight ? _NaviPaneState._kTopBarHeight
: 0), : 0),
bottom: bottom: context.padding.bottom +
_NaviPaneState._kBottomBarHeight + context.padding.bottom, (controller._withBottomBarPadding
? _NaviPaneState._kBottomBarHeight
: 0),
) )
: EdgeInsets.zero, : EdgeInsets.zero,
child: child, child: child,

View File

@@ -55,7 +55,7 @@ class _SmoothScrollProviderState extends State<SmoothScrollProvider> {
return widget.builder( return widget.builder(
context, context,
_controller, _controller,
const ClampingScrollPhysics(), const BouncingScrollPhysics(),
); );
} }
return Listener( return Listener(
@@ -93,7 +93,7 @@ class _SmoothScrollProviderState extends State<SmoothScrollProvider> {
_controller, _controller,
_isMouseScroll _isMouseScroll
? const NeverScrollableScrollPhysics() ? const NeverScrollableScrollPhysics()
: const ClampingScrollPhysics(), : const BouncingScrollPhysics(),
), ),
); );
} }

View File

@@ -51,9 +51,9 @@ class _Appdata {
return; return;
} }
var json = jsonDecode(await file.readAsString()); var json = jsonDecode(await file.readAsString());
for(var key in json['settings'].keys) { for(var key in (json['settings'] as Map<String, dynamic>).keys) {
if(json[key] != null) { if(json['settings'][key] != null) {
settings[key] = json[key]; settings[key] = json['settings'][key];
} }
} }
searchHistory = List.from(json['searchHistory']); searchHistory = List.from(json['searchHistory']);

View File

@@ -56,6 +56,7 @@ class _MyAppState extends State<MyApp> {
@override @override
void initState() { void initState() {
App.registerForceRebuild(forceRebuild); App.registerForceRebuild(forceRebuild);
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
super.initState(); super.initState();
} }

View File

@@ -74,6 +74,7 @@ class _ComicPageState extends LoadingState<ComicPage, ComicDetails>
buildChapters(), buildChapters(),
buildThumbnails(), buildThumbnails(),
buildRecommend(), buildRecommend(),
SliverPadding(padding: EdgeInsets.only(bottom: context.padding.bottom)),
], ],
); );
} }
@@ -109,6 +110,8 @@ class _ComicPageState extends LoadingState<ComicPage, ComicDetails>
], ],
); );
yield const SliverPadding(padding: EdgeInsets.only(top: 8));
yield Row( yield Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View File

@@ -243,7 +243,7 @@ class _BodyState extends State<_Body> {
.paddingBottom(32), .paddingBottom(32),
Row( Row(
children: [ children: [
TextButton(onPressed: chooseFile, child: Text("Choose file".tl)) TextButton(onPressed: selectFile, child: Text("Select file".tl))
.paddingLeft(8), .paddingLeft(8),
const Spacer(), const Spacer(),
TextButton( TextButton(
@@ -265,7 +265,7 @@ class _BodyState extends State<_Body> {
); );
} }
void chooseFile() async { void selectFile() async {
final result = await FilePicker.platform.pickFiles( final result = await FilePicker.platform.pickFiles(
type: FileType.custom, type: FileType.custom,
allowedExtensions: ['js'], allowedExtensions: ['js'],

View File

@@ -260,7 +260,8 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
if (_lastException != null) { if (_lastException != null) {
// display error and retry button on screen // display error and retry button on screen
return SizedBox( return SizedBox(
height: 300, height: widget.height == null ? 300 : null,
width: widget.width == null ? 300 : null,
child: Center( child: Center(
child: SizedBox( child: SizedBox(
height: 300, height: 300,
@@ -295,87 +296,92 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
); );
} }
var width = widget.width??MediaQuery.of(context).size.width; return LayoutBuilder(builder: (context, constrains) {
double? height; var width = widget.width;
var height = widget.height;
Size? cacheSize = _cache[widget.image.hashCode]; if(_imageInfo != null) {
if(cacheSize != null){ // Record the height and the width of the image
height = cacheSize.height * (width / cacheSize.width); _cache[widget.image.hashCode] = Size(
height = height.ceilToDouble(); _imageInfo!.image.width.toDouble(),
} _imageInfo!.image.height.toDouble()
var brightness = Theme.of(context).brightness;
if(_imageInfo != null){
// Record the height and the width of the image
_cache[widget.image.hashCode] = Size(
_imageInfo!.image.width.toDouble(),
_imageInfo!.image.height.toDouble()
);
// build image
Widget result = RawImage(
// Do not clone the image, because RawImage is a stateless wrapper.
// The image will be disposed by this state object when it is not needed
// anymore, such as when it is unmounted or when the image stream pushes
// a new image.
image: _imageInfo?.image,
debugImageLabel: _imageInfo?.debugLabel,
width: width,
height: height,
scale: _imageInfo?.scale ?? 1.0,
color: widget.color,
opacity: widget.opacity,
colorBlendMode: widget.colorBlendMode,
fit: widget.fit,
alignment: widget.alignment,
repeat: widget.repeat,
centerSlice: widget.centerSlice,
matchTextDirection: widget.matchTextDirection,
invertColors: _invertColors,
isAntiAlias: widget.isAntiAlias,
filterQuality: widget.filterQuality,
);
if (!widget.excludeFromSemantics) {
result = Semantics(
container: widget.semanticLabel != null,
image: true,
label: widget.semanticLabel ?? '',
child: result,
); );
} }
result = SizedBox(
width: width, Size? cacheSize = _cache[widget.image.hashCode];
height: height, if(cacheSize != null){
child: Center( if(width == double.infinity) {
child: result, width = constrains.maxWidth;
), height = width * cacheSize.height / cacheSize.width;
); } else if(height == double.infinity) {
return result; height = constrains.maxHeight;
} else { width = height * cacheSize.width / cacheSize.height;
// build progress }
return SizedBox( }
width: width,
height: height??300, if(_imageInfo != null){
child: Center( // build image
child: SizedBox( Widget result = RawImage(
width: 24, // Do not clone the image, because RawImage is a stateless wrapper.
height: 24, // The image will be disposed by this state object when it is not needed
child: CircularProgressIndicator( // anymore, such as when it is unmounted or when the image stream pushes
backgroundColor: brightness == Brightness.dark // a new image.
? Colors.white24 image: _imageInfo?.image,
: Colors.black12, debugImageLabel: _imageInfo?.debugLabel,
strokeWidth: 3, width: width,
value: (_loadingProgress != null && height: height,
_loadingProgress!.expectedTotalBytes!=null && scale: _imageInfo?.scale ?? 1.0,
_loadingProgress!.expectedTotalBytes! != 0) color: widget.color,
?_loadingProgress!.cumulativeBytesLoaded / _loadingProgress!.expectedTotalBytes! opacity: widget.opacity,
:0, colorBlendMode: widget.colorBlendMode,
fit: widget.fit,
alignment: widget.alignment,
repeat: widget.repeat,
centerSlice: widget.centerSlice,
matchTextDirection: widget.matchTextDirection,
invertColors: _invertColors,
isAntiAlias: widget.isAntiAlias,
filterQuality: widget.filterQuality,
);
if (!widget.excludeFromSemantics) {
result = Semantics(
container: widget.semanticLabel != null,
image: true,
label: widget.semanticLabel ?? '',
child: result,
);
}
result = SizedBox(
width: width,
height: height,
child: Center(
child: result,
),
);
return result;
} else {
// build progress
return SizedBox(
width: width,
height: height,
child: Center(
child: SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 3,
value: (_loadingProgress != null &&
_loadingProgress!.expectedTotalBytes!=null &&
_loadingProgress!.expectedTotalBytes! != 0)
?_loadingProgress!.cumulativeBytesLoaded / _loadingProgress!.expectedTotalBytes!
:0,
),
), ),
), ),
), );
); }
} });
} }
@override @override

View File

@@ -258,7 +258,7 @@ class _GalleryModeState extends State<_GalleryMode>
event.logicalKey == LogicalKeyboardKey.arrowRight) { event.logicalKey == LogicalKeyboardKey.arrowRight) {
forward = false; forward = false;
} }
if(event is KeyDownEvent || event is KeyRepeatEvent) { if (event is KeyDownEvent || event is KeyRepeatEvent) {
if (forward == true) { if (forward == true) {
controller.nextPage( controller.nextPage(
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
@@ -371,13 +371,12 @@ class _ContinuousModeState extends State<_ContinuousMode>
if (index == 0 || index == reader.maxPage + 1) { if (index == 0 || index == reader.maxPage + 1) {
return const SizedBox(); return const SizedBox();
} }
double width = MediaQuery.of(context).size.width; double? width, height;
double height = MediaQuery.of(context).size.height; if (reader.mode == ReaderMode.continuousLeftToRight ||
reader.mode == ReaderMode.continuousRightToLeft) {
double imageWidth = width; height = double.infinity;
} else {
if (height / width < 1.2) { width = double.infinity;
imageWidth = height / 1.2;
} }
_precacheImage(index, context); _precacheImage(index, context);
@@ -387,9 +386,9 @@ class _ContinuousModeState extends State<_ContinuousMode>
return ComicImage( return ComicImage(
filterQuality: FilterQuality.medium, filterQuality: FilterQuality.medium,
image: image, image: image,
width: imageWidth, width: width,
height: imageWidth * 1.2, height: height,
fit: BoxFit.cover, fit: BoxFit.contain,
); );
}, },
scrollBehavior: const MaterialScrollBehavior() scrollBehavior: const MaterialScrollBehavior()
@@ -420,10 +419,10 @@ class _ContinuousModeState extends State<_ContinuousMode>
return; return;
} }
if (scrollController.offset != if (scrollController.offset !=
scrollController.position.maxScrollExtent && scrollController.position.maxScrollExtent &&
scrollController.offset != scrollController.offset !=
scrollController.position.minScrollExtent) { scrollController.position.minScrollExtent) {
if(reader.mode == ReaderMode.continuousTopToBottom) { if (reader.mode == ReaderMode.continuousTopToBottom) {
value = Offset(value.dx, 0); value = Offset(value.dx, 0);
} else { } else {
value = Offset(0, value.dy); value = Offset(0, value.dy);

View File

@@ -102,7 +102,9 @@ class _ReaderState extends State<Reader> with _ReaderLocation, _ReaderWindow {
chapter = widget.initialChapter ?? 1; chapter = widget.initialChapter ?? 1;
mode = ReaderMode.fromKey(appdata.settings['readerMode']); mode = ReaderMode.fromKey(appdata.settings['readerMode']);
history = widget.history; history = widget.history;
updateHistory(); Future.microtask(() {
updateHistory();
});
super.initState(); super.initState();
} }