@cocreate/file 1.14.2 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [1.15.1](https://github.com/CoCreate-app/CoCreate-file/compare/v1.15.0...v1.15.1) (2024-02-13)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add file.size and add missing object param ([32f8508](https://github.com/CoCreate-app/CoCreate-file/commit/32f85080079dcb91fee2bb294b72d16d769b3440))
7
+
8
+ # [1.15.0](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.2...v1.15.0) (2024-02-05)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Removed https://cdn.cocreate.app/latest/CoCreate.min.css ([e0ae28d](https://github.com/CoCreate-app/CoCreate-file/commit/e0ae28de52a02ee58947093f6dad3dd9dfee93e8))
14
+ * renderValue ([4e3308a](https://github.com/CoCreate-app/CoCreate-file/commit/4e3308a157ee2257bc1eb603ddc1484b5579cac8))
15
+ * typo renderValue condition ([65ba50f](https://github.com/CoCreate-app/CoCreate-file/commit/65ba50fe6a84e02bad033f423d39a0ab22fdb766))
16
+
17
+
18
+ ### Features
19
+
20
+ * setValue() ([44d4012](https://github.com/CoCreate-app/CoCreate-file/commit/44d40127823d7ccdf8286943b435eeff939e6e2f))
21
+
1
22
  ## [1.14.2](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.1...v1.14.2) (2024-01-17)
2
23
 
3
24
 
package/demo/index.html CHANGED
@@ -32,10 +32,26 @@
32
32
  <button actions="upload">upload</button>
33
33
  </form>
34
34
 
35
+ <div
36
+ type="file"
37
+ array="test"
38
+ object=""
39
+ key="image"
40
+ accept="image/*"
41
+ placeholder="Upload Image or Video Thumbnail"
42
+ class="floating-label min-height:40px active"
43
+ render-selector="[template]"
44
+ active>
45
+ <div template>
46
+ <img src="{{image.src}}" alt="image" width="100%" />
47
+ </div>
48
+ </div>
49
+
35
50
  <form>
36
51
  <input
37
52
  type="file"
38
53
  directory
54
+ realtime="false"
39
55
  render-selector="document; [template]" />
40
56
 
41
57
  <button actions="saveLocally">saveLocally</button>
package/docs/index.html CHANGED
@@ -21,11 +21,6 @@
21
21
  property="og:image"
22
22
  content="https://cdn.cocreate.app/docs/file.png" />
23
23
 
24
- <!-- CoCreate CSS -->
25
- <link
26
- rel="stylesheet"
27
- href="https://cdn.cocreate.app/latest/CoCreate.min.css"
28
- type="text/css" />
29
24
  <link
30
25
  rel="stylesheet"
31
26
  href="../index.css"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/file",
3
- "version": "1.14.2",
3
+ "version": "1.15.1",
4
4
  "description": "A headless file uploader that uses HTML5 attributes for customization. Allows easy upload of files to server.",
5
5
  "keywords": [
6
6
  "file",
package/src/client.js CHANGED
@@ -26,7 +26,7 @@ import Observer from '@cocreate/observer';
26
26
  import Crud from '@cocreate/crud-client';
27
27
  import Elements from '@cocreate/elements';
28
28
  import Actions from '@cocreate/actions';
29
- import render from '@cocreate/render';
29
+ import { render } from '@cocreate/render';
30
30
  import { queryElements } from '@cocreate/utils';
31
31
  import '@cocreate/element-prototype';
32
32
 
@@ -42,38 +42,67 @@ const Files = new Map();
42
42
  * - If a single element is provided, it initializes that element (assuming it is of type "file").
43
43
  * - If an array of elements is provided, each element in the array is initialized.
44
44
  */
45
- function init(elements) {
45
+ async function init(elements) {
46
46
  if (!elements)
47
47
  elements = document.querySelectorAll('[type="file"]')
48
48
  else if (!Array.isArray(elements))
49
49
  elements = [elements]
50
50
  for (let i = 0; i < elements.length; i++) {
51
- if (elements[i].tagName !== 'INPUT') {
52
- // TODO: create input and append to div if input dos not exist
53
- // check if input exist
54
- let input = document.createElement("input");
55
- input.type = "file";
56
- input.setAttribute('hidden', '')
57
- elements[i].appendChild(input);
51
+ let nestedInput, isInput = elements[i].tagName === 'INPUT'
52
+ if (!isInput) {
53
+ nestedInput = elements[i].querySelector('input[type="file"]')
58
54
  }
59
55
 
60
56
  elements[i].getValue = async () => await getFiles([elements[i]])
61
57
  elements[i].getFiles = async () => await getFiles([elements[i]])
58
+ elements[i].setValue = (files) => setFiles(elements[i], files);
59
+ elements[i].renderValue = (files) => setFiles(elements[i], files);
62
60
 
63
- // elements[i].setValue = (value) => pickr.setColor(value);
61
+ // if (elements[i].renderValue) {
62
+ // let data = await elements[i].getValue()
63
+ // if (data)
64
+ // elements[i].setValue(data)
65
+ // }
64
66
 
65
67
  if (elements[i].hasAttribute('directory')) {
66
- if (window.showDirectoryPicker)
68
+ if (!isInput && window.showDirectoryPicker)
67
69
  elements[i].addEventListener("click", fileEvent);
68
70
  else if ('webkitdirectory' in elements[i]) {
69
71
  elements[i].webkitdirectory = true
70
- elements[i].addEventListener("change", fileEvent)
72
+ if (!isInput && !nestedInput) {
73
+ nestedInput = document.createElement("input");
74
+ nestedInput.type = "file";
75
+ nestedInput.setAttribute('hidden', '')
76
+ elements[i].appendChild(nestedInput);
77
+ }
78
+
79
+ if (nestedInput) {
80
+ elements[i].addEventListener("click", function () {
81
+ nestedInput.click()
82
+ });
83
+ nestedInput.addEventListener("change", fileEvent);
84
+ } else
85
+ elements[i].addEventListener("change", fileEvent);
71
86
  } else
72
87
  console.error("Directory selection not supported in this browser.");
73
- } else if (window.showOpenFilePicker)
88
+ } else if (!isInput && window.showOpenFilePicker)
74
89
  elements[i].addEventListener("click", fileEvent);
75
- else
76
- elements[i].addEventListener("change", fileEvent);
90
+ else {
91
+ if (!isInput && !nestedInput) {
92
+ nestedInput = document.createElement("input");
93
+ nestedInput.type = "file";
94
+ nestedInput.setAttribute('hidden', '')
95
+ elements[i].appendChild(nestedInput);
96
+ }
97
+
98
+ if (nestedInput) {
99
+ elements[i].addEventListener("click", function () {
100
+ nestedInput.click()
101
+ });
102
+ nestedInput.addEventListener("change", fileEvent);
103
+ } else
104
+ elements[i].addEventListener("change", fileEvent);
105
+ }
77
106
  }
78
107
  }
79
108
 
@@ -82,7 +111,7 @@ async function fileEvent(event) {
82
111
  const input = event.target;
83
112
  let selected = inputs.get(input) || new Map()
84
113
  let files = input.files;
85
- if (!files.length) {
114
+ if (!files || !files.length) {
86
115
  event.preventDefault()
87
116
  const multiple = input.multiple
88
117
  if (input.hasAttribute('directory')) {
@@ -120,7 +149,10 @@ async function fileEvent(event) {
120
149
  }
121
150
 
122
151
  if (!files[i].src)
123
- files[i] = await readFile(files[i])
152
+ await readFile(files[i])
153
+
154
+ if (!files[i].size)
155
+ files[i].size = handle.size
124
156
 
125
157
  files[i].directory = handle.directory || '/'
126
158
  files[i].path = handle.path || '/'
@@ -140,15 +172,14 @@ async function fileEvent(event) {
140
172
  inputs.set(input, selected);
141
173
  console.log("Files selected:", selected);
142
174
 
143
- if (!input.renderValue)
144
- input.renderValue(selected.values())
175
+ if (input.renderValue)
176
+ input.renderValue(Array.from(selected.values()))
145
177
 
146
178
  const isImport = input.getAttribute('import')
147
179
  const isRealtime = input.getAttribute('realtime')
148
180
  if (isRealtime !== 'false' && (isImport || isImport == "")) {
149
181
  Import(input)
150
182
  }
151
-
152
183
  }
153
184
  } catch (error) {
154
185
  if (error.name !== 'AbortError') {
@@ -201,12 +232,14 @@ async function getFiles(fileInputs) {
201
232
  for (let input of fileInputs) {
202
233
  const selected = inputs.get(input)
203
234
  if (selected) {
204
- for (let file of selected.values()) {
235
+ for (let file of Array.from(selected.values())) {
205
236
  if (!file.src)
206
- file = await readFile(file)
237
+ await readFile(file)
238
+ let fileObject = { ...file }
239
+ fileObject.size = file.size
240
+ await getCustomData(fileObject)
207
241
 
208
- file = await getCustomData({ ...file })
209
- files.push(file)
242
+ files.push(fileObject)
210
243
  }
211
244
  }
212
245
  }
@@ -214,7 +247,6 @@ async function getFiles(fileInputs) {
214
247
  return files
215
248
  }
216
249
 
217
- // gets file custom data
218
250
  async function getCustomData(file) {
219
251
  let form = document.querySelector(`[file_id="${file.id}"]`);
220
252
  if (form) {
@@ -226,10 +258,12 @@ async function getCustomData(file) {
226
258
  }
227
259
  }
228
260
  }
261
+
262
+ delete file.input;
263
+
229
264
  return file;
230
265
  }
231
266
 
232
-
233
267
  // This function reads the file and returns its src
234
268
  function readFile(file) {
235
269
  return new Promise((resolve) => {
@@ -238,14 +272,11 @@ function readFile(file) {
238
272
 
239
273
  if (fileType[1] === 'directory') {
240
274
  return resolve(file)
241
- } else if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileType[1])
242
- || fileType[0] === 'image') {
275
+ } else if (fileType[0] === 'image') {
243
276
  readAs = 'readAsDataURL';
244
- } else if (['mp4', 'avi', 'mov', 'mpeg', 'flv'].includes(fileType[1])
245
- || fileType[0] === 'video') {
277
+ } else if (fileType[0] === 'video') {
246
278
  readAs = 'readAsDataURL';
247
- } if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
248
- || fileType[0] === 'audio') { // updated condition
279
+ } else if (fileType[0] === 'audio') {
249
280
  readAs = 'readAsDataURL';
250
281
  } else if (fileType[1] === 'pdf') {
251
282
  readAs = 'readAsDataURL';
@@ -269,6 +300,24 @@ function readFile(file) {
269
300
  });
270
301
  }
271
302
 
303
+ function setFiles(element, files) {
304
+ if (!files) return
305
+ if (!Array.isArray(files))
306
+ files = [files]
307
+ else if (!files.length)
308
+ return
309
+
310
+ let selected = inputs.get(element) || new Map()
311
+ for (let i = 0; i < files.length; i++) {
312
+ files[i].input = element
313
+ selected.set(files[i].id, files[i])
314
+ Files.set(files[i].id, files[i])
315
+ }
316
+ inputs.set(element, selected);
317
+ if (element.renderValue)
318
+ render({ source: element, data: Array.from(selected.values()) })
319
+ }
320
+
272
321
  async function save(element, action, data) {
273
322
  try {
274
323
  if (!data)
@@ -382,13 +431,11 @@ async function upload(element, data) {
382
431
  if (Data.type === 'key')
383
432
  Data.type = 'object'
384
433
 
385
- if (Data.type === 'object') {
386
- let object = input.getAttribute('object')
387
- if (key) {
388
- Data[Data.type] = { _id: object, [key]: files }
389
- } else {
390
- Data[Data.type] = files
391
- }
434
+ let object = input.getAttribute('object')
435
+ if (key) {
436
+ Data[Data.type] = { _id: object, [key]: files }
437
+ } else {
438
+ Data[Data.type] = files
392
439
  }
393
440
 
394
441
  Data.method = Data.type + '.update'