Skip to content

Commit 54524d1

Browse files
authored
Merge pull request #108 from arduino/feature/alert-unsaved
Alert user before closing tab with unsaved changes
2 parents a13ffdc + 36c473f commit 54524d1

File tree

4 files changed

+63
-25
lines changed

4 files changed

+63
-25
lines changed

ui/arduino/store.js

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ async function store(state, emitter) {
4848
parentFolder: null, // Null parent folder means not saved?
4949
source: 'disk'
5050
})
51+
newFile.editor.onChange = function() {
52+
newFile.hasChanges = true
53+
emitter.emit('render')
54+
}
5155
state.openFiles.push(newFile)
5256
state.editingFile = newFile.id
5357

@@ -351,6 +355,7 @@ async function store(state, emitter) {
351355
log('error', e)
352356
}
353357

358+
openFile.hasChanges = false
354359
state.isSaving = false
355360
state.savingProgress = 0
356361
emitter.emit('refresh-files')
@@ -365,6 +370,11 @@ async function store(state, emitter) {
365370
})
366371
emitter.on('close-tab', (id) => {
367372
log('close-tab', id)
373+
const currentTab = state.openFiles.find(f => f.id === id)
374+
if (currentTab.hasChanges && currentTab.parentFolder !== null) {
375+
let response = confirm("Your file has unsaved changes. Are you sure you want to proceed?")
376+
if (!response) return false
377+
}
368378
state.openFiles = state.openFiles.filter(f => f.id !== id)
369379
// state.editingFile = null
370380

@@ -375,6 +385,10 @@ async function store(state, emitter) {
375385
source: 'disk',
376386
parentFolder: null
377387
})
388+
newFile.editor.onChange = function() {
389+
newFile.hasChanges = true
390+
emitter.emit('render')
391+
}
378392
state.openFiles.push(newFile)
379393
state.editingFile = newFile.id
380394
}
@@ -995,6 +1009,7 @@ async function store(state, emitter) {
9951009
}
9961010
}
9971011

1012+
openFile.hasChanges = false
9981013
state.renamingTab = null
9991014
state.isSaving = false
10001015
state.savingProgress = 0
@@ -1037,43 +1052,49 @@ async function store(state, emitter) {
10371052
let files = []
10381053
for (let i in state.selectedFiles) {
10391054
let selectedFile = state.selectedFiles[i]
1055+
let openFile = null
10401056
if (selectedFile.type == 'folder') {
10411057
// Don't open folders
10421058
continue
10431059
}
1044-
if (selectedFile.source === 'board') {
1060+
if (selectedFile.source == 'board') {
10451061
const fileContent = await serial.loadFile(
10461062
serial.getFullPath(
10471063
'/',
10481064
state.boardNavigationPath,
10491065
selectedFile.fileName
10501066
)
10511067
)
1052-
files.push(
1053-
createFile({
1054-
parentFolder: state.boardNavigationPath,
1055-
fileName: selectedFile.fileName,
1056-
source: selectedFile.source,
1057-
content: fileContent
1058-
})
1059-
)
1060-
} else {
1068+
openFile = createFile({
1069+
parentFolder: state.boardNavigationPath,
1070+
fileName: selectedFile.fileName,
1071+
source: selectedFile.source,
1072+
content: fileContent
1073+
})
1074+
openFile.editor.onChange = function() {
1075+
openFile.hasChanges = true
1076+
emitter.emit('render')
1077+
}
1078+
} else if (selectedFile.source == 'disk') {
10611079
const fileContent = await disk.loadFile(
10621080
disk.getFullPath(
10631081
state.diskNavigationRoot,
10641082
state.diskNavigationPath,
10651083
selectedFile.fileName
10661084
)
10671085
)
1068-
files.push(
1069-
createFile({
1070-
parentFolder: state.diskNavigationPath,
1071-
fileName: selectedFile.fileName,
1072-
source: selectedFile.source,
1073-
content: fileContent
1074-
})
1075-
)
1086+
openFile = createFile({
1087+
parentFolder: state.diskNavigationPath,
1088+
fileName: selectedFile.fileName,
1089+
source: selectedFile.source,
1090+
content: fileContent
1091+
})
1092+
openFile.editor.onChange = function() {
1093+
openFile.hasChanges = true
1094+
emitter.emit('render')
1095+
}
10761096
}
1097+
files.push(openFile)
10771098
}
10781099

10791100
files = files.filter((f) => { // find files to open
@@ -1280,11 +1301,17 @@ async function store(state, emitter) {
12801301
emitter.emit('render')
12811302
})
12821303

1283-
function createFile({ source, parentFolder, fileName, content = newFileContent }) {
1304+
function createFile(args) {
1305+
const {
1306+
source,
1307+
parentFolder,
1308+
fileName,
1309+
content = newFileContent,
1310+
hasChanges = false
1311+
} = args
12841312
const id = generateHash()
12851313
const editor = state.cache(CodeMirrorEditor, `editor_${id}`)
12861314
editor.content = content
1287-
const hasChanges = false
12881315
return {
12891316
id,
12901317
source,
@@ -1300,6 +1327,7 @@ async function store(state, emitter) {
13001327
fileName: generateFileName(),
13011328
parentFolder,
13021329
source,
1330+
hasChanges: true
13031331
})
13041332
}
13051333
}

ui/arduino/views/components/elements/editor.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ class CodeMirrorEditor extends Component {
77

88
load(el) {
99
const onCodeChange = (update) => {
10-
this.content = update.state.doc.toString()
1110
// console.log('code change', this.content)
11+
this.content = update.state.doc.toString()
12+
this.onChange()
1213
}
1314
this.editor = createEditor(this.content, el, onCodeChange)
14-
1515
}
1616

1717
createElement(content) {
@@ -22,4 +22,8 @@ class CodeMirrorEditor extends Component {
2222
update() {
2323
return false
2424
}
25+
26+
onChange() {
27+
return false
28+
}
2529
}

ui/arduino/views/components/elements/tab.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ function Tab(args) {
88
onFinishRenaming = () => false,
99
disabled = false,
1010
active = false,
11-
renaming = false
11+
renaming = false,
12+
hasChanges = false
1213
} = args
1314

1415
if (active) {
@@ -41,7 +42,9 @@ function Tab(args) {
4142
return html`
4243
<div class="tab active" tabindex="0">
4344
<img class="icon" src="media/${icon}" />
44-
<div class="text" ondblclick=${onStartRenaming}>${text}</div>
45+
<div class="text" ondblclick=${onStartRenaming}>
46+
${hasChanges ? ' *' : ''} ${text}
47+
</div>
4548
<div class="options" >
4649
<button onclick=${onCloseTab}>
4750
<img class="icon" src="media/close.svg" />
@@ -65,7 +68,9 @@ function Tab(args) {
6568
onclick=${selectTab}
6669
>
6770
<img class="icon" src="media/${icon}" />
68-
<div class="text">${text}</div>
71+
<div class="text">
72+
${hasChanges ? '*' : ''} ${text}
73+
</div>
6974
<div class="options">
7075
<button onclick=${onCloseTab}>
7176
<img class="icon" src="media/close.svg" />

ui/arduino/views/components/tabs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ function Tabs(state, emit) {
77
icon: file.source === 'board'? 'connect.svg': 'computer.svg',
88
active: file.id === state.editingFile,
99
renaming: file.id === state.renamingTab,
10+
hasChanges: file.hasChanges,
1011
onSelectTab: () => emit('select-tab', file.id),
1112
onCloseTab: () => emit('close-tab', file.id),
1213
onStartRenaming: () => emit('rename-tab', file.id),

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