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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy