Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
24f967c
functionality to add multiple files
nikeetaa231 Aug 30, 2022
d252e11
WIP multiple upload story
nikeetaa231 Aug 30, 2022
da67b8e
css change for slot designs
sabirveli Aug 30, 2022
3e2e179
story fixes
sabirveli Aug 30, 2022
4e6e371
designs using slot WIP
sabirveli Aug 30, 2022
3151030
some fixes
nikeetaa231 Aug 30, 2022
be0e12f
Merge branch 'file-uploader-changes' of https://github.com/kws3media/…
nikeetaa231 Aug 30, 2022
a26a865
Merge branch 'master' into file-uploader-changes
nikeetaa231 Aug 30, 2022
88c8b0c
slot props for boxed design
sabirveli Aug 30, 2022
9be0452
some css fix for dynamic designs
sabirveli Aug 30, 2022
bc362d4
boxed design for testing
sabirveli Aug 30, 2022
7f666b6
drag and drop functionality
sabirveli Aug 31, 2022
aa56cdf
slot design fixes for multiple files upload
nikeetaa231 Aug 31, 2022
9970e26
custom design
sabirveli Aug 31, 2022
af59ccc
component fixes
sabirveli Aug 31, 2022
df93899
fixes
nikeetaa231 Aug 31, 2022
222ce74
Merge branch 'file-uploader-changes' of https://github.com/kws3media/…
nikeetaa231 Aug 31, 2022
fdf029c
fixes
nikeetaa231 Aug 31, 2022
86ed613
multiple upload fixes
nikeetaa231 Aug 31, 2022
8711d1d
remove console logging
nikeetaa231 Aug 31, 2022
0f43580
multiple designs
sabirveli Aug 31, 2022
fff039b
css fixes
sabirveli Aug 31, 2022
366db82
param fixes
sabirveli Aug 31, 2022
dfb5207
merge multiple files decorator to file upload
nikeetaa231 Aug 31, 2022
523801d
separate component for multiple upload
nikeetaa231 Aug 31, 2022
01f3f4e
fixes
nikeetaa231 Aug 31, 2022
32ea4dc
remove multiple file upload story
nikeetaa231 Aug 31, 2022
3e9cab7
single story for both multiple and single upload
sabirveli Aug 31, 2022
bf082b1
remove seperate component for multiple
sabirveli Aug 31, 2022
ce10930
fixes
sabirveli Aug 31, 2022
77bdd90
WIP Cloud file upload component
nikeetaa231 Sep 1, 2022
4c631ca
import cloud upload component
nikeetaa231 Sep 1, 2022
91ad140
variable type fixes
nikeetaa231 Sep 1, 2022
59bbeda
upload helper
nikeetaa231 Sep 1, 2022
b006c1c
cloud file upload decorator component
nikeetaa231 Sep 1, 2022
a3c7066
example for cloud upload
nikeetaa231 Sep 1, 2022
f616b1d
cloud uploader migration WIP
sabirveli Sep 2, 2022
694fda0
Merge branch 'master' into file-uploader-changes
nikeetaa231 Sep 5, 2022
7afd2c6
services
sabirveli Sep 5, 2022
b91b84e
cloud prop
sabirveli Sep 5, 2022
bf1fff0
cloud upload fix
sabirveli Sep 5, 2022
fc55acf
comp fixes
sabirveli Sep 5, 2022
5de8903
cloud uploader dependencies
sabirveli Sep 5, 2022
f1a609d
remove commented code
nikeetaa231 Sep 6, 2022
94f32b8
Merge branch 'master' into file-uploader-changes
nikeetaa231 Sep 7, 2022
cb9289f
Fixes for image refresh
sabirveli Sep 13, 2022
6f73938
upload progress
sabirveli Sep 13, 2022
3df5d5a
upload notification helper comps
sabirveli Sep 14, 2022
3bb6857
integrate notification
sabirveli Sep 14, 2022
ec2ba65
reset once uploaded
nikeetaa231 Sep 21, 2022
0a18fb6
refactor code for cloud upload design
nikeetaa231 Sep 22, 2022
0c92bf1
fixes
nikeetaa231 Sep 22, 2022
157112c
jsdoc type for new properties
nikeetaa231 Sep 22, 2022
1448f79
Merge branch 'master' into file-uploader-changes
ekhaled May 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
"svelte-eslint-parser": "^0.14.0",
"svelte-loader": "^3.1.2",
"svelte-preprocess": "^4.8.0",
"svelte2tsx": "^0.6.11",
"sveltedoc-parser": "github:ekhaled/sveltedoc-parser#custom",
"typescript": "^5.0.4"
"sveltedoc-parser": "https://github.com/ekhaled/sveltedoc-parser#integration",
"promis": "^1.1.4",
"microevent": "https://github.com/ekhaled/microevent.js.git"
}
}
339 changes: 339 additions & 0 deletions packages/@kws3/ui/controls/CloudFileUpload.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
<div
class="kws-cloud-file-uploader {klass} {_is_dragging ? 'is-dragging' : ''}"
on:dragenter={dragenter}
on:dragleave={dragleave}
on:drop={drop}>
<form bind:this={formElement} on:submit|preventDefault={handleSubmit}>
<slot>
<div class="file has-name is-fullwidth is-{size} is-{color} {klass}">
<label class="file-label" for="">
<span class="file-cta">
<span class="icon">
<Icon icon="plus" size="small" />
</span>
<span class="f-label"> {label} </span>
</span>
<span class="file-name">
<div>
<span class="help">
Max size: {maxFileSize}
</span>
</div>

<div style="max-width:100%;white-space:normal">
<span class="help has-text-centered">{fileTypes}</span>
</div>
</span>
</label>
</div>
</slot>
<div class="drop-on-me">{drag_msg}</div>
<input
class="file-input"
bind:this={uploadElement}
multiple
type="file"
name="file"
{accept}
on:change={updateState} />
</form>
</div>

{#if failedValidation.length}
<ul>
{#each failedValidation as file}
<slot name="failed" {file}>
<li class="my-2">
<span class="has-text-danger"
><code>{file.name}</code> Not uploaded.</span
><br />
<small class="has-text-grey">{file.error_message}</small>
</li>
</slot>
{/each}
</ul>
{/if}

<script>
import { createEventDispatcher } from "svelte";
import { readable } from "svelte/store";
import { Icon } from "@kws3/ui";

/**
*
* @typedef {import('@kws3/ui/types').ColorOptions} ColorOptions
* @typedef {import('@kws3/ui/types').SizeOptions} SizeOptions
*
*/
const fire = createEventDispatcher();

/**
* @type {function}
*/
export let preparer,
/**
* @type {function}
*/
acknowledger,
/**
* @type {string}
*/
queue = "a-random-queue-name",
/**
* Size of the File Input
* @type {SizeOptions}
*/
size = "",
/**
* Color of the File Input
* @type {ColorOptions}
*/
color = "info",
/**
* Input Label Text
* @type {string}
*/
label = "Upload Files",
/**
* Drag Message
* @type {string}
*/
drag_msg = "Drop files here to upload",
/**
* Maximum File size
* @type {Number}
*/
max = 500000,
/**
* Extensions of allowed file types
* @type {string| array}
*/
allowed = "*",
/**
* Extensions of valid file types
* @type {string}
*/
accept = "*";

let klass = "";
export { klass as class };

let formElement, uploadElement, fileTypes, maxFileSize;
let failedValidation = [];

$: {
fileTypes =
allowed !== "*" && Array.isArray(allowed) && allowed.length
? allowed.join(", ")
: "";
maxFileSize = formatFileSize(max);
}

const handleSubmit = () => {};

const updateState = () => {
try {
let files = uploadElement.files;
const formattedFiles = [...files].map((f) => {
return {
name: f.name,
size: f.fileSize || f.size,
type: f.type,
blob: f,
};
});

file_chosen(formattedFiles);
} catch (e) {
console.log(e);
}
};

let _is_dragging = false;
const dragenter = () => {
_is_dragging = true;
};
const dragleave = () => {
_is_dragging = false;
};
const drop = () => {
_is_dragging = false;
};

function filter(files) {
//use this function to filter filetypes and file max allowable sizes
for (let i = 0; i < files.length; i++) {
let file = files[i];

let validateType = fileTypesValidation(file, allowed);
if (!validateType.allowed) {
file.stamp = +new Date();
file.error = true;
file.error_message = validateType.msg;
failedValidation.push(file);
files.splice(i, 1);
i--;
}

let validateSize = fileSizeValidation(file, max);

if (!validateSize.allowed) {
file.stamp = +new Date();
file.error = true;
file.error_message = validateSize.msg;
failedValidation.push(file);
files.splice(i, 1);
i--;
}
}
return files;
}

function file_chosen(files) {
//reset failedValidation list
failedValidation = [];

filter(files).forEach((file) => {
const queueItem = readable(null, (set) => {
/**
* @type {Object}
*/
const statusObject = {
status: "preparing",
loaded: 0,
total: file.size,
progress: 0,
original_name: file.name,
url: "",
ack_payload: {},
};
set(statusObject);

preparer({ file: file.name })
.then((r) => {
//console.log(r.response);

const endpoint = r.response;

const { url } = endpoint;

statusObject.url = url.split("?")[0];
set(statusObject);

fire("upload", { endpoint });
// Net.raw(
// {
// url: url,
// method: "PUT",
// body: file.blob,
// onprogress: (e) => {
// statusObject.status = "uploading";
// statusObject.loaded = e.loaded;
// statusObject.total = e.total;
// statusObject.progress = Math.round(
// (e.loaded / e.total) * 100
// );
// set(statusObject);
// },
// headers: {
// "x-amz-acl": acl,
// },
// },
// true
// )
// .then(() => {
// statusObject.status = "completing";
// set(statusObject);

// acknowledger({
// bucket,
// folder,
// name,
// original_name,
// driver,
// })
// .then((r) => {
// statusObject.ack_payload = r.response;
// statusObject.status = "uploaded";
// set(statusObject);
// })
// .catch((r) => {
// console.log(r);
// statusObject.status = "failed";
// set(statusObject);
// });
// })
// .catch((r) => {
// console.log(r);
// statusObject.status = "failed";
// set(statusObject);
// });
})
.catch((r) => {
console.log(r);
statusObject.status = "failed";
set(statusObject);
});
});
//uploadQueue.create(queue, queueItem);
fire("uploadQueue", { queue, queueItem });
});

formElement.reset();
}

function formatFileSize(n) {
if (n === undefined || /\D/.test(n)) {
return "N/A";
}
if (n > 1073741824) {
return Math.round(n / 1073741824) + " GB";
}
if (n > 1048576) {
return Math.round(n / 1048576) + " MB";
}
if (n > 1024) {
return Math.round(n / 1024) + " KB";
}
return n + " b";
}

function fileSizeValidation(file, max) {
let _allowed = true;
let msg = "";

if (max > 0) {
if (file.size > max) {
_allowed = false;
msg =
"File size is too large. Maximum allowed file size is " +
formatFileSize(max);
}
}
return { allowed: _allowed, msg: msg };
}
function fileTypesValidation(file, allowed) {
if (allowed === "*") {
return {
allowed: true,
msg: "",
};
}
let _allowed = true;
let msg = "";

// eslint-disable-next-line no-useless-escape
var ext = file.name.toLowerCase().match(/\.([^\.]+)$/)[1];
if (typeof allowed.length != "undefined") {
if (allowed.indexOf(ext) === -1) {
_allowed = false;
msg =
"Files of type " +
ext +
" are not allowed.\n Allowed file types: " +
allowed.join(", ");
}
}
return { allowed: _allowed, msg: msg };
}
</script>
Loading