Preview ({mimeType})
diff --git a/frontend/app/view/view.less b/frontend/app/view/view.less
index 3700d347..3a1fcb2c 100644
--- a/frontend/app/view/view.less
+++ b/frontend/app/view/view.less
@@ -63,4 +63,8 @@
object-fit: contain;
}
}
+ &.view-preview-directory {
+ flex-direction: column;
+ align-items: start;
+ }
}
diff --git a/frontend/app/workspace/workspace.tsx b/frontend/app/workspace/workspace.tsx
index 2d03b794..4b5384de 100644
--- a/frontend/app/workspace/workspace.tsx
+++ b/frontend/app/workspace/workspace.tsx
@@ -92,6 +92,9 @@ function Widgets() {
clickPreview("build/appicon.png")}>
+
clickPreview("~")}>
+
+
clickPlot()}>
diff --git a/pkg/service/fileservice/fileservice.go b/pkg/service/fileservice/fileservice.go
index a1c486f1..c66c81d0 100644
--- a/pkg/service/fileservice/fileservice.go
+++ b/pkg/service/fileservice/fileservice.go
@@ -5,6 +5,7 @@ package fileservice
import (
"encoding/base64"
+ "encoding/json"
"fmt"
"os"
"path/filepath"
@@ -41,9 +42,9 @@ func (fs *FileService) StatFile(path string) (*FileInfo, error) {
if err != nil {
return nil, fmt.Errorf("cannot stat file %q: %w", path, err)
}
- mimeType := utilfn.DetectMimeType(path)
+ mimeType := utilfn.DetectMimeType(cleanedPath)
return &FileInfo{
- Path: wavebase.ReplaceHomeDir(path),
+ Path: cleanedPath,
Size: finfo.Size(),
Mode: finfo.Mode(),
ModTime: finfo.ModTime().UnixMilli(),
@@ -63,6 +64,35 @@ func (fs *FileService) ReadFile(path string) (*FullFile, error) {
if finfo.Size > MaxFileSize {
return nil, fmt.Errorf("file %q is too large to read, use /wave/stream-file", path)
}
+ if finfo.IsDir {
+ innerFilesEntries, err := os.ReadDir(finfo.Path)
+ if err != nil {
+ return nil, fmt.Errorf("unable to parse directory %s", finfo.Path)
+ }
+
+ var innerFilesInfo []FileInfo
+ for _, innerFileEntry := range innerFilesEntries {
+ innerFileInfoInt, _ := innerFileEntry.Info()
+ innerFileInfo := FileInfo{
+ Path: innerFileInfoInt.Name(),
+ Size: innerFileInfoInt.Size(),
+ Mode: innerFileInfoInt.Mode(),
+ ModTime: innerFileInfoInt.ModTime().UnixMilli(),
+ IsDir: innerFileInfoInt.IsDir(),
+ MimeType: "",
+ }
+ innerFilesInfo = append(innerFilesInfo, innerFileInfo)
+ }
+
+ filesSerialized, err := json.Marshal(innerFilesInfo)
+ if err != nil {
+ return nil, fmt.Errorf("unable to serialize files %s", finfo.Path)
+ }
+ return &FullFile{
+ Info: finfo,
+ Data64: base64.StdEncoding.EncodeToString(filesSerialized),
+ }, nil
+ }
cleanedPath := filepath.Clean(wavebase.ExpandHomeDir(path))
barr, err := os.ReadFile(cleanedPath)
if err != nil {
diff --git a/pkg/util/utilfn/utilfn.go b/pkg/util/utilfn/utilfn.go
index ae568d63..f18b98ef 100644
--- a/pkg/util/utilfn/utilfn.go
+++ b/pkg/util/utilfn/utilfn.go
@@ -634,6 +634,13 @@ func DetectMimeType(path string) string {
if mimeType := mime.TypeByExtension(ext); mimeType != "" {
return mimeType
}
+ stats, err := os.Stat(path)
+ if err != nil {
+ return ""
+ }
+ if stats.IsDir() {
+ return "directory"
+ }
fd, err := os.Open(path)
if err != nil {
return ""