mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
Improve UI
This commit is contained in:
@@ -1,5 +1,27 @@
|
||||
part of 'components.dart';
|
||||
|
||||
ImageProvider? _findImageProvider(Comic comic) {
|
||||
ImageProvider image;
|
||||
if (comic is LocalComic) {
|
||||
image = LocalComicImageProvider(comic);
|
||||
} else if (comic is History) {
|
||||
image = HistoryImageProvider(comic);
|
||||
} else if (comic.sourceKey == 'local') {
|
||||
var localComic = LocalManager().find(comic.id, ComicType.local);
|
||||
if (localComic == null) {
|
||||
return null;
|
||||
}
|
||||
image = FileImage(localComic.coverFile);
|
||||
} else {
|
||||
image = CachedImageProvider(
|
||||
comic.cover,
|
||||
sourceKey: comic.sourceKey,
|
||||
cid: comic.id,
|
||||
);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
class ComicTile extends StatelessWidget {
|
||||
const ComicTile(
|
||||
{super.key,
|
||||
@@ -27,8 +49,14 @@ class ComicTile extends StatelessWidget {
|
||||
onTap!();
|
||||
return;
|
||||
}
|
||||
App.mainNavigatorKey?.currentContext
|
||||
?.to(() => ComicPage(id: comic.id, sourceKey: comic.sourceKey));
|
||||
App.mainNavigatorKey?.currentContext?.to(
|
||||
() => ComicPage(
|
||||
id: comic.id,
|
||||
sourceKey: comic.sourceKey,
|
||||
cover: comic.cover,
|
||||
title: comic.title,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onLongPressed(context) {
|
||||
@@ -61,8 +89,14 @@ class ComicTile extends StatelessWidget {
|
||||
icon: Icons.chrome_reader_mode_outlined,
|
||||
text: 'Details'.tl,
|
||||
onClick: () {
|
||||
App.mainNavigatorKey?.currentContext
|
||||
?.to(() => ComicPage(id: comic.id, sourceKey: comic.sourceKey));
|
||||
App.mainNavigatorKey?.currentContext?.to(
|
||||
() => ComicPage(
|
||||
id: comic.id,
|
||||
sourceKey: comic.sourceKey,
|
||||
cover: comic.cover,
|
||||
title: comic.title,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
MenuEntry(
|
||||
@@ -161,24 +195,10 @@ class ComicTile extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget buildImage(BuildContext context) {
|
||||
ImageProvider image;
|
||||
if (comic is LocalComic) {
|
||||
image = LocalComicImageProvider(comic as LocalComic);
|
||||
} else if (comic is History) {
|
||||
image = HistoryImageProvider(comic as History);
|
||||
} else if (comic.sourceKey == 'local') {
|
||||
var localComic = LocalManager().find(comic.id, ComicType.local);
|
||||
if (localComic == null) {
|
||||
var image = _findImageProvider(comic);
|
||||
if (image == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
image = FileImage(localComic.coverFile);
|
||||
} else {
|
||||
image = CachedImageProvider(
|
||||
comic.cover,
|
||||
sourceKey: comic.sourceKey,
|
||||
cid: comic.id,
|
||||
);
|
||||
}
|
||||
return AnimatedImage(
|
||||
image: image,
|
||||
fit: BoxFit.cover,
|
||||
@@ -199,16 +219,26 @@ class ComicTile extends StatelessWidget {
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 24, 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
Hero(
|
||||
tag: "cover${comic.id}${comic.sourceKey}",
|
||||
child: Container(
|
||||
width: height * 0.68,
|
||||
height: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: context.colorScheme.outlineVariant,
|
||||
blurRadius: 1,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: buildImage(context),
|
||||
),
|
||||
),
|
||||
SizedBox.fromSize(
|
||||
size: const Size(16, 5),
|
||||
),
|
||||
@@ -248,6 +278,8 @@ class ComicTile extends StatelessWidget {
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Hero(
|
||||
tag: "cover${comic.id}${comic.sourceKey}",
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.colorScheme.secondaryContainer,
|
||||
@@ -264,6 +296,7 @@ class ComicTile extends StatelessWidget {
|
||||
child: buildImage(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: (() {
|
||||
@@ -1400,7 +1433,7 @@ class _RatingWidgetState extends State<RatingWidget> {
|
||||
}
|
||||
if (full < widget.count) {
|
||||
children.add(ClipRect(
|
||||
clipper: SMClipper(rating: star() * widget.size),
|
||||
clipper: _SMClipper(rating: star() * widget.size),
|
||||
child: Icon(
|
||||
Icons.star,
|
||||
size: widget.size,
|
||||
@@ -1449,10 +1482,10 @@ class _RatingWidgetState extends State<RatingWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
class SMClipper extends CustomClipper<Rect> {
|
||||
class _SMClipper extends CustomClipper<Rect> {
|
||||
final double rating;
|
||||
|
||||
SMClipper({required this.rating});
|
||||
_SMClipper({required this.rating});
|
||||
|
||||
@override
|
||||
Rect getClip(Size size) {
|
||||
@@ -1460,7 +1493,52 @@ class SMClipper extends CustomClipper<Rect> {
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReclip(SMClipper oldClipper) {
|
||||
bool shouldReclip(_SMClipper oldClipper) {
|
||||
return rating != oldClipper.rating;
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleComicTile extends StatelessWidget {
|
||||
const SimpleComicTile({super.key, required this.comic, this.onTap});
|
||||
|
||||
final Comic comic;
|
||||
|
||||
final void Function()? onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var image = _findImageProvider(comic);
|
||||
|
||||
var child = image == null
|
||||
? const SizedBox()
|
||||
: AnimatedImage(
|
||||
image: image,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.medium,
|
||||
);
|
||||
|
||||
return AnimatedTapRegion(
|
||||
borderRadius: 8,
|
||||
onTap: onTap ?? () {
|
||||
context.to(
|
||||
() => ComicPage(
|
||||
id: comic.id,
|
||||
sourceKey: comic.sourceKey,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 92,
|
||||
height: 114,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -41,39 +41,44 @@ class AnimatedTapRegion extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AnimatedTapRegionState extends State<AnimatedTapRegion> {
|
||||
bool isScaled = false;
|
||||
|
||||
bool isHovered = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
onEnter: (_) {
|
||||
setState(() {
|
||||
isHovered = true;
|
||||
if (!isScaled) {
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (isHovered) {
|
||||
setState(() => isScaled = true);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
onExit: (_) {
|
||||
setState(() {
|
||||
isHovered = false;
|
||||
if(isScaled) {
|
||||
setState(() => isScaled = false);
|
||||
}
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: AnimatedScale(
|
||||
child: AnimatedContainer(
|
||||
duration: _fastAnimationDuration,
|
||||
scale: isScaled ? 1.1 : 1,
|
||||
child: widget.child,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
||||
boxShadow: isHovered
|
||||
? [
|
||||
BoxShadow(
|
||||
color: context.colorScheme.outline,
|
||||
blurRadius: 2,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
]
|
||||
: [
|
||||
BoxShadow(
|
||||
color: context.colorScheme.outlineVariant,
|
||||
blurRadius: 1,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@@ -200,16 +200,18 @@ class NaviPaneState extends State<NaviPane>
|
||||
}
|
||||
|
||||
Widget buildMainView() {
|
||||
return Navigator(
|
||||
return HeroControllerScope(
|
||||
controller: MaterialApp.createMaterialHeroController(),
|
||||
child: Navigator(
|
||||
observers: [widget.observer],
|
||||
key: widget.navigatorKey,
|
||||
onGenerateRoute: (settings) => AppPageRoute(
|
||||
preventRebuild: false,
|
||||
isRootRoute: true,
|
||||
builder: (context) {
|
||||
return _NaviMainView(state: this);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -362,13 +364,11 @@ class _SideNaviWidget extends StatelessWidget {
|
||||
color: enabled ? colorScheme.primaryContainer : null,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: showTitle ? Row(
|
||||
children: [
|
||||
icon,
|
||||
const SizedBox(width: 12),
|
||||
Text(entry.label)
|
||||
],
|
||||
) : Align(
|
||||
child: showTitle
|
||||
? Row(
|
||||
children: [icon, const SizedBox(width: 12), Text(entry.label)],
|
||||
)
|
||||
: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: icon,
|
||||
),
|
||||
@@ -395,13 +395,11 @@ class _PaneActionWidget extends StatelessWidget {
|
||||
duration: const Duration(milliseconds: 180),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
height: 38,
|
||||
child: showTitle ? Row(
|
||||
children: [
|
||||
icon,
|
||||
const SizedBox(width: 12),
|
||||
Text(entry.label)
|
||||
],
|
||||
) : Align(
|
||||
child: showTitle
|
||||
? Row(
|
||||
children: [icon, const SizedBox(width: 12), Text(entry.label)],
|
||||
)
|
||||
: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: icon,
|
||||
),
|
||||
|
@@ -19,7 +19,6 @@ class AppPageRoute<T> extends PageRoute<T> with _AppRouteTransitionMixin{
|
||||
super.barrierDismissible = false,
|
||||
this.enableIOSGesture = true,
|
||||
this.preventRebuild = true,
|
||||
this.isRootRoute = false,
|
||||
}) {
|
||||
assert(opaque);
|
||||
}
|
||||
@@ -50,9 +49,6 @@ class AppPageRoute<T> extends PageRoute<T> with _AppRouteTransitionMixin{
|
||||
|
||||
@override
|
||||
final bool preventRebuild;
|
||||
|
||||
@override
|
||||
final bool isRootRoute;
|
||||
}
|
||||
|
||||
mixin _AppRouteTransitionMixin<T> on PageRoute<T> {
|
||||
@@ -79,8 +75,6 @@ mixin _AppRouteTransitionMixin<T> on PageRoute<T> {
|
||||
|
||||
bool get preventRebuild;
|
||||
|
||||
bool get isRootRoute;
|
||||
|
||||
Widget? _child;
|
||||
|
||||
@override
|
||||
@@ -121,22 +115,6 @@ mixin _AppRouteTransitionMixin<T> on PageRoute<T> {
|
||||
|
||||
@override
|
||||
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
|
||||
if(isRootRoute) {
|
||||
return FadeTransition(
|
||||
opacity: Tween<double>(begin: 0, end: 1.0).animate(CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.ease
|
||||
)),
|
||||
child: FadeTransition(
|
||||
opacity: Tween<double>(begin: 1.0, end: 0).animate(CurvedAnimation(
|
||||
parent: secondaryAnimation,
|
||||
curve: Curves.ease
|
||||
)),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return SlidePageTransitionBuilder().buildTransitions(
|
||||
this,
|
||||
context,
|
||||
|
@@ -1,14 +1,11 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:shimmer/shimmer.dart";
|
||||
import 'package:shimmer_animation/shimmer_animation.dart';
|
||||
import "package:venera/components/components.dart";
|
||||
import "package:venera/foundation/app.dart";
|
||||
import "package:venera/foundation/comic_source/comic_source.dart";
|
||||
import "package:venera/foundation/image_provider/cached_image.dart";
|
||||
import "package:venera/pages/search_result_page.dart";
|
||||
import "package:venera/utils/translations.dart";
|
||||
|
||||
import "comic_page.dart";
|
||||
|
||||
class AggregatedSearchPage extends StatefulWidget {
|
||||
const AggregatedSearchPage({super.key, required this.keyword});
|
||||
|
||||
@@ -73,9 +70,9 @@ class _SliverSearchResultState extends State<_SliverSearchResult>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
bool isLoading = true;
|
||||
|
||||
static const _kComicHeight = 144.0;
|
||||
static const _kComicHeight = 132.0;
|
||||
|
||||
get _comicWidth => _kComicHeight * 0.72;
|
||||
get _comicWidth => _kComicHeight * 0.7;
|
||||
|
||||
static const _kLeftPadding = 16.0;
|
||||
|
||||
@@ -123,28 +120,9 @@ class _SliverSearchResultState extends State<_SliverSearchResult>
|
||||
}
|
||||
|
||||
Widget buildComic(Comic c) {
|
||||
return AnimatedTapRegion(
|
||||
borderRadius: 8,
|
||||
onTap: () {
|
||||
context.to(() => ComicPage(
|
||||
id: c.id,
|
||||
sourceKey: c.sourceKey,
|
||||
));
|
||||
},
|
||||
child: Container(
|
||||
height: _kComicHeight,
|
||||
width: _comicWidth,
|
||||
decoration: BoxDecoration(
|
||||
color: context.colorScheme.surfaceContainerLow,
|
||||
),
|
||||
child: AnimatedImage(
|
||||
width: _comicWidth,
|
||||
height: _kComicHeight,
|
||||
fit: BoxFit.cover,
|
||||
image: CachedImageProvider(c.cover),
|
||||
),
|
||||
),
|
||||
).paddingLeft(_kLeftPadding);
|
||||
return SimpleComicTile(comic: c)
|
||||
.paddingLeft(_kLeftPadding)
|
||||
.paddingBottom(2);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -169,10 +147,7 @@ class _SliverSearchResultState extends State<_SliverSearchResult>
|
||||
SizedBox(
|
||||
height: _kComicHeight,
|
||||
width: double.infinity,
|
||||
child: Shimmer.fromColors(
|
||||
baseColor: context.colorScheme.surfaceContainerLow,
|
||||
highlightColor: context.colorScheme.surfaceContainer,
|
||||
direction: ShimmerDirection.ltr,
|
||||
child: Shimmer(
|
||||
child: LayoutBuilder(builder: (context, constrains) {
|
||||
var itemWidth = _comicWidth + _kLeftPadding;
|
||||
var items = (constrains.maxWidth / itemWidth).ceil();
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shimmer_animation/shimmer_animation.dart';
|
||||
import 'package:sliver_tools/sliver_tools.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import 'package:venera/components/components.dart';
|
||||
@@ -26,12 +27,22 @@ import 'dart:math' as math;
|
||||
import 'comments_page.dart';
|
||||
|
||||
class ComicPage extends StatefulWidget {
|
||||
const ComicPage({super.key, required this.id, required this.sourceKey});
|
||||
const ComicPage({
|
||||
super.key,
|
||||
required this.id,
|
||||
required this.sourceKey,
|
||||
this.cover,
|
||||
this.title,
|
||||
});
|
||||
|
||||
final String id;
|
||||
|
||||
final String sourceKey;
|
||||
|
||||
final String? cover;
|
||||
|
||||
final String? title;
|
||||
|
||||
@override
|
||||
State<ComicPage> createState() => _ComicPageState();
|
||||
}
|
||||
@@ -55,13 +66,11 @@ class _ComicPageState extends LoadingState<ComicPage, ComicDetails>
|
||||
|
||||
@override
|
||||
Widget buildLoading() {
|
||||
return Column(
|
||||
children: [
|
||||
const Appbar(title: Text("")),
|
||||
Expanded(
|
||||
child: super.buildLoading(),
|
||||
),
|
||||
],
|
||||
return _ComicPageLoadingPlaceHolder(
|
||||
cover: widget.cover,
|
||||
title: widget.title,
|
||||
sourceKey: widget.sourceKey,
|
||||
cid: widget.id,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -201,23 +210,34 @@ class _ComicPageState extends LoadingState<ComicPage, ComicDetails>
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(width: 16),
|
||||
Container(
|
||||
Hero(
|
||||
tag: "cover${comic.id}${comic.sourceKey}",
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: context.colorScheme.outlineVariant,
|
||||
blurRadius: 1,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
height: 144,
|
||||
width: 144 * 0.72,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: AnimatedImage(
|
||||
image: CachedImageProvider(
|
||||
comic.cover,
|
||||
widget.cover ?? comic.cover,
|
||||
sourceKey: comic.sourceKey,
|
||||
cid: comic.id,
|
||||
),
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
@@ -1946,3 +1966,124 @@ class _CommentWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ComicPageLoadingPlaceHolder extends StatelessWidget {
|
||||
const _ComicPageLoadingPlaceHolder({
|
||||
this.cover,
|
||||
this.title,
|
||||
required this.sourceKey,
|
||||
required this.cid,
|
||||
});
|
||||
|
||||
final String? cover;
|
||||
|
||||
final String? title;
|
||||
|
||||
final String sourceKey;
|
||||
|
||||
final String cid;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget buildContainer(double? width, double? height,
|
||||
{Color? color, double? radius}) {
|
||||
return Container(
|
||||
height: height,
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: color ?? context.colorScheme.surfaceContainerLow,
|
||||
borderRadius: BorderRadius.circular(radius ?? 4),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Shimmer(
|
||||
child: Column(
|
||||
children: [
|
||||
Appbar(title: Text(""), backgroundColor: context.colorScheme.surface),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(width: 16),
|
||||
buildImage(context),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (title != null)
|
||||
Text(title ?? "", style: ts.s18)
|
||||
else
|
||||
buildContainer(200, 25),
|
||||
const SizedBox(height: 8),
|
||||
buildContainer(80, 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (context.width < changePoint)
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: buildContainer(null, 36, radius: 18),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: buildContainer(null, 36, radius: 18),
|
||||
),
|
||||
],
|
||||
).paddingHorizontal(16),
|
||||
const Divider(),
|
||||
const SizedBox(height: 8),
|
||||
Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2.4,
|
||||
).fixHeight(24).fixWidth(24),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildImage(BuildContext context) {
|
||||
Widget child;
|
||||
if (cover != null) {
|
||||
child = AnimatedImage(
|
||||
image: CachedImageProvider(
|
||||
cover!,
|
||||
sourceKey: sourceKey,
|
||||
cid: cid,
|
||||
),
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
} else {
|
||||
child = const SizedBox();
|
||||
}
|
||||
|
||||
return Hero(
|
||||
tag: "cover$cid$sourceKey",
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: context.colorScheme.outlineVariant,
|
||||
blurRadius: 1,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
height: 144,
|
||||
width: 144 * 0.72,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -6,8 +6,6 @@ import 'package:venera/foundation/comic_source/comic_source.dart';
|
||||
import 'package:venera/foundation/consts.dart';
|
||||
import 'package:venera/foundation/favorites.dart';
|
||||
import 'package:venera/foundation/history.dart';
|
||||
import 'package:venera/foundation/image_provider/history_image_provider.dart';
|
||||
import 'package:venera/foundation/image_provider/local_comic_image.dart';
|
||||
import 'package:venera/foundation/local.dart';
|
||||
import 'package:venera/foundation/log.dart';
|
||||
import 'package:venera/pages/accounts_page.dart';
|
||||
@@ -267,8 +265,8 @@ class _HistoryState extends State<_History> {
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: history.length,
|
||||
itemBuilder: (context, index) {
|
||||
return AnimatedTapRegion(
|
||||
borderRadius: 8,
|
||||
return SimpleComicTile(
|
||||
comic: history[index],
|
||||
onTap: () {
|
||||
context.to(
|
||||
() => ComicPage(
|
||||
@@ -277,25 +275,7 @@ class _HistoryState extends State<_History> {
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 92,
|
||||
height: 114,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondaryContainer,
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: AnimatedImage(
|
||||
image: HistoryImageProvider(history[index]),
|
||||
width: 96,
|
||||
height: 128,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.medium,
|
||||
),
|
||||
),
|
||||
).paddingHorizontal(8);
|
||||
).paddingHorizontal(8).paddingVertical(2);
|
||||
},
|
||||
),
|
||||
).paddingHorizontal(8).paddingBottom(16),
|
||||
@@ -388,32 +368,8 @@ class _LocalState extends State<_Local> {
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: local.length,
|
||||
itemBuilder: (context, index) {
|
||||
return AnimatedTapRegion(
|
||||
onTap: () {
|
||||
local[index].read();
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Container(
|
||||
width: 92,
|
||||
height: 114,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondaryContainer,
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: AnimatedImage(
|
||||
image: LocalComicImageProvider(
|
||||
local[index],
|
||||
),
|
||||
width: 96,
|
||||
height: 128,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.medium,
|
||||
),
|
||||
),
|
||||
).paddingHorizontal(8);
|
||||
return SimpleComicTile(comic: local[index])
|
||||
.paddingHorizontal(8);
|
||||
},
|
||||
),
|
||||
).paddingHorizontal(8),
|
||||
|
@@ -867,14 +867,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
shimmer:
|
||||
shimmer_animation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shimmer
|
||||
sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9"
|
||||
name: shimmer_animation
|
||||
sha256: "9357080b7dd892aae837d569e1fbbcbe7f9a02ca994e558561d90e35e92f1101"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "2.2.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@@ -69,7 +69,7 @@ dependencies:
|
||||
ref: 7637b8b67d0a831f3cd7e702b8173e300880d32e
|
||||
pdf: ^3.11.1
|
||||
dynamic_color: ^1.7.0
|
||||
shimmer: ^3.0.0
|
||||
shimmer_animation: ^2.1.0
|
||||
flutter_memory_info: ^0.0.1
|
||||
syntax_highlight: ^0.4.0
|
||||
text_scroll: ^0.2.0
|
||||
|
Reference in New Issue
Block a user