Skip to content

Commit

Permalink
ImageDialogでファイルをそのまま保存できるように
Browse files Browse the repository at this point in the history
  • Loading branch information
poppingmoon committed Oct 26, 2023
1 parent bfe996f commit 69da27e
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 54 deletions.
4 changes: 4 additions & 0 deletions lib/providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:miria/repository/tab_settings_repository.dart';
import 'package:miria/repository/time_line_repository.dart';
import 'package:miria/repository/user_list_time_line_repository.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:miria/state_notifier/common/download_file_notifier.dart';
import 'package:miria/state_notifier/common/misskey_server_list_notifier.dart';
import 'package:miria/state_notifier/note_create_page/note_create_state_notifier.dart';
import 'package:miria/state_notifier/photo_edit_page/photo_edit_state_notifier.dart';
Expand Down Expand Up @@ -263,3 +264,6 @@ final misskeyServerListNotifierProvider = AsyncNotifierProvider.autoDispose<
MisskeyServerListNotifier, List<JoinMisskeyInstanceInfo>>(
MisskeyServerListNotifier.new,
);

final downloadFileNotifierProvider =
NotifierProvider<DownloadFileNotifier, void>(DownloadFileNotifier.new);
48 changes: 48 additions & 0 deletions lib/state_notifier/common/download_file_notifier.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:miria/providers.dart';
import 'package:misskey_dart/misskey_dart.dart' hide Permission;
import 'package:permission_handler/permission_handler.dart';

class DownloadFileNotifier extends Notifier<void> {
@override
void build() {
return;
}

Future<void> downloadFile(DriveFile driveFile) async {
if (defaultTargetPlatform == TargetPlatform.android) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
final permissionStatus = await Permission.storage.status;
if (permissionStatus.isDenied) {
await Permission.storage.request();
}
} else {
final permissionStatus = await Permission.photos.status;
if (permissionStatus.isDenied) {
await Permission.photos.request();
}
}
}

final tempDir = ref.read(fileSystemProvider).systemTempDirectory;
final savePath = "${tempDir.path}/${driveFile.name}";

await ref.read(dioProvider).download(
driveFile.url,
savePath,
options: Options(
responseType: ResponseType.bytes,
),
);

await ImageGallerySaver.saveFile(
savePath,
name: driveFile.name,
);
}
}
44 changes: 12 additions & 32 deletions lib/view/common/image_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import 'dart:math';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:miria/providers.dart';
import 'package:miria/view/common/misskey_notes/network_image.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:misskey_dart/misskey_dart.dart';

class ImageDialog extends ConsumerStatefulWidget {
final List<String> imageUrlList;
final List<DriveFile> driveFiles;
final int initialPage;

const ImageDialog({
super.key,
required this.imageUrlList,
required this.driveFiles,
required this.initialPage,
});

Expand Down Expand Up @@ -47,6 +44,8 @@ class ImageDialogState extends ConsumerState<ImageDialog> {

@override
Widget build(BuildContext context) {
final imageUrlList = widget.driveFiles.map((file) => file.url);

return AlertDialog(
backgroundColor: Colors.transparent,
titlePadding: EdgeInsets.zero,
Expand Down Expand Up @@ -117,7 +116,7 @@ class ImageDialogState extends ConsumerState<ImageDialog> {
? const ScrollPhysics()
: const NeverScrollableScrollPhysics(),
children: [
for (final url in widget.imageUrlList)
for (final url in imageUrlList)
ScaleNotifierInteractiveViewer(
imageUrl: url,
controller: _transformationController,
Expand Down Expand Up @@ -162,33 +161,14 @@ class ImageDialogState extends ConsumerState<ImageDialog> {
onPressed: () async {
final page = pageController.page?.toInt();
if (page == null) return;
final response = await ref.read(dioProvider).get(
widget.imageUrlList[page],
options:
Options(responseType: ResponseType.bytes));

if (defaultTargetPlatform == TargetPlatform.android) {
final androidInfo =
await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
final permissionStatus =
await Permission.storage.status;
if (permissionStatus.isDenied) {
await Permission.storage.request();
}
} else {
final permissionStatus =
await Permission.photos.status;
if (permissionStatus.isDenied) {
await Permission.photos.request();
}
}
}

await ImageGallerySaver.saveImage(response.data);
final driveFile = widget.driveFiles[page];
ref
.read(downloadFileNotifierProvider.notifier)
.downloadFile(driveFile);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("画像保存したで")));
const SnackBar(content: Text("画像保存したで")),
);
},
constraints:
const BoxConstraints(minWidth: 0, minHeight: 0),
Expand Down
29 changes: 17 additions & 12 deletions lib/view/common/misskey_notes/misskey_file_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class MisskeyFileViewState extends ConsumerState<MisskeyFileView> {
isSensitive: targetFile.isSensitive,
thumbnailUrl:
(targetFile.thumbnailUrl ?? targetFile.url).toString(),
targetFiles: [targetFile.url.toString()],
targetFiles: [targetFile],
fileType: targetFile.type,
name: targetFile.name,
position: 0,
Expand All @@ -71,7 +71,7 @@ class MisskeyFileViewState extends ConsumerState<MisskeyFileView> {
child: MisskeyImage(
isSensitive: targetFile.element.isSensitive,
thumbnailUrl: targetFile.element.thumbnailUrl?.toString(),
targetFiles: targetFiles.map((e) => e.url).toList(),
targetFiles: targetFiles,
fileType: targetFile.element.type,
name: targetFile.element.name,
position: targetFile.index,
Expand All @@ -93,7 +93,7 @@ class MisskeyFileViewState extends ConsumerState<MisskeyFileView> {
class MisskeyImage extends ConsumerStatefulWidget {
final bool isSensitive;
final String? thumbnailUrl;
final List<String> targetFiles;
final List<DriveFile> targetFiles;
final int position;
final String fileType;
final String name;
Expand Down Expand Up @@ -169,14 +169,17 @@ class MisskeyImageState extends ConsumerState<MisskeyImage> {
} else {
if (widget.fileType.startsWith("image")) {
showDialog(
context: context,
builder: (context) => ImageDialog(
imageUrlList: widget.targetFiles,
initialPage: widget.position,
));
context: context,
builder: (context) => ImageDialog(
driveFiles: widget.targetFiles,
initialPage: widget.position,
),
);
} else {
launchUrl(Uri.parse(widget.targetFiles[widget.position]),
mode: LaunchMode.externalApplication);
launchUrl(
Uri.parse(widget.targetFiles[widget.position].url),
mode: LaunchMode.externalApplication,
);
}
}
}, child: Builder(
Expand Down Expand Up @@ -232,7 +235,7 @@ class MisskeyImageState extends ConsumerState<MisskeyImage> {
height: 200,
child: NetworkImageView(
url: widget.thumbnailUrl ??
widget.targetFiles[widget.position],
widget.targetFiles[widget.position].url,
type: ImageType.imageThumbnail,
loadingBuilder: (context, widget, chunkEvent) =>
SizedBox(
Expand Down Expand Up @@ -269,7 +272,9 @@ class MisskeyImageState extends ConsumerState<MisskeyImage> {
cachedWidget = TextButton.icon(
onPressed: () {
launchUrl(
Uri.parse(widget.targetFiles[widget.position]),
Uri.parse(
widget.targetFiles[widget.position].url,
),
mode: LaunchMode.externalApplication);
},
icon: const Icon(Icons.file_download_outlined),
Expand Down
21 changes: 11 additions & 10 deletions lib/view/misskey_page_page/misskey_page_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,19 @@ class PageContent extends ConsumerWidget {
return MfmText(mfmText: content.text);
}
if (content is misskey.PageImage) {
final url = page.attachedFiles
.firstWhereOrNull((e) => e.id == content.fileId)
?.url;
final thumbnailUrl = page.attachedFiles
.firstWhereOrNull((e) => e.id == content.fileId)
?.thumbnailUrl;
if (url != null) {
final file =
page.attachedFiles.firstWhereOrNull((e) => e.id == content.fileId);
if (file != null) {
final url = file.url;
final thumbnailUrl = file.thumbnailUrl;
return GestureDetector(
onTap: () => showDialog(
context: context,
builder: (context) =>
ImageDialog(imageUrlList: [url], initialPage: 0)),
context: context,
builder: (context) => ImageDialog(
driveFiles: [file],
initialPage: 0,
),
),
child: NetworkImageView(
url: thumbnailUrl ?? url, type: ImageType.image));
} else {
Expand Down

0 comments on commit 69da27e

Please sign in to comment.