11Component[OptionsPattern[]] := With[{Class = OptionValue["Class"], Event = OptionValue["Event"], Label = OptionValue["Label"], Descr = OptionValue["Description"]},
22 {
33 <div class="flex items-center sm-controls {Class}">
4- <label id="label-#instanceId" for="#instanceId" class="relative transition-all cursor-default rounded-md 0 pl-3 pr-2 text-left text-gray-500 ring-1 ring-inset ring-gray-400 focus:outline-none focus:ring-1 focus:ring-indigo-600 sm:text-xs sm:leading-6 bg-gray-200 hover:bg-gray-100">
5- <div id="bar-#instanceId" class="absolute bg-gray-400/30 top-0 left-0 w-0 h-full z-0 rounded-md transition-all" style="width:0%"></div>
4+ <label id="label-#instanceId" for="#instanceId" class="relative transition-all cursor-default rounded-md 0 pl-3 pr-2 text-left text-gray-500 ring-1 ring-inset ring-gray-400 focus:outline-none focus:ring-1 focus:ring-indigo-600 sm:text-xs sm:leading-6 bg-gray-200 hover:bg-gray-100" style="background:white" >
5+ <div id="bar-#instanceId" class="absolute top-0 left-0 w-0 h-full z-0 rounded-md transition-all" style="width:0%"></div>
66 <div class="flex flex-col items-center justify-center py-2">
77 <p class="text-sm text-gray-500 pr-1 flex gap-x-1 items-center z-50">
88 <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" >
@@ -26,19 +26,9 @@ Component[OptionsPattern[]] := With[{Class = OptionValue["Class"], Event = Optio
2626
2727 let dragged = false;
2828
29- const splitStringIntoChunks0 = (str, chunkSize) => {
30- if (!str || chunkSize <= 0) return [];
31-
32- const chunks = [];
33- for (let i = 0; i < str.length; i += chunkSize) {
34- chunks.push(str.slice(i, Math.min(i + chunkSize, str.length)));
35- }
36- return chunks;
37- }
38-
3929 const transferFiles = (list) => {
4030 if (list.length == 0) return;
41- const id = new Date().valueOf ();
31+ const id = crypto.randomUUID ();
4232 let count = 0;
4333
4434 const progress = (num) => {
@@ -65,41 +55,50 @@ Component[OptionsPattern[]] := With[{Class = OptionValue["Class"], Event = Optio
6555 };
6656
6757 progress(0);
68- server.kernel.emitt ('<Event/>', `<|"Id" -> "${id}", " Length" -> ${ list.length}|>` , 'Transaction');
58+ server.kernel.io.fire ('<Event/>', {Id: id, Length: list.length}, 'Transaction');
6959
7060 for (const file of list) {
71- readFile(file, (name, result) => {
72- if (result.length > 5 * 1024 * 1024) {
73- const chunks = splitStringIntoChunks0(result, 5 * 1024 * 1024);
74- chunks.forEach((chunk, index) => {
75- server.kernel.emitt('<Event/>', `<|"Transaction" -> "${id}", "Chunk"->${index+1}, "Chunks"->${chunks.length}, "Name" -> "${name}", "Data" -> "${chunk}"|>`, 'Chunk');
76- });
61+ readFileChunked(file, id, (name, chunkData, chunkIndex, totalChunks) => {
62+ if (totalChunks === 1) {
63+ server.kernel.io.fire('<Event/>', {Transaction: id, Name: name, Data: chunkData}, 'File');
7764 } else {
78- server.kernel.emitt ('<Event/>', `<|" Transaction" -> "${id}", "Name" -> "${ name}", " Data" -> "${result}"|>` , 'File ');
65+ server.kernel.io.fire ('<Event/>', { Transaction: id, Chunk: chunkIndex + 1, Chunks: totalChunks, Name: name, Data: chunkData} , 'Chunk ');
7966 }
67+ }, () => {
8068 count++;
8169 progress(count);
82- })
70+ });
8371 }
8472
8573 }
8674
87- function readFile(file, cbk) {
88- const reader = new FileReader();
89- reader.addEventListener('load', (event) => {
90- let compressedData = base64ArrayBuffer(event.target.result);
91- console.log(compressedData);
92- cbk(file.name, compressedData);
93- });
94-
95- reader.addEventListener('progress', (event) => {
96- if (event.loaded && event.total) {
97- const percent = (event.loaded / event.total) * 100;
98- console.log(percent);
99- }
100- });
101-
102- reader.readAsArrayBuffer(file);
75+ function arrayBufferToBase64(buffer) {
76+ let binary = '';
77+ const bytes = new Uint8Array(buffer);
78+ for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);
79+ return btoa(binary);
80+ }
81+
82+ function readFileChunked(file, id, onChunk, onDone) {
83+ const CHUNK_BYTES = 5 * 1024 * 1024;
84+ const totalChunks = Math.ceil(file.size / CHUNK_BYTES) || 1;
85+ let chunkIndex = 0;
86+
87+ const readNext = () => {
88+ if (chunkIndex >= totalChunks) { onDone(); return; }
89+ const start = chunkIndex * CHUNK_BYTES;
90+ const slice = file.slice(start, start + CHUNK_BYTES);
91+ const reader = new FileReader();
92+ reader.addEventListener('load', (event) => {
93+ const encoded = arrayBufferToBase64(event.target.result);
94+ onChunk(file.name, encoded, chunkIndex, totalChunks);
95+ chunkIndex++;
96+ readNext();
97+ });
98+ reader.readAsArrayBuffer(slice);
99+ };
100+
101+ readNext();
103102 }
104103
105104 element.addEventListener('change', (event) => {
0 commit comments