Compare commits
2 Commits
14a86b8ae1
...
260b8b180e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
260b8b180e | ||
|
|
4f67ead22d |
@@ -24,10 +24,18 @@ class UploadBloc extends Bloc<UploadEvent, UploadState> {
|
||||
|
||||
for (final file in event.files) {
|
||||
try {
|
||||
print(
|
||||
'[UploadBloc] Starting upload for ${file.name} to orgId=${event.orgId}, path=${file.path}',
|
||||
);
|
||||
print(
|
||||
'[UploadBloc] File bytes: ${file.bytes?.length ?? 0} bytes, localPath: ${file.localPath}',
|
||||
);
|
||||
// Simulate upload
|
||||
await _fileRepository.uploadFile(event.orgId, file);
|
||||
print('[UploadBloc] Upload successful for ${file.name}');
|
||||
add(UploadCompleted(file));
|
||||
} catch (e) {
|
||||
print('[UploadBloc] Upload failed for ${file.name}: $e');
|
||||
add(UploadFailed(fileName: file.name, error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,6 +665,14 @@ class _FileExplorerState extends State<FileExplorer> {
|
||||
return BlocListener<UploadBloc, UploadState>(
|
||||
listener: (context, uploadState) {
|
||||
if (uploadState is UploadInProgress) {
|
||||
// Show error if any upload failed
|
||||
for (final upload in uploadState.uploads) {
|
||||
if (upload.error != null && upload.error!.isNotEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Upload failed: ${upload.error}')),
|
||||
);
|
||||
}
|
||||
}
|
||||
final hasCompleted = uploadState.uploads.any((u) => u.isCompleted);
|
||||
if (hasCompleted) {
|
||||
final fbState = context.read<FileBrowserBloc>().state;
|
||||
|
||||
@@ -52,18 +52,32 @@ class FileService {
|
||||
// If bytes or localPath available, send multipart upload with field 'file'
|
||||
final Map<String, dynamic> fields = {'path': file.path};
|
||||
FormData formData;
|
||||
print(
|
||||
'[FileService] uploadFile: file=${file.name}, path=${file.path}, orgId=$orgId',
|
||||
);
|
||||
print(
|
||||
'[FileService] bytes=${file.bytes?.length ?? 0}, localPath=${file.localPath}',
|
||||
);
|
||||
|
||||
if (file.bytes != null) {
|
||||
print(
|
||||
'[FileService] Using bytes for upload (${file.bytes!.length} bytes)',
|
||||
);
|
||||
formData = FormData.fromMap({
|
||||
...fields,
|
||||
'file': MultipartFile.fromBytes(file.bytes!, filename: file.name),
|
||||
});
|
||||
} else if (file.localPath != null) {
|
||||
print('[FileService] Using localPath for upload: ${file.localPath}');
|
||||
formData = FormData.fromMap({
|
||||
...fields,
|
||||
'file': MultipartFile.fromFile(file.localPath!, filename: file.name),
|
||||
});
|
||||
} else {
|
||||
// Fallback to metadata-only create (folders or client that can't send file content)
|
||||
print(
|
||||
'[FileService] No bytes or localPath; falling back to metadata-only',
|
||||
);
|
||||
final data = {
|
||||
'name': file.name,
|
||||
'path': file.path,
|
||||
@@ -82,19 +96,10 @@ class FileService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (orgId.isEmpty) {
|
||||
await _apiClient.post(
|
||||
'/user/files',
|
||||
data: formData,
|
||||
fromJson: (d) => null,
|
||||
);
|
||||
return;
|
||||
}
|
||||
await _apiClient.post(
|
||||
'/orgs/$orgId/files',
|
||||
data: formData,
|
||||
fromJson: (d) => null,
|
||||
);
|
||||
final endpoint = orgId.isEmpty ? '/user/files' : '/orgs/$orgId/files';
|
||||
print('[FileService] Uploading to endpoint: $endpoint');
|
||||
await _apiClient.post(endpoint, data: formData, fromJson: (d) => null);
|
||||
print('[FileService] Upload completed for ${file.name}');
|
||||
}
|
||||
|
||||
Future<void> deleteFile(String orgId, String path) async {
|
||||
|
||||
BIN
go_cloud/api
BIN
go_cloud/api
Binary file not shown.
@@ -968,17 +968,17 @@ func createOrgFileHandler(w http.ResponseWriter, r *http.Request, db *database.D
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Save to disk under data/uploads/orgs/<orgId>/<parentPath>
|
||||
baseDir := filepath.Join("data", "uploads", "orgs", orgID.String())
|
||||
// Fallback: Save to temp directory (WebDAV should be the primary storage)
|
||||
baseDir := filepath.Join("/tmp", "uploads", "orgs", orgID.String())
|
||||
targetDir := filepath.Join(baseDir, parentPath)
|
||||
if err = os.MkdirAll(targetDir, 0o755); err != nil {
|
||||
errors.LogError(r, err, "Failed to create target dir")
|
||||
errors.LogError(r, err, "Failed to create target dir in /tmp")
|
||||
errors.WriteError(w, errors.CodeInternal, "Server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
outPath := filepath.Join(targetDir, header.Filename)
|
||||
if err = os.WriteFile(outPath, data, 0o644); err != nil {
|
||||
errors.LogError(r, err, "Failed to write file")
|
||||
errors.LogError(r, err, "Failed to write file to /tmp")
|
||||
errors.WriteError(w, errors.CodeInternal, "Server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -1148,17 +1148,17 @@ func createUserFileHandler(w http.ResponseWriter, r *http.Request, db *database.
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: write to disk
|
||||
baseDir := filepath.Join("data", "uploads", "users", userID.String())
|
||||
// Fallback: write to temp directory (WebDAV should be the primary storage)
|
||||
baseDir := filepath.Join("/tmp", "uploads", "users", userID.String())
|
||||
targetDir := filepath.Join(baseDir, parentPath)
|
||||
if err = os.MkdirAll(targetDir, 0o755); err != nil {
|
||||
errors.LogError(r, err, "Failed to create target dir")
|
||||
errors.LogError(r, err, "Failed to create target dir in /tmp")
|
||||
errors.WriteError(w, errors.CodeInternal, "Server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
outPath := filepath.Join(targetDir, header.Filename)
|
||||
if err = os.WriteFile(outPath, data, 0o644); err != nil {
|
||||
errors.LogError(r, err, "Failed to create file")
|
||||
errors.LogError(r, err, "Failed to write file to /tmp")
|
||||
errors.WriteError(w, errors.CodeInternal, "Server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user