8000 Disk view plugged · arduino/lab-micropython-editor@ce9c5dc · GitHub
[go: up one dir, main page]

Skip to content

Commit ce9c5dc

Browse files
committed
Disk view plugged
1 parent 63cc099 commit ce9c5dc

File tree

7 files changed

+123
-87
lines changed

7 files changed

+123
-87
lines changed

index.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,31 @@ function listFolder(folder, filesOnly) {
2626
return files
2727
}
2828

29+
function ilistFolder(folder, filesOnly) {
30+
let files = fs.readdirSync(path.resolve(folder))
31+
files = files.map(f => {
32+
let filePath = path.resolve(folder, f)
33+
return {
34+
path: f,
35+
type: fs.lstatSync(filePath).isDirectory() ? 'folder' : 'file'
36+
}
37+
})
38+
// Filter out directories
39+
if (filesOnly) {
40+
files = files.filter(f => f.type === 'file')
41+
}
42+
// Filter out dot files
43+
files = files.filter(f => f.path.indexOf('.') !== 0)
44+
return files
45+
}
46+
2947
// LOCAL FILE SYSTEM ACCESS
3048
ipcMain.handle('open-folder', async (event) => {
3149
console.log('ipcMain', 'open-folder')
3250
const folder = await openFolderDialog()
3351
let files = []
3452
if (folder) {
35-
files = listFolder(folder)
53+
files = ilistFolder(folder)
3654
}
3755
return { folder, files }
3856
})
@@ -43,6 +61,12 @@ ipcMain.handle('list-files', async (event, folder) => {
4361
return listFolder(folder)
4462
})
4563

64+
ipcMain.handle('ilist-files', async (event, folder) => {
65+
console.log('ipcMain', 'ilist-files', folder)
66+
if (!folder) return []
67+
return ilistFolder(folder)
68+
})
69+
4670
ipcMain.handle('load-file', (event, folder, filename) => {
4771
console.log('ipcMain', 'load-file', folder, filename )
4872
let filePath = path.resolve(folder, filename)

preload.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ const Disk = {
8787
listFiles: async (folder) => {
8888
return ipcRenderer.invoke('list-files', folder)
8989
},
90+
ilistFiles: async (folder) => {
91+
return ipcRenderer.invoke('ilist-files', folder)
92+
},
9093
loadFile: async (folder, file) => {
9194
let content = await ipcRenderer.invoke('load-file', folder, file)
9295
return new TextDecoder().decode(content)

ui/ftp/components/diskView.tsx

Lines changed: 62 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,75 @@
11
import React from 'react'
22

3+
import {
4+
File,
5+
DeviceType
6+
} from '../main.type.ts'
7+
8+
type DiskViewParams = {
9+
waiting: Boolean,
10+
diskPath: String
11+
diskFiles: File[]
12+
selectedFiles: File[]
13+
openFolder: () => void
14+
selectFile: (file: File) => void
15+
navigate: (path: String) => void
16+
}
17+
318
const DiskView: React.FC = ({ logic }) => {
4-
const { waiting } = logic()
19+
const {
20+
waiting = true,
21+
diskPath,
22+
diskFiles = [],
23+
selectedFiles = [],
24+
openFolder,
25+
selectFile,
26+
navigate
27+
} : DiskViewParams = logic()
28+
29+
const ListItem = (file: File, i: number) => {
30+
const onClick = () => {
31+
if (file.type === 'file') {
32+
selectFile(file)
33+
} else {
34+
navigate(diskPath + '/' + file.path)
35+
}
36+
}
37+
const checked = selectedFiles
38+
.filter(f => f.device === DeviceType.disk)
39+
.find(f => f.path === file.path)
40+
const icon = file.type === 'file'
41+
? <div className="checkbox">📄</div>
42+
: <div className="checkbox">📁</div>
43+
return (
44+
<div className={`list-item ${checked?'checked':''}`} key={i} onClick={onClick}>
45+
{icon}<span>{file.path}</span>
46+
</div>
47+
)
48+
}
49+
50+
const NavigationItem = (name: string, i:number) => {
51+
const crumbs = diskPath.split('/').filter(c => c !== '')
52+
const path = '/' + crumbs.slice(0, i).join('/')
53+
return (
54+
<button key={i} onClick={() => navigate(path)}>{name}</button>
55+
)
56+
}
57+
let diskPathArray = []
58+
if (diskPath) {
59+
diskPathArray = ['/'].concat(
60+
diskPath.split('/').filter(s => s !== '')
61+
)
62+
}
563
return (
664
<div className="column file-panel">
765
<div className="toolbar row full-width">
8-
<button>Select folder</button>
66+
<button onClick={openFolder}>Select folder</button>
967
</div>
1068
<div className="row full-width navigation">
11-
<button>/</button>
12-
<button>home</button>
13-
<button>projects</button>
14-
<button>arduino</button>
15-
<button>micropython</button>
16-
<button>example</button>
69+
{diskPathArray.map(NavigationItem)}
1770
</div>
1871
<div className="column full-width full-height list">
19-
<div className="list-item">
20-
<div className="checkbox">📁</div>
21-
lib
22-
</div>
23-
<div className="list-item">
24-
<input type="checkbox" />
25-
<span>boot.py</span>
26-
</div>
27-
<div className="list-item">
28-
<input type="checkbox" />
29-
<span>main.py</span>
30-
</div>
31-
<div className="list-item">
32-
<input type="checkbox" />
33-
<span>turing_machine.py</span>
34-
</div>
35-
<div className="list-item">
36-
<input type="checkbox" />
37-
<span>README.md</span>
38-
</div>
39-
<div className="list-item">
40-
<div className="checkbox">📁</div>
41-
lib
42-
</div>
43-
<div className="list-item">
44-
<input type="checkbox" />
45-
<span>boot.py</span>
46-
</div>
47-
<div className="list-item">
48-
<input type="checkbox" />
49-
<span>main.py</span>
50-
</div>
51-
<div className="list-item">
52-
<input type="checkbox" />
53-
<span>turing_machine.py</span>
54-
</div>
55-
<div className="list-item">
56-
<input type="checkbox" />
57-
<span>README.md</span>
58-
</div>
59-
<div className="list-item">
60-
<div className="checkbox">📁</div>
61-
lib
62-
</div>
63-
<div className="list-item">
64-
<input type="checkbox" />
65-
<span>boot.py</span>
66-
</div>
67-
<div className="list-item">
68-
<input type="checkbox" />
69-
<span>main.py</span>
70-
</div>
71-
<div className="list-item">
72-
<input type="checkbox" />
73-
<span>turing_machine.py</span>
74-
</div>
75-
<div className="list-item">
76-
<input type="checkbox" />
77-
<span>README.md</span>
78-
</div>
72+
{diskFiles.map(ListItem)}
7973
</div>
8074
</div>
8175
)

ui/ftp/components/serialView.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ type SerialParams = () => {
1515
connect: (path: string) => void
1616
disconnect: () => void
1717
selectFile: (path: string) => void
18-
refresh: () => void
1918
navigate: (path: string) => void
2019
}
2120

ui/ftp/main.logic.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ export const useMainLogic = function() {
2020

2121
// HELPERS
2222
const navigateDisk = async (newPath) => {
23-
const files = await BridgeDisk.listFiles(newPath)
23+
setWaiting(true)
2424
setDiskPath(newPath)
25-
setDiskFiles(files)
25+
await refreshDiskFiles(newPath)
2626
const newSelection = selectedFiles.filter(f => f.device !== DeviceType.disk)
2727
setSelectedFiles(newSelection)
28+
setWaiting(false)
2829
}
2930

3031
const navigateSerial = async (newPath) => {
@@ -36,11 +37,12 @@ export const useMainLogic = function() {
3637
setWaiting(false)
3738
}
3839

39-
const refreshSerialFiles = async (path) => {
40+
const refreshSerialFiles = async (path: String) => {
4041
const detailedFiles = await BridgeSerial.ilistFiles(path)
4142
const folders = detailedFiles.filter(f => f[1] === FileType.folder) || []
4243
const files = detailedFiles.filter(f => f[1] === FileType.file) || []
43-
const sortedFiles = folders.concat(files)
44+
const sortedFiles = folders
45+
.concat(files)
4446
.map(f => ({
4547
path: f[0],
4648
type: (f[1] === FileType.folder) ? 'folder' : 'file',
@@ -50,9 +52,18 @@ export const useMainLogic = function() {
5052
setSerialFiles(sortedFiles)
5153
}
5254

53-
const refreshDiskFiles = async () => {
54-
const files = await BridgeDisk.listFiles(diskPath)
55-
setDiskFiles(files)
55+
const refreshDiskFiles = async (path: String) => {
56+
const detailedFiles = await BridgeDisk.ilistFiles(path)
57+
const folders = detailedFiles.filter(f => f.type === 'folder') || []
58+
const files = detailedFiles.filter(f => f.type === 'file') || []
59+
const sortedFiles = folders
60+
.concat(files)
61+
.map(f => ({
62+
path: f.path,
63+
type: f.type,
64+
device: DeviceType.disk
65+
}))
66+
setDiskFiles(sortedFiles)
5667
}
5768

5869
const refresh = async () => {
@@ -64,7 +75,7 @@ export const useMainLogic = function() {
6475
if (connectedDevice) await refreshSerialFiles(serialPath)
6576
else setSerialFiles([])
6677
// list disk files
67-
if (diskPath) await refreshDiskFiles()
78+
if (diskPath) await refreshDiskFiles(diskPath)
6879
else setDiskFiles([])
6980

7081
setWaiting(false)
@@ -103,7 +114,6 @@ export const useMainLogic = function() {
103114
setSelectedFiles(serialFilesOnly.slice())
104115
}
105116
},
106-
refresh: refresh,
107117
navigate: navigateSerial,
108118
})
109119
const diskLogic = () => ({
@@ -113,20 +123,21 @@ export const useMainLogic = function() {
113123
openFolder: async () => {
114124
const { folder, files } = await BridgeDisk.openFolder()
115125
setDiskPath(folder)
116-
setDiskFiles(files)
126+
await refreshDiskFiles(folder)
117127
},
118-
selectFile: (path) => {
128+
selectFile: (file: File) => {
119129
const diskFilesOnly = selectedFiles.filter(f => f.device === DeviceType.disk)
120-
const selected = diskFilesOnly.find(f => f.path === path)
130+
const selected = diskFilesOnly.find(f => f.path === file.path)
121131
if (selected) {
122-
let newSelection = diskFilesOnly.filter(f => f.path !== path)
132+
let newSelection = diskFilesOnly.filter(f => f.path !== file.path)
123133
setSelectedFiles(newSelection)
124134
} else {
125-
let file = {
126-
path: path,
135+
let f = {
136+
path: file.path,
137+
type: file.type,
127138
device: DeviceType.disk
128139
}
129-
diskFilesOnly.push(file)
140+
diskFilesOnly.push(f)
130141
setSelectedFiles(diskFilesOnly.slice())
131142
}
132143
},

ui/ftp/main.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ main {
8282
.list-item {
8383
padding: var(--base-size) 5px;
8484
cursor: pointer;
85+
display: flex;
8586
.checkbox, input[type="checkbox"] {
8687
display: inline-block;
8788
width: 50px;
@@ -95,6 +96,10 @@ main {
9596
background: var(--highlight-color);
9697
color: var(--light-color);
9798
font-weight: bold;
99+
100+
&:hover {
101+
opacity: 0.85;
102+
}
98103
}
99104
}
100105

ui/ftp/main.type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export type File = {
55
path: String
66
type: FileType
77
device: Device
8-
size: Number
8+
size?: Number
99
}
1010

1111
export type AvailableDevice = {

0 commit comments

Comments
 (0)
0