Paste to upload

This commit is contained in:
2024-06-29 21:03:15 +08:00
parent e336d2372a
commit 49f999871a
9 changed files with 115 additions and 33 deletions

View File

@ -1,19 +1,20 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' show basename;
import 'package:solian/exts.dart';
import 'package:solian/models/attachment.dart';
import 'package:solian/platform.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/providers/content/attachment.dart';
import 'package:super_clipboard/super_clipboard.dart';
import 'package:super_drag_and_drop/super_drag_and_drop.dart';
class AttachmentPublishPopup extends StatefulWidget {
@ -153,10 +154,48 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
setState(() => _isBusy = false);
}
void pasteFileToUpload() async {
final clipboard = SystemClipboard.instance;
if (clipboard == null) return;
final reader = await clipboard.read();
for (final format in Formats.standardFormats.whereType<FileFormat>()) {
if (reader.canProvide(format)) {
reader.getFile(format, (file) async {
final data = await file.readAll();
await uploadAttachment(
data,
file.fileName ?? 'unknown',
await calculateBytesSha256(data),
);
});
}
}
}
void handlePasteFile(ClipboardReadEvent event) async {
final reader = await event.getClipboardReader();
for (final format in Formats.standardFormats.whereType<FileFormat>()) {
if (reader.canProvide(format)) {
reader.getFile(format, (file) async {
final data = await file.readAll();
await uploadAttachment(
data,
file.fileName ?? 'unknown',
await calculateBytesSha256(data),
);
});
}
}
}
Future<void> uploadAttachment(Uint8List data, String path, String hash,
{double? ratio}) async {
final AttachmentProvider provider = Get.find();
try {
context.showSnackbar((PlatformInfo.isWeb
? 'attachmentUploadingWebMode'
: 'attachmentUploading')
.trParams({'name': basename(path)}));
final resp = await provider.createAttachment(
data,
path,
@ -167,6 +206,7 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
var result = Attachment.fromJson(resp.body);
setState(() => _attachments.add(result));
widget.onUpdate(_attachments.map((e) => e!.id).toList());
context.clearSnackbar();
} catch (err) {
rethrow;
}
@ -222,11 +262,13 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
void initState() {
super.initState();
revertMetadataList();
ClipboardEvents.instance?.registerPasteEventListener(handlePasteFile);
}
@override
void dispose() {
super.dispose();
ClipboardEvents.instance?.unregisterPasteEventListener(handlePasteFile);
}
@override
@ -256,11 +298,9 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
final data = await file.readAll();
await uploadAttachment(
data,
file.fileName ?? 'attachment',
file.fileName ?? 'unknown',
await calculateBytesSha256(data),
);
}, onError: (error) {
print('Error reading value $error');
});
}
}
@ -359,6 +399,13 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
alignment: WrapAlignment.center,
runAlignment: WrapAlignment.center,
children: [
if (PlatformInfo.isDesktop)
ElevatedButton.icon(
icon: const Icon(Icons.paste),
label: Text('attachmentAddClipboard'.tr),
style: const ButtonStyle(visualDensity: density),
onPressed: () => pasteFileToUpload(),
),
ElevatedButton.icon(
icon: const Icon(Icons.add_photo_alternate),
label: Text('attachmentAddGalleryPhoto'.tr),

View File

@ -134,15 +134,17 @@ class _PostItemState extends State<PostItem> {
size: 16,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
),
Text(
'postRepliedNotify'.trParams(
{'username': '@${widget.item.replyTo!.author.name}'},
),
style: TextStyle(
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
),
).paddingOnly(left: 6),
Expanded(
child: Text(
'postRepliedNotify'.trParams(
{'username': '@${widget.item.replyTo!.author.name}'},
),
style: TextStyle(
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
),
).paddingOnly(left: 6),
),
],
).paddingOnly(left: 12),
Card(
@ -167,15 +169,17 @@ class _PostItemState extends State<PostItem> {
size: 16,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
),
Text(
'postRepostedNotify'.trParams(
{'username': '@${widget.item.repostTo!.author.name}'},
),
style: TextStyle(
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
),
).paddingOnly(left: 6),
Expanded(
child: Text(
'postRepostedNotify'.trParams(
{'username': '@${widget.item.repostTo!.author.name}'},
),
style: TextStyle(
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
),
).paddingOnly(left: 6),
),
],
).paddingOnly(left: 12),
Card(