Skip to content

Commit eeb34cc

Browse files
committed
fix: refactor(client.js): Simplify file selection event listener
Changed the event listener function names selectFile and selectDirectory to a single, more generic function name fileEvent. Removed the duplicate code in functions selectFile and fileInputChange and moved it to the new event listener function. Added an optional import parameter to trigger an import function call after successful file selection. Added a new function to export the selected data to a JSON file.
1 parent 99f48a7 commit eeb34cc

File tree

1 file changed

+104
-91
lines changed

1 file changed

+104
-91
lines changed

src/client.js

Lines changed: 104 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -31,128 +31,93 @@ function init(elements) {
3131

3232
if (elements[i].hasAttribute('directory')) {
3333
if (window.showDirectoryPicker)
34-
elements[i].addEventListener("click", selectDirectory);
34+
elements[i].addEventListener("click", fileEvent);
3535
else if ('webkitdirectory' in elements[i]) {
3636
elements[i].webkitdirectory = true
37-
elements[i].addEventListener("change", fileInputChange)
37+
elements[i].addEventListener("change", fileEvent)
3838
} else
3939
console.error("Directory selection not supported in this browser.");
4040
} else if (window.showOpenFilePicker)
41-
elements[i].addEventListener("click", selectFile);
41+
elements[i].addEventListener("click", fileEvent);
4242
else
43-
elements[i].addEventListener("change", fileInputChange);
43+
elements[i].addEventListener("change", fileEvent);
4444
}
4545
}
4646

47-
async function fileInputChange(event) {
48-
const input = event.target;
49-
const files = input.files;
50-
let selected = inputs.get(input) || new Map()
51-
for (let i = 0; i < files.length; i++) {
52-
files[i].input = input
53-
files[i].id = await getFileId(files[i])
54-
if (selected.has(files[i].id)) {
55-
console.log('Duplicate file has been selected. This could be in error as the browser does not provide a clear way of checking duplictaes')
56-
}
57-
58-
selected.set(files[i].id, files[i])
59-
}
60-
inputs.set(input, selected);
61-
console.log("FileList:", Array.from(selected.values()));
62-
renderFiles(input)
63-
}
64-
65-
async function selectFile(event) {
66-
event.preventDefault()
67-
const input = event.target;
68-
let selected = inputs.get(input) || new Map()
47+
async function fileEvent(event) {
6948
try {
70-
const multiple = input.multiple
71-
const selectedFiles = await window.showOpenFilePicker({ multiple });
72-
73-
for (const handle of selectedFiles) {
74-
let file = await handle.getFile()
75-
file.input = input
76-
file.id = await getFileId(file)
77-
if (selected.has(file.id)) {
78-
console.log('Duplicate file has been selected. This could be in error as the browser does not provide a clear way of checking duplictaes')
79-
}
80-
81-
file.handle = handle
82-
selected.set(file.id, file)
83-
}
84-
85-
if (selected.size) {
86-
inputs.set(input, selected);
87-
console.log("Files selected:", selected);
88-
renderFiles(input)
89-
}
90-
91-
} catch (error) {
92-
if (error.name !== 'AbortError') {
93-
console.error("Error selecting files:", error);
94-
}
95-
}
96-
}
49+
const input = event.target;
50+
let selected = inputs.get(input) || new Map()
51+
52+
let files = input.files;
53+
if (!files.length) {
54+
event.preventDefault()
55+
const multiple = input.multiple
56+
if (input.hasAttribute('directory')) {
57+
let handle = await window.showDirectoryPicker();
58+
let file = {
59+
name: handle.name,
60+
directory: '/',
61+
path: '/' + handle.name,
62+
type: 'text/directory',
63+
'content-type': 'text/directory'
64+
}
65+
file.input = input
66+
file.id = await getFileId(file)
67+
if (selected.has(file.id)) {
68+
console.log('Duplicate file has been selected. This could be in error as the browser does not provide a clear way of checking duplictaes')
69+
}
9770

98-
async function selectDirectory(event) {
99-
event.preventDefault()
100-
const input = event.target;
101-
let selected = inputs.get(input) || new Map()
71+
file.handle = handle
72+
selected.set(file.id, file)
10273

103-
try {
104-
const handle = await window.showDirectoryPicker();
105-
let file = {
106-
name: handle.name,
107-
directory: '/',
108-
path: '/' + handle.name,
109-
type: 'text/directory',
110-
'content-type': 'text/directory'
111-
}
112-
file.input = input
113-
file.id = await getFileId(file)
114-
if (selected.has(file.id)) {
115-
console.log('Duplicate file has been selected. This could be in error as the browser does not provide a clear way of checking duplictaes')
74+
files = await getDirectoryHandles(handle, handle.name)
75+
} else {
76+
files = await window.showOpenFilePicker({ multiple });
77+
}
11678
}
11779

118-
file.handle = handle
119-
selected.set(file.id, file)
120-
121-
const handles = await getSelectedDirectoryHandles(handle, handle.name)
122-
for (let i = 0; i < handles.length; i++) {
123-
let file = handles[i]
124-
if (handles[i].kind === 'file') {
125-
file = await handles[i].getFile();
126-
file.directory = handles[i].directory
127-
file.parentDirectory = handles[i].parentDirectory
128-
file.path = handles[i].path
80+
for (let i = 0; i < files.length; i++) {
81+
const handle = files[i]
82+
if (files[i].kind === 'file') {
83+
files[i] = await files[i].getFile();
84+
files[i].handle = handle
85+
} else if (files[i].kind === 'directory') {
86+
files[i].handle = handle
12987
}
13088

131-
file.input = input
132-
file.id = await getFileId(file)
133-
if (selected.has(file.id)) {
89+
files[i].directory = handle.directory || '/'
90+
files[i].parentDirectory = handle.parentDirectory || ''
91+
files[i].path = handle.path || '/' + handle.name
92+
files[i]['content-type'] = files[i].type
93+
files[i].input = input
94+
files[i].id = await getFileId(files[i])
95+
if (selected.has(files[i].id)) {
13496
console.log('Duplicate file has been selected. This could be in error as the browser does not provide a clear way of checking duplictaes')
13597
}
13698

137-
file.handle = handles[i]
138-
file['content-type'] = file.type
139-
140-
selected.set(file.id, file)
99+
selected.set(files[i].id, files[i])
141100
}
142101

143102
if (selected.size) {
144103
inputs.set(input, selected);
145-
console.log("Directory selected:", selected);
104+
console.log("Files selected:", selected);
146105
renderFiles(input)
106+
const isImport = input.getAttribute('import')
107+
if (isImport || isImport == "") {
108+
Import(input)
109+
}
110+
147111
}
148112
} catch (error) {
149113
if (error.name !== 'AbortError') {
150114
console.error("Error selecting directory:", error);
151115
}
152116
}
117+
153118
}
154119

155-
async function getSelectedDirectoryHandles(handle, name) {
120+
async function getDirectoryHandles(handle, name) {
156121
let handles = [];
157122
for await (const entry of handle.values()) {
158123
entry.directory = '/' + name
@@ -166,7 +131,7 @@ async function getSelectedDirectoryHandles(handle, name) {
166131
} else if (entry.kind === 'directory') {
167132
entry.type = 'text/directory'
168133
handles.push(entry);
169-
const entries = await getSelectedDirectoryHandles(entry, name + '/' + entry.name);
134+
const entries = await getDirectoryHandles(entry, name + '/' + entry.name);
170135
handles = handles.concat(entries);
171136
}
172137
}
@@ -449,6 +414,54 @@ async function Import(input) {
449414
return response
450415
}
451416

417+
async function Export(btn) {
418+
const item_id = btn.getAttribute('template_id');
419+
let item = this.items.get(item_id)
420+
if (!item) return;
421+
422+
423+
let Item = new Object(item)
424+
Item.filter.startIndex = 0;
425+
delete Item.el
426+
delete Item.count
427+
428+
let data;
429+
if (crud) {
430+
data = await crud.readDocument(Item);
431+
}
432+
// TODO: get from local data source
433+
exportFile(data);
434+
}
435+
436+
async function exportFile(data) {
437+
let file_name = data.type || 'download';
438+
let exportData = JSON.stringify(data.document, null, 4);
439+
let blob = new Blob([exportData], { type: "application/json" });
440+
let url = URL.createObjectURL(blob);
441+
442+
let link = document.createElement("a");
443+
444+
link.href = url;
445+
link.download = file_name;
446+
447+
document.body.appendChild(link);
448+
449+
link.dispatchEvent(
450+
new MouseEvent('click', {
451+
bubbles: true,
452+
cancelable: true,
453+
view: window
454+
})
455+
);
456+
457+
URL.revokeObjectURL(url);
458+
link.remove();
459+
460+
document.dispatchEvent(new CustomEvent('exported', {
461+
detail: {}
462+
}));
463+
}
464+
452465
async function create(directory, type, name, src = "") {
453466
try {
454467
if (directory.handle && directory.input) {

0 commit comments

Comments
 (0)