mirror of
https://github.com/venera-app/venera.git
synced 2025-09-28 08:17:25 +00:00
Improve UI
This commit is contained in:
@@ -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,21 +210,32 @@ class _ComicPageState extends LoadingState<ComicPage, ComicDetails>
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(width: 16),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
height: 144,
|
||||
width: 144 * 0.72,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: AnimatedImage(
|
||||
image: CachedImageProvider(
|
||||
comic.cover,
|
||||
sourceKey: comic.sourceKey,
|
||||
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(
|
||||
widget.cover ?? comic.cover,
|
||||
sourceKey: comic.sourceKey,
|
||||
cid: comic.id,
|
||||
),
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user