mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 12:57:24 +00:00
download and downloading page
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
|
||||
class DownloadPage extends StatefulWidget {
|
||||
const DownloadPage({super.key});
|
||||
|
||||
@override
|
||||
State<DownloadPage> createState() => _DownloadPageState();
|
||||
}
|
||||
|
||||
class _DownloadPageState extends State<DownloadPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
15
lib/pages/downloaded_page.dart
Normal file
15
lib/pages/downloaded_page.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
|
||||
class DownloadedPage extends StatefulWidget {
|
||||
const DownloadedPage({super.key});
|
||||
|
||||
@override
|
||||
State<DownloadedPage> createState() => _DownloadedPageState();
|
||||
}
|
||||
|
||||
class _DownloadedPageState extends State<DownloadedPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
166
lib/pages/downloading_page.dart
Normal file
166
lib/pages/downloading_page.dart
Normal file
@@ -0,0 +1,166 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:pixes/components/md.dart';
|
||||
import 'package:pixes/foundation/app.dart';
|
||||
import 'package:pixes/foundation/image_provider.dart';
|
||||
import 'package:pixes/network/download.dart';
|
||||
import 'package:pixes/utils/translation.dart';
|
||||
|
||||
import '../utils/io.dart';
|
||||
|
||||
class DownloadingPage extends StatefulWidget {
|
||||
const DownloadingPage({super.key});
|
||||
|
||||
@override
|
||||
State<DownloadingPage> createState() => _DownloadingPageState();
|
||||
}
|
||||
|
||||
class _DownloadingPageState extends State<DownloadingPage> {
|
||||
@override
|
||||
void initState() {
|
||||
DownloadManager().registerUiUpdater(() => setState((){}));
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
DownloadManager().removeUiUpdater();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Map<String, FlyoutController> controller = {};
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScaffoldPage(
|
||||
content: CustomScrollView(
|
||||
slivers: [
|
||||
buildTop(),
|
||||
const SliverPadding(padding: EdgeInsets.only(top: 16)),
|
||||
buildContent()
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTop() {
|
||||
int bytesPerSecond = DownloadManager().bytesPerSecond;
|
||||
|
||||
return SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text("${"Speed".tl}: ${bytesToText(bytesPerSecond)}/s",
|
||||
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildContent() {
|
||||
return SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
var task = DownloadManager().tasks[index];
|
||||
return buildItem(task);
|
||||
},
|
||||
childCount: DownloadManager().tasks.length
|
||||
),
|
||||
).sliverPaddingHorizontal(12);
|
||||
}
|
||||
|
||||
Widget buildItem(DownloadingTask task) {
|
||||
controller[task.illust.id.toString()] ??= FlyoutController();
|
||||
|
||||
return Card(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: SizedBox(
|
||||
height: 96,
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: 12),
|
||||
Container(
|
||||
height: double.infinity,
|
||||
width: 72,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(color: ColorScheme.of(context).outlineVariant, width: 0.6),
|
||||
),
|
||||
child: Image(
|
||||
image: CachedImageProvider(task.illust.images.first.medium),
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.medium,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(task.illust.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 4),
|
||||
Text(task.illust.author.name, style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
const Spacer(),
|
||||
if(task.error == null)
|
||||
Text("${task.downloadedImages}/${task.totalImages} ${"Downloaded".tl}", style: const TextStyle(fontSize: 12, color: Colors.grey))
|
||||
else
|
||||
Text("Error: ${task.error!.replaceAll("\n", " ")}", style: TextStyle(fontSize: 12, color: ColorScheme.of(context).error), maxLines: 2,),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if(task.error != null)
|
||||
Button(
|
||||
child: Text("Retry".tl).fixWidth(46),
|
||||
onPressed: () {
|
||||
task.retry();
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
FlyoutTarget(
|
||||
controller: controller[task.illust.id.toString()]!,
|
||||
child: Button(
|
||||
child: Text("Cancel".tl, style: TextStyle(color: ColorScheme.of(context).error),).fixWidth(46),
|
||||
onPressed: (){
|
||||
controller[task.illust.id.toString()]!.showFlyout(
|
||||
navigatorKey: App.rootNavigatorKey.currentState,
|
||||
builder: (context) {
|
||||
return FlyoutContent(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Are you sure you want to cancel this download?'.tl,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 12.0),
|
||||
Button(
|
||||
onPressed: () {
|
||||
Flyout.of(context).close();
|
||||
task.cancel();
|
||||
setState(() {});
|
||||
},
|
||||
child: Text('Yes'.tl),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/material.dart' show Icons;
|
||||
import 'package:pixes/components/animated_image.dart';
|
||||
@@ -69,6 +71,11 @@ class _IllustPageState extends State<IllustPage> {
|
||||
}
|
||||
|
||||
Widget buildImage(double width, double height, int index) {
|
||||
File? downloadFile;
|
||||
if(widget.illust.downloaded) {
|
||||
downloadFile = DownloadManager().getImage(widget.illust.id, index);
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
return Text(
|
||||
widget.illust.title,
|
||||
@@ -93,9 +100,13 @@ class _IllustPageState extends State<IllustPage> {
|
||||
width: imageWidth,
|
||||
height: imageHeight,
|
||||
child: GestureDetector(
|
||||
onTap: () => ImagePage.show(widget.illust.images[index].original),
|
||||
onTap: () => ImagePage.show(downloadFile == null
|
||||
? widget.illust.images[index].original
|
||||
: "file://${downloadFile.path}"),
|
||||
child: Image(
|
||||
image: CachedImageProvider(widget.illust.images[index].large),
|
||||
image: downloadFile == null
|
||||
? CachedImageProvider(widget.illust.images[index].large) as ImageProvider
|
||||
: FileImage(downloadFile) as ImageProvider,
|
||||
width: imageWidth,
|
||||
fit: BoxFit.cover,
|
||||
height: imageHeight,
|
||||
@@ -123,14 +134,9 @@ class _IllustPageState extends State<IllustPage> {
|
||||
),
|
||||
);
|
||||
|
||||
if (index == 0) {
|
||||
return Hero(
|
||||
tag: "illust_${widget.illust.id}",
|
||||
child: image,
|
||||
);
|
||||
} else {
|
||||
return image;
|
||||
}
|
||||
return Center(
|
||||
child: image,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +380,10 @@ class _BottomBarState extends State<_BottomBar> {
|
||||
});
|
||||
}
|
||||
|
||||
void download() {}
|
||||
void download() {
|
||||
DownloadManager().addDownloadingTask(widget.illust);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
bool showText = width > 640;
|
||||
|
||||
@@ -416,24 +425,47 @@ class _BottomBarState extends State<_BottomBar> {
|
||||
yield const SizedBox(width: 8,);
|
||||
|
||||
if (!widget.illust.downloaded) {
|
||||
yield Button(
|
||||
onPressed: download,
|
||||
child: SizedBox(
|
||||
height: 28,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
FluentIcons.download,
|
||||
size: 18,
|
||||
),
|
||||
if(showText)
|
||||
const SizedBox(width: 8,),
|
||||
if(showText)
|
||||
Text("Download".tl),
|
||||
],
|
||||
if(widget.illust.downloading) {
|
||||
yield Button(
|
||||
onPressed: () => {},
|
||||
child: SizedBox(
|
||||
height: 28,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
FluentIcons.download,
|
||||
color: ColorScheme.of(context).outline,
|
||||
size: 18,
|
||||
),
|
||||
if(showText)
|
||||
const SizedBox(width: 8,),
|
||||
if(showText)
|
||||
Text("Downloading".tl,
|
||||
style: TextStyle(color: ColorScheme.of(context).outline),),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
} else {
|
||||
yield Button(
|
||||
onPressed: download,
|
||||
child: SizedBox(
|
||||
height: 28,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
FluentIcons.download,
|
||||
size: 18,
|
||||
),
|
||||
if(showText)
|
||||
const SizedBox(width: 8,),
|
||||
if(showText)
|
||||
Text("Download".tl),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
yield const SizedBox(width: 8,);
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:pixes/components/page_route.dart';
|
||||
@@ -60,7 +62,9 @@ class _ImagePageState extends State<ImagePage> with WindowListener{
|
||||
color: Colors.transparent
|
||||
),
|
||||
filterQuality: FilterQuality.medium,
|
||||
imageProvider: CachedImageProvider(widget.url),
|
||||
imageProvider: widget.url.startsWith("file://")
|
||||
? FileImage(File(widget.url.replaceFirst("file://", "")))
|
||||
: CachedImageProvider(widget.url) as ImageProvider,
|
||||
)),
|
||||
Positioned(
|
||||
top: 0,
|
||||
|
@@ -8,6 +8,7 @@ import "package:pixes/components/md.dart";
|
||||
import "package:pixes/foundation/app.dart";
|
||||
import "package:pixes/network/network.dart";
|
||||
import "package:pixes/pages/bookmarks.dart";
|
||||
import "package:pixes/pages/downloaded_page.dart";
|
||||
import "package:pixes/pages/following_artworks.dart";
|
||||
import "package:pixes/pages/ranking.dart";
|
||||
import "package:pixes/pages/recommendation_page.dart";
|
||||
@@ -20,7 +21,7 @@ import "package:pixes/utils/translation.dart";
|
||||
import "package:window_manager/window_manager.dart";
|
||||
|
||||
import "../components/page_route.dart";
|
||||
import "download_page.dart";
|
||||
import "downloading_page.dart";
|
||||
|
||||
const _kAppBarHeight = 36.0;
|
||||
|
||||
@@ -34,7 +35,7 @@ class MainPage extends StatefulWidget {
|
||||
class _MainPageState extends State<MainPage> with WindowListener {
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
int index = 3;
|
||||
int index = 4;
|
||||
|
||||
int windowButtonKey = 0;
|
||||
|
||||
@@ -101,9 +102,14 @@ class _MainPageState extends State<MainPage> with WindowListener {
|
||||
title: Text('Search'.tl),
|
||||
body: const SizedBox.shrink(),
|
||||
),
|
||||
PaneItem(
|
||||
icon: const Icon(MdIcons.downloading, size: 20,),
|
||||
title: Text('Downloading'.tl),
|
||||
body: const SizedBox.shrink(),
|
||||
),
|
||||
PaneItem(
|
||||
icon: const Icon(MdIcons.download, size: 20,),
|
||||
title: Text('Download'.tl),
|
||||
title: Text('Downloaded'.tl),
|
||||
body: const SizedBox.shrink(),
|
||||
),
|
||||
PaneItemSeparator(),
|
||||
@@ -148,7 +154,8 @@ class _MainPageState extends State<MainPage> with WindowListener {
|
||||
static final pageBuilders = <Widget Function()>[
|
||||
() => UserInfoPage(appdata.account!.user.id),
|
||||
() => const SearchPage(),
|
||||
() => const DownloadPage(),
|
||||
() => const DownloadingPage(),
|
||||
() => const DownloadedPage(),
|
||||
() => const RecommendationPage(),
|
||||
() => const BookMarkedArtworkPage(),
|
||||
() => const FollowingArtworksPage(),
|
||||
|
Reference in New Issue
Block a user