Skip to content

Commit 1e43d2d

Browse files
authored
Merge pull request #99 from arduino/feature/rename-files
Rename files
2 parents 7c043c7 + bf20272 commit 1e43d2d

File tree

4 files changed

+199
-27
lines changed

4 files changed

+199
-27
lines changed

ui/arduino2/main.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,9 @@ button.small .icon {
501501

502502
.file-list .item .options {
503503
display: none;
504-
padding: 5px;
505504
align-items: center;
506505
align-self: stretch;
506+
cursor: pointer;
507507
}
508508

509509
.file-list .item:hover .options {
@@ -548,9 +548,13 @@ button.small .icon {
548548
}
549549

550550
.file-list .item input {
551+
box-sizing: border-box;
551552
border: none;
552553
border-radius: none;
553554
height: 100%;
555+
width: 100%;
554556
background: rgba(255, 255, 255, 0.5);
555557
font-family: inherit;
558+
font-size: inherit;
559+
outline-color: #F4BA00;
556560
}

ui/arduino2/media/cursor.svg

+3
Loading

ui/arduino2/store.js

+139-4
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,6 @@ async function store(state, emitter) {
589589
return
590590
}
591591

592-
593592
for (let i in state.selectedFiles) {
594593
const file = state.selectedFiles[i]
595594
if (file.type == 'folder') {
@@ -637,8 +636,145 @@ async function store(state, emitter) {
637636
emitter.emit('render')
638637
})
639638

640-
emitter.on('rename-file', () => { /* TODO */ })
641-
emitter.on('finish-renaming', () => { /* TODO */ })
639+
emitter.on('rename-file', (source, item) => {
640+
log('rename-file', source, item)
641+
state.renamingFile = source
642+
emitter.emit('render')
643+
})
644+
emitter.on('finish-renaming', async (value) => {
645+
log('finish-renaming', value)
646+
647+
// You can only rename one file, the selected one
648+
const file = state.selectedFiles[0]
649+
650+
if (!value || file.fileName == value) {
651+
state.renamingFile = null
652+
emitter.emit('render')
653+
return
654+
}
655+
656+
state.isSaving = true
657+
emitter.emit('render')
658+
659+
// Check if new name overwrites something
660+
if (state.renamingFile == 'board' && state.isConnected) {
661+
// Check if it will overwrite something
662+
const willOverwrite = await checkOverwrite({
663+
fileNames: [ value ],
664+
parentPath: disk.getFullPath(
665+
state.boardNavigationRoot, state.boardNavigationPath, ''
666+
),
667+
source: 'board'
668+
})
669+
if (willOverwrite.length > 0) {
670+
let message = `You are about to overwrite the following file/folder on your board:\n\n`
671+
message += `${value}\n\n`
672+
message += `Are you sure you want to proceed?`
673+
const confirmAction = confirm(message, 'Cancel', 'Yes')
674+
if (!confirmAction) {
675+
state.isSaving = false
676+
state.renamingFile = null
677+
emitter.emit('render')
678+
return
679+
}
680+
681+
if (file.type == 'folder') {
682+
await removeBoardFolder(
683+
serial.getFullPath(
684+
state.boardNavigationRoot,
685+
state.boardNavigationPath,
686+
value
687+
)
688+
)
689+
} else if (file.type == 'file') {
690+
await serial.removeFile(
691+
serial.getFullPath(
692+
state.boardNavigationRoot,
693+
state.boardNavigationPath,
694+
value
695+
)
696+
)
697+
}
698+
}
699+
} else if (state.renamingFile == 'disk') {
700+
// Check if it will overwrite something
701+
const willOverwrite = await checkOverwrite({
702+
fileNames: [ value ],
703+
parentPath: disk.getFullPath(
704+
state.diskNavigationRoot, state.diskNavigationPath, ''
705+
),
706+
source: 'disk'
707+
})
708+
if (willOverwrite.length > 0) {
709+
let message = `You are about to overwrite the following file/folder on your disk:\n\n`
710+
message += `${value}\n\n`
711+
message += `Are you sure you want to proceed?`
712+
const confirmAction = confirm(message, 'Cancel', 'Yes')
713+
if (!confirmAction) {
714+
state.isSaving = false
715+
state.renamingFile = null
716+
emitter.emit('render')
717+
return
718+
}
719+
720+
if (file.type == 'folder') {
721+
await disk.removeFolder(
722+
disk.getFullPath(
723+
state.diskNavigationRoot,
724+
state.diskNavigationPath,
725+
value
726+
)
727+
)
728+
} else if (file.type == 'file') {
729+
await disk.removeFile(
730+
disk.getFullPath(
731+
state.diskNavigationRoot,
732+
state.diskNavigationPath,
733+
value
734+
)
735+
)
736+
}
737+
738+
}
739+
}
740+
741+
try {
742+
if (state.renamingFile == 'board') {
743+
await serial.renameFile(
744+
serial.getFullPath(
745+
state.boardNavigationRoot,
746+
state.boardNavigationPath,
747+
file.fileName
748+
),
749+
serial.getFullPath(
750+
state.boardNavigationRoot,
751+
state.boardNavigationPath,
752+
value
753+
)
754+
)
755+
} else {
756+
await disk.renameFile(
757+
disk.getFullPath(
758+
state.diskNavigationRoot,
759+
state.diskNavigationPath,
760+
file.fileName
761+
),
762+
disk.getFullPath(
763+
state.diskNavigationRoot,
764+
state.diskNavigationPath,
765+
value
766+
)
767+
)
768+
}
769+
} catch (e) {
770+
alert(`The file ${file.fileName} could not be renamed to ${value}`)
771+
}
772+
773+
state.isSaving = false
774+
state.renamingFile = null
775+
emitter.emit('refresh-files')
776+
emitter.emit('render')
777+
})
642778

643779
emitter.on('toggle-file-selection', (file, source, event) => {
644780
log('toggle-file-selection', file, source, event)
@@ -1018,7 +1154,6 @@ async function checkBoardFile({ root, parentFolder, fileName }) {
10181154

10191155
async function checkOverwrite({ fileNames = [], parentPath, source }) {
10201156
let files = []
1021-
let overwrite = []
10221157
if (source === 'board') {
10231158
files = await getBoardFiles(parentPath)
10241159
} else {

ui/arduino2/views/components/file-list.js

+52-22
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,84 @@ function generateFileList(source) {
1313
}
1414
}
1515

16+
const newFileItem = html`
17+
<div class="item">
18+
<img class="icon" src="media/file.svg" />
19+
<div class="text">
20+
<input type="text" onkeydown=${onKeyEvent} onblur=${(e) => emit('finish-creating-file', e.target.value)}/>
21+
</div>
22+
</div>
23+
`
24+
const newFolderItem = html`
25+
<div class="item">
26+
<img class="icon" src="media/folder.svg" />
27+
<div class="text">
28+
<input type="text" onkeydown=${onKeyEvent} onblur=${(e) => emit('finish-creating-folder', e.target.value)}/>
29+
</div>
30+
</div>
31+
`
32+
1633
function FileItem(item, i) {
34+
const renamingFileItem = html`
35+
<input type="text"
36+
value=${item.fileName}
37+
onkeydown=${onKeyEvent}
38+
onblur=${(e) => emit('finish-renaming', e.target.value)}
39+
onclick=${(e) => false}
40+
ondblclick=${(e) => false}
41+
/>
42+
`
1743
const isChecked = state.selectedFiles.find(
1844
f => f.fileName === item.fileName && f.source === source
1945
)
46+
function renameItem(e) {
47+
e.preventDefault()
48+
emit('rename-file', source, item)
49+
return false
50+
}
51+
function navigateToFolder() {
52+
if (!state.renamingFile) emit(`navigate-${source}-folder`, item.fileName)
53+
}
54+
function openFile() {
55+
if (!state.renamingFile) emit(`open-file`, source, item)
56+
}
57+
let fileName = item.fileName
58+
const isSelected = state.selectedFiles.find(f => f.fileName === fileName)
59+
60+
if (state.renamingFile == source && isSelected) {
61+
fileName = renamingFileItem
62+
}
2063
if (item.type === 'folder') {
2164
return html`
2265
<div
2366
class="item ${isChecked ? 'selected' : ''}"
24-
ondblclick=${() => emit(`navigate-${source}-folder`, item.fileName)}
2567
onclick=${(e) => emit('toggle-file-selection', item, source, e)}
68+
ondblclick=${navigateToFolder}
2669
>
2770
<img class="icon" src="media/folder.svg" />
28-
<div class="text">${item.fileName}</div>
71+
<div class="text">${fileName}</div>
72+
<div class="options" onclick=${renameItem}>
73+
<img src="media/cursor.svg" />
74+
</div>
2975
</div>
3076
`
3177
} else {
3278
return html`
3379
<div
3480
class="item ${isChecked ? 'selected' : ''}"
3581
onclick=${(e) => emit('toggle-file-selection', item, source, e)}
36-
ondblclick=${() => emit(`open-file`, source, item)}
82+
ondblclick=${openFile}
3783
>
3884
<img class="icon" src="media/file.svg" />
39-
<div class="text">${item.fileName}</div>
40-
<div class="options" onclick=${() => console.log('options', item)}>
41-
<img src="media/falafel.svg" />
85+
<div class="text">${fileName}</div>
86+
<div class="options" onclick=${renameItem}>
87+
<img src="media/cursor.svg" />
4288
</div>
4389
</div>
4490
`
4591
}
4692
}
4793

48-
const newFileItem = html`
49-
<div class="item">
50-
<img class="icon" src="media/file.svg" />
51-
<div class="text">
52-
<input type="text" onkeydown=${onKeyEvent} onblur=${(e) => emit('finish-creating-file', e.target.value)}/>
53-
</div>
54-
</div>
55-
`
56-
const newFolderItem = html`
57-
<div class="item">
58-
<img class="icon" src="media/folder.svg" />
59-
<div class="text">
60-
<input type="text" onkeydown=${onKeyEvent} onblur=${(e) => emit('finish-creating-folder', e.target.value)}/>
61-
</div>
62-
</div>
63-
`
6494
// XXX: Use `source` to filter an array of files with a `source` as proprety
6595
const list = html`
6696
<div class="file-list">

0 commit comments

Comments
 (0)