✨ File list drag and drop
This commit is contained in:
@@ -99,9 +99,7 @@ class FileListScreen extends HookConsumerWidget {
|
|||||||
completer.future
|
completer.future
|
||||||
.then((uploadedFile) {
|
.then((uploadedFile) {
|
||||||
if (uploadedFile != null) {
|
if (uploadedFile != null) {
|
||||||
// Refresh the file list after successful upload
|
|
||||||
ref.invalidate(cloudFileListNotifierProvider);
|
ref.invalidate(cloudFileListNotifierProvider);
|
||||||
showSnackBar('File uploaded successfully');
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catchError((error) {
|
.catchError((error) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:desktop_drop/desktop_drop.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
@@ -5,8 +6,10 @@ import 'package:gap/gap.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/file_list_item.dart';
|
import 'package:island/models/file_list_item.dart';
|
||||||
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/pods/file_list.dart';
|
import 'package:island/pods/file_list.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/services/file_uploader.dart';
|
||||||
import 'package:island/utils/format.dart';
|
import 'package:island/utils/format.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
@@ -36,6 +39,8 @@ class FileListView extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final dragging = useState(false);
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
if (mode.value == FileListMode.normal) {
|
if (mode.value == FileListMode.normal) {
|
||||||
final notifier = ref.read(cloudFileListNotifierProvider.notifier);
|
final notifier = ref.read(cloudFileListNotifierProvider.notifier);
|
||||||
@@ -291,7 +296,52 @@ class FileListView extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
return Column(
|
return DropTarget(
|
||||||
|
onDragDone: (details) async {
|
||||||
|
dragging.value = false;
|
||||||
|
// Handle file upload
|
||||||
|
for (final file in details.files) {
|
||||||
|
final universalFile = UniversalFile(
|
||||||
|
data: file,
|
||||||
|
type: UniversalFileType.file,
|
||||||
|
displayName: file.name,
|
||||||
|
);
|
||||||
|
|
||||||
|
final completer = FileUploader.createCloudFile(
|
||||||
|
fileData: universalFile,
|
||||||
|
ref: ref,
|
||||||
|
path: currentPath.value,
|
||||||
|
onProgress: (progress, _) {
|
||||||
|
// Progress is handled by the upload tasks system
|
||||||
|
if (progress != null) {
|
||||||
|
debugPrint('Upload progress: ${(progress * 100).toInt()}%');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
completer.future
|
||||||
|
.then((uploadedFile) {
|
||||||
|
if (uploadedFile != null) {
|
||||||
|
ref.invalidate(cloudFileListNotifierProvider);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catchError((error) {
|
||||||
|
showSnackBar('Failed to upload file: $error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDragEntered: (details) {
|
||||||
|
dragging.value = true;
|
||||||
|
},
|
||||||
|
onDragExited: (details) {
|
||||||
|
dragging.value = false;
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color:
|
||||||
|
dragging.value
|
||||||
|
? Theme.of(context).primaryColor.withOpacity(0.1)
|
||||||
|
: null,
|
||||||
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
_buildPathNavigation(ref, currentPath),
|
_buildPathNavigation(ref, currentPath),
|
||||||
@@ -301,12 +351,15 @@ class FileListView extends HookConsumerWidget {
|
|||||||
slivers: [
|
slivers: [
|
||||||
bodyWidget,
|
bodyWidget,
|
||||||
const SliverGap(12),
|
const SliverGap(12),
|
||||||
if (mode.value == FileListMode.normal && currentPath.value == '/')
|
if (mode.value == FileListMode.normal &&
|
||||||
|
currentPath.value == '/')
|
||||||
SliverToBoxAdapter(child: _buildUnindexedFilesEntry(ref)),
|
SliverToBoxAdapter(child: _buildUnindexedFilesEntry(ref)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <desktop_drop/desktop_drop_plugin.h>
|
||||||
#include <file_saver/file_saver_plugin.h>
|
#include <file_saver/file_saver_plugin.h>
|
||||||
#include <file_selector_linux/file_selector_plugin.h>
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
#include <flutter_platform_alert/flutter_platform_alert_plugin.h>
|
#include <flutter_platform_alert/flutter_platform_alert_plugin.h>
|
||||||
@@ -29,6 +30,9 @@
|
|||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) desktop_drop_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin");
|
||||||
|
desktop_drop_plugin_register_with_registrar(desktop_drop_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) file_saver_registrar =
|
g_autoptr(FlPluginRegistrar) file_saver_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin");
|
||||||
file_saver_plugin_register_with_registrar(file_saver_registrar);
|
file_saver_plugin_register_with_registrar(file_saver_registrar);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
desktop_drop
|
||||||
file_saver
|
file_saver
|
||||||
file_selector_linux
|
file_selector_linux
|
||||||
flutter_platform_alert
|
flutter_platform_alert
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import connectivity_plus
|
import connectivity_plus
|
||||||
|
import desktop_drop
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
import file_picker
|
import file_picker
|
||||||
import file_saver
|
import file_saver
|
||||||
@@ -48,6 +49,7 @@ import window_manager
|
|||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||||
|
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||||
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
|
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- croppy (0.0.1):
|
- croppy (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- desktop_drop (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- file_picker (0.0.1):
|
- file_picker (0.0.1):
|
||||||
@@ -258,6 +260,7 @@ PODS:
|
|||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
|
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
|
||||||
- croppy (from `Flutter/ephemeral/.symlinks/plugins/croppy/macos`)
|
- croppy (from `Flutter/ephemeral/.symlinks/plugins/croppy/macos`)
|
||||||
|
- desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`)
|
||||||
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
||||||
- file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`)
|
- file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`)
|
||||||
- file_saver (from `Flutter/ephemeral/.symlinks/plugins/file_saver/macos`)
|
- file_saver (from `Flutter/ephemeral/.symlinks/plugins/file_saver/macos`)
|
||||||
@@ -327,6 +330,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
|
||||||
croppy:
|
croppy:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/croppy/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/croppy/macos
|
||||||
|
desktop_drop:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
||||||
file_picker:
|
file_picker:
|
||||||
@@ -411,6 +416,7 @@ EXTERNAL SOURCES:
|
|||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e
|
connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e
|
||||||
croppy: d9bfc8c02f3cd1851f669a421df298a474b78f43
|
croppy: d9bfc8c02f3cd1851f669a421df298a474b78f43
|
||||||
|
desktop_drop: 10a3e6a7fa9dbe350541f2574092fecfa345a07b
|
||||||
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
||||||
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
|
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
|
||||||
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
|
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
|
||||||
|
|||||||
@@ -393,6 +393,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.11"
|
version: "0.7.11"
|
||||||
|
desktop_drop:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: desktop_drop
|
||||||
|
sha256: e70b46b2d61f1af7a81a40d1f79b43c28a879e30a4ef31e87e9c27bea4d784e8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.0"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ dependencies:
|
|||||||
flutter_expandable_fab: ^2.5.2
|
flutter_expandable_fab: ^2.5.2
|
||||||
event_bus: ^2.0.1
|
event_bus: ^2.0.1
|
||||||
convert: ^3.1.2
|
convert: ^3.1.2
|
||||||
|
desktop_drop: ^0.7.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||||
#include <dart_ipc/dart_ipc_plugin_c_api.h>
|
#include <dart_ipc/dart_ipc_plugin_c_api.h>
|
||||||
|
#include <desktop_drop/desktop_drop_plugin.h>
|
||||||
#include <file_saver/file_saver_plugin.h>
|
#include <file_saver/file_saver_plugin.h>
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||||
@@ -42,6 +43,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||||
DartIpcPluginCApiRegisterWithRegistrar(
|
DartIpcPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("DartIpcPluginCApi"));
|
registry->GetRegistrarForPlugin("DartIpcPluginCApi"));
|
||||||
|
DesktopDropPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("DesktopDropPlugin"));
|
||||||
FileSaverPluginRegisterWithRegistrar(
|
FileSaverPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FileSaverPlugin"));
|
registry->GetRegistrarForPlugin("FileSaverPlugin"));
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
connectivity_plus
|
connectivity_plus
|
||||||
dart_ipc
|
dart_ipc
|
||||||
|
desktop_drop
|
||||||
file_saver
|
file_saver
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
firebase_core
|
firebase_core
|
||||||
|
|||||||
Reference in New Issue
Block a user