diff --git a/lib/api/client.dart b/lib/api/client.dart index d17450b..7218357 100644 --- a/lib/api/client.dart +++ b/lib/api/client.dart @@ -209,4 +209,19 @@ class EHApi extends __EHApi { Future> getTags(List ids, {CancelToken? cancel}) { return _getTags(ids.join(","), cancel: cancel); } + + String exportGalleryZipUrl(int gid, + {bool? jpnTitle, int? maxLength, bool? exportAd}) { + final uri = Uri.parse(_combineBaseUrls(_dio.options.baseUrl, baseUrl)); + var queries = { + "jpn_title": jpnTitle?.toString(), + "max_length": maxLength?.toString(), + "export_ad": exportAd?.toString(), + }; + queries.removeWhere((key, value) => value == null); + final newUri = uri + .resolve("export/gallery/zip/$gid") + .replace(queryParameters: queries); + return newUri.toString(); + } } diff --git a/lib/globals.dart b/lib/globals.dart index 8f7681f..d3aac98 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -89,7 +89,7 @@ bool tryInitApi(BuildContext context) { if (_api != null) { return true; } - initApi("${Uri.base.origin}/api"); + initApi("${Uri.base.origin}/api/"); clearAllStates(context); return true; } diff --git a/lib/platform/save_file_none.dart b/lib/platform/save_file_none.dart index 5181ed2..354da61 100644 --- a/lib/platform/save_file_none.dart +++ b/lib/platform/save_file_none.dart @@ -4,3 +4,7 @@ void saveFileWeb( Uint8List data, String mimeType, String filenameWithoutExtension) { throw UnimplementedError(); } + +void saveUriWeb(String uri) { + throw UnimplementedError(); +} diff --git a/lib/platform/save_file_web.dart b/lib/platform/save_file_web.dart index 6e66c45..b71809c 100644 --- a/lib/platform/save_file_web.dart +++ b/lib/platform/save_file_web.dart @@ -26,3 +26,9 @@ void saveFileWeb( a.click(); Url.revokeObjectUrl(url); } + +void saveUriWeb(String uri) { + final a = document.createElement("a") as AnchorElement; + a.href = uri; + a.click(); +} diff --git a/lib/utils.dart b/lib/utils.dart index 1f8e2c6..203fea2 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -5,3 +5,22 @@ bool get isDesktop => !kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS); bool get isWindows => !kIsWeb && Platform.isWindows; bool get isAndroid => !kIsWeb && Platform.isAndroid; + +String? getFilenameFromContentDisposition(String? contentDisposition) { + if (contentDisposition == null) { + return null; + } + var ind = contentDisposition.indexOf("filename=\""); + if (ind != -1) { + final filename = contentDisposition.substring( + ind + 10, contentDisposition.lastIndexOf("\"")); + return Uri.decodeComponent(filename); + } + ind = contentDisposition.indexOf("filename*=UTF-8''"); + if (ind != -1) { + final filename = + contentDisposition.substring(ind + 17, contentDisposition.length); + return Uri.decodeComponent(filename); + } + return null; +} diff --git a/lib/utils/download_zip.dart b/lib/utils/download_zip.dart index 80c17f1..4956264 100644 --- a/lib/utils/download_zip.dart +++ b/lib/utils/download_zip.dart @@ -1,10 +1,17 @@ import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; +import 'package:path/path.dart' as path; import '../globals.dart'; import '../platform/save_file.dart'; +import '../utils.dart'; Future downloadZip(int gid, {bool? jpnTitle, int? maxLength, bool? exportAd}) async { + if (kIsWeb) { + saveUriWeb(api.exportGalleryZipUrl(gid, + jpnTitle: jpnTitle, maxLength: maxLength, exportAd: exportAd)); + return; + } final cancel = CancelToken(); final re = await api.exportGalleryZip(gid, jpnTitle: jpnTitle, @@ -16,12 +23,11 @@ Future downloadZip(int gid, throw Exception("${data.statusCode} ${data.statusMessage}."); } final fileName = re.response.headers.value("content-disposition"); - final filenameWithoutExtension = fileName?.substring( - fileName.indexOf("filename=\"") + 10, fileName.lastIndexOf(".")) ?? - "$gid"; + final filenameWithoutExtension = path.basenameWithoutExtension( + getFilenameFromContentDisposition(fileName) ?? "$gid"); try { final f = await platformPath.openFile( - Uri.decodeComponent(filenameWithoutExtension), "application/zip"); + filenameWithoutExtension, "application/zip"); try { await data.stream.forEach((data) { f.write(data);