mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 21:07:24 +00:00
load illust with id; context menu
This commit is contained in:
@@ -2,6 +2,8 @@ import 'package:fluent_ui/fluent_ui.dart';
|
|||||||
import 'package:pixes/components/animated_image.dart';
|
import 'package:pixes/components/animated_image.dart';
|
||||||
import 'package:pixes/foundation/app.dart';
|
import 'package:pixes/foundation/app.dart';
|
||||||
import 'package:pixes/foundation/image_provider.dart';
|
import 'package:pixes/foundation/image_provider.dart';
|
||||||
|
import 'package:pixes/network/download.dart';
|
||||||
|
import 'package:pixes/utils/translation.dart';
|
||||||
|
|
||||||
import '../network/network.dart';
|
import '../network/network.dart';
|
||||||
import '../pages/illust_page.dart';
|
import '../pages/illust_page.dart';
|
||||||
@@ -19,12 +21,18 @@ class IllustWidget extends StatefulWidget {
|
|||||||
class _IllustWidgetState extends State<IllustWidget> {
|
class _IllustWidgetState extends State<IllustWidget> {
|
||||||
bool isBookmarking = false;
|
bool isBookmarking = false;
|
||||||
|
|
||||||
|
final contextController = FlyoutController();
|
||||||
|
final contextAttachKey = GlobalKey();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return LayoutBuilder(builder: (context, constrains) {
|
return LayoutBuilder(builder: (context, constrains) {
|
||||||
final width = constrains.maxWidth;
|
final width = constrains.maxWidth;
|
||||||
final height = widget.illust.height * width / widget.illust.width;
|
final height = widget.illust.height * width / widget.illust.width;
|
||||||
return SizedBox(
|
return FlyoutTarget(
|
||||||
|
controller: contextController,
|
||||||
|
child: SizedBox(
|
||||||
|
key: contextAttachKey,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
@@ -44,6 +52,7 @@ class _IllustWidgetState extends State<IllustWidget> {
|
|||||||
});
|
});
|
||||||
},));
|
},));
|
||||||
},
|
},
|
||||||
|
onSecondaryTapUp: showMenu,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(4.0),
|
borderRadius: BorderRadius.circular(4.0),
|
||||||
child: AnimatedImage(
|
child: AnimatedImage(
|
||||||
@@ -63,18 +72,54 @@ class _IllustWidgetState extends State<IllustWidget> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildButton() {
|
void showMenu(TapUpDetails details) {
|
||||||
void favorite() async{
|
// This calculates the position of the flyout according to the parent navigator
|
||||||
|
final targetContext = contextAttachKey.currentContext;
|
||||||
|
if (targetContext == null) return;
|
||||||
|
final box = targetContext.findRenderObject() as RenderBox;
|
||||||
|
final position = box.localToGlobal(
|
||||||
|
details.localPosition,
|
||||||
|
ancestor: Navigator.of(context).context.findRenderObject(),
|
||||||
|
);
|
||||||
|
|
||||||
|
contextController.showFlyout(
|
||||||
|
barrierColor: Colors.transparent,
|
||||||
|
position: position,
|
||||||
|
builder: (context) {
|
||||||
|
return MenuFlyout(
|
||||||
|
items: [
|
||||||
|
MenuFlyoutItem(text: Text("View".tl), onPressed: (){
|
||||||
|
context.to(() => IllustPage(widget.illust, favoriteCallback: (v) {
|
||||||
|
setState(() {
|
||||||
|
widget.illust.isBookmarked = v;
|
||||||
|
});
|
||||||
|
},));
|
||||||
|
}),
|
||||||
|
MenuFlyoutItem(text: Text("Private Favorite".tl), onPressed: (){
|
||||||
|
favorite("private");
|
||||||
|
}),
|
||||||
|
MenuFlyoutItem(text: Text("Download".tl), onPressed: (){
|
||||||
|
context.showToast(message: "Added");
|
||||||
|
DownloadManager().addDownloadingTask(widget.illust);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void favorite([String type = "public"]) async{
|
||||||
if(isBookmarking) return;
|
if(isBookmarking) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
isBookmarking = true;
|
isBookmarking = true;
|
||||||
});
|
});
|
||||||
var method = widget.illust.isBookmarked ? "delete" : "add";
|
var method = widget.illust.isBookmarked ? "delete" : "add";
|
||||||
var res = await Network().addBookmark(widget.illust.id.toString(), method);
|
var res = await Network().addBookmark(widget.illust.id.toString(), method, type);
|
||||||
if(res.error) {
|
if(res.error) {
|
||||||
if(mounted) {
|
if(mounted) {
|
||||||
context.showToast(message: "Network Error");
|
context.showToast(message: "Network Error");
|
||||||
@@ -87,6 +132,7 @@ class _IllustWidgetState extends State<IllustWidget> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildButton() {
|
||||||
Widget child;
|
Widget child;
|
||||||
if(isBookmarking) {
|
if(isBookmarking) {
|
||||||
child = const SizedBox(
|
child = const SizedBox(
|
||||||
|
@@ -233,6 +233,7 @@ class DownloadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addDownloadingTask(Illust illust) {
|
void addDownloadingTask(Illust illust) {
|
||||||
|
if(illust.downloaded || illust.downloading) return;
|
||||||
var task = DownloadingTask(illust, receiveBytesCallback: receiveBytes, onCompleted: (task) {
|
var task = DownloadingTask(illust, receiveBytesCallback: receiveBytes, onCompleted: (task) {
|
||||||
saveInfo(illust, task.imagePaths);
|
saveInfo(illust, task.imagePaths);
|
||||||
tasks.remove(task);
|
tasks.remove(task);
|
||||||
|
@@ -391,4 +391,13 @@ class Network {
|
|||||||
return Res.fromErrorRes(res);
|
return Res.fromErrorRes(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Res<Illust>> getIllustByID(String id) async {
|
||||||
|
var res = await apiGet("/v1/illust/detail?illust_id=$id");
|
||||||
|
if (res.success) {
|
||||||
|
return Res(Illust.fromJson(res.data["illust"]));
|
||||||
|
} else {
|
||||||
|
return Res.error(res.errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ import 'package:pixes/components/page_route.dart';
|
|||||||
import 'package:pixes/components/title_bar.dart';
|
import 'package:pixes/components/title_bar.dart';
|
||||||
import 'package:pixes/foundation/app.dart';
|
import 'package:pixes/foundation/app.dart';
|
||||||
import 'package:pixes/network/download.dart';
|
import 'package:pixes/network/download.dart';
|
||||||
|
import 'package:pixes/pages/illust_page.dart';
|
||||||
import 'package:pixes/utils/translation.dart';
|
import 'package:pixes/utils/translation.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
@@ -54,7 +55,7 @@ class _DownloadedPageState extends State<DownloadedPage> {
|
|||||||
return GridViewWithFixedItemHeight(
|
return GridViewWithFixedItemHeight(
|
||||||
itemCount: illusts.length,
|
itemCount: illusts.length,
|
||||||
itemHeight: 152,
|
itemHeight: 152,
|
||||||
maxCrossAxisExtent: 560,
|
maxCrossAxisExtent: 742,
|
||||||
builder: (context, index) {
|
builder: (context, index) {
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
||||||
@@ -120,7 +121,15 @@ class _DownloadedPageState extends State<DownloadedPage> {
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 6),
|
||||||
|
Button(
|
||||||
|
child: Text("Info".tl).fixWidth(42),
|
||||||
|
onPressed: () {
|
||||||
|
context.to(() => IllustPageWithId(
|
||||||
|
illusts[index].illustId.toString()));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
FlyoutTarget(
|
FlyoutTarget(
|
||||||
controller: flyoutControllers[index],
|
controller: flyoutControllers[index],
|
||||||
child: Button(
|
child: Button(
|
||||||
|
@@ -887,3 +887,23 @@ class _CommentsPageState extends MultiPageLoadingState<_CommentsPage, Comment> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IllustPageWithId extends StatefulWidget {
|
||||||
|
const IllustPageWithId(this.id, {super.key});
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<IllustPageWithId> createState() => _IllustPageWithIdState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IllustPageWithIdState extends LoadingState<IllustPageWithId, Illust> {
|
||||||
|
@override
|
||||||
|
Widget buildContent(BuildContext context, Illust data) {
|
||||||
|
return IllustPage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Res<Illust>> loadData() {
|
||||||
|
return Network().getIllustByID(widget.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2,10 +2,12 @@ import 'package:fluent_ui/fluent_ui.dart';
|
|||||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||||
import 'package:pixes/appdata.dart';
|
import 'package:pixes/appdata.dart';
|
||||||
import 'package:pixes/components/loading.dart';
|
import 'package:pixes/components/loading.dart';
|
||||||
|
import 'package:pixes/components/message.dart';
|
||||||
import 'package:pixes/components/page_route.dart';
|
import 'package:pixes/components/page_route.dart';
|
||||||
import 'package:pixes/components/user_preview.dart';
|
import 'package:pixes/components/user_preview.dart';
|
||||||
import 'package:pixes/foundation/app.dart';
|
import 'package:pixes/foundation/app.dart';
|
||||||
import 'package:pixes/network/network.dart';
|
import 'package:pixes/network/network.dart';
|
||||||
|
import 'package:pixes/pages/illust_page.dart';
|
||||||
import 'package:pixes/pages/user_info_page.dart';
|
import 'package:pixes/pages/user_info_page.dart';
|
||||||
import 'package:pixes/utils/translation.dart';
|
import 'package:pixes/utils/translation.dart';
|
||||||
|
|
||||||
@@ -41,17 +43,15 @@ class _SearchPageState extends State<SearchPage> {
|
|||||||
case 0:
|
case 0:
|
||||||
context.to(() => SearchResultPage(text));
|
context.to(() => SearchResultPage(text));
|
||||||
case 1:
|
case 1:
|
||||||
// TODO: novel search
|
showToast(context, message: "Not implemented");
|
||||||
case 2:
|
case 2:
|
||||||
context.to(() => SearchUserResultPage(text));
|
context.to(() => SearchUserResultPage(text));
|
||||||
case 3:
|
case 3:
|
||||||
// TODO: artwork id
|
context.to(() => IllustPageWithId(text));
|
||||||
throw UnimplementedError();
|
|
||||||
case 4:
|
case 4:
|
||||||
context.to(() => UserInfoPage(text));
|
context.to(() => UserInfoPage(text));
|
||||||
case 5:
|
case 5:
|
||||||
// TODO: novel id
|
showToast(context, message: "Not implemented");
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user