@rpcbase/client 0.197.0 → 0.198.0
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/{ui/FileUpload → form/FileInput}/FileUploadContext.tsx +8 -5
- package/{ui/FileUpload → form/FileInput}/FileUploadForm/index.tsx +5 -3
- package/{ui/FileUpload → form/FileInput}/index.tsx +3 -3
- package/{ui/FileUpload → form/FileInput}/upload-worker/index.js +1 -0
- package/{ui/FileUpload → form/FileInput}/upload-worker/upload_file.js +3 -1
- package/form/Form.tsx +23 -0
- package/form/Input.tsx +61 -0
- package/{ui → form}/SubmitButton/index.tsx +1 -1
- package/form/hook-form.tsx +7 -0
- package/form/index.tsx +5 -0
- package/package.json +1 -1
- package/ui/FileUpload/FileUploadModal.tsx +0 -51
- /package/{ui/FileUpload → form/FileInput}/FileUploadForm/usePreventUnload.js +0 -0
- /package/{ui/FileUpload → form/FileInput}/UploadButton.tsx +0 -0
- /package/{ui/FileUpload → form/FileInput}/constants.ts +0 -0
- /package/{ui/FileUpload/file-upload.scss → form/FileInput/file-input.scss} +0 -0
- /package/{ui/FileUpload → form/FileInput}/upload-worker/get_file_hash.js +0 -0
- /package/{ui/FileUpload → form/FileInput}/upload-worker/no_compress_exts.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Promise from "bluebird"
|
|
2
|
-
import {
|
|
2
|
+
import {ReactNode} from "react"
|
|
3
3
|
import debug from "debug"
|
|
4
|
-
import {
|
|
4
|
+
import {createContext, useContext, useState, useRef, useEffect} from "react"
|
|
5
5
|
|
|
6
6
|
import {EVENTS, UPLOAD_MAX_CONCURRENCY} from "./constants"
|
|
7
7
|
|
|
@@ -63,9 +63,9 @@ export const FileUploadContextProvider = ({
|
|
|
63
63
|
new URL("./upload-worker/index.js", import.meta.url),
|
|
64
64
|
)
|
|
65
65
|
|
|
66
|
-
const onMessage = async({
|
|
66
|
+
const onMessage = async({data}) => {
|
|
67
67
|
log("worker message:", data)
|
|
68
|
-
const {
|
|
68
|
+
const {type, payload} = data
|
|
69
69
|
|
|
70
70
|
if (type === EVENTS.UPLOAD_COMPLETE) {
|
|
71
71
|
const {filename, hash} = payload
|
|
@@ -118,7 +118,10 @@ export const FileUploadContextProvider = ({
|
|
|
118
118
|
}
|
|
119
119
|
})
|
|
120
120
|
|
|
121
|
-
await Promise.map(
|
|
121
|
+
await Promise.map(
|
|
122
|
+
getUploadFiles(), startUploadAndWait,
|
|
123
|
+
{concurrency: UPLOAD_MAX_CONCURRENCY}
|
|
124
|
+
)
|
|
122
125
|
|
|
123
126
|
if (typeof onUploadComplete === "function") {
|
|
124
127
|
await onUploadComplete(getUploadFiles())
|
|
@@ -17,7 +17,9 @@ const STATUS_MESSAGES = {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const FileUploadForm = () => {
|
|
20
|
-
const {workerRef,
|
|
20
|
+
const {workerRef,
|
|
21
|
+
selectedFiles,
|
|
22
|
+
setSelectedFiles, processedFiles, updateProcessedFile} = useFileUploadContext()
|
|
21
23
|
|
|
22
24
|
usePreventUnload()
|
|
23
25
|
|
|
@@ -119,8 +121,8 @@ const FileUploadForm = () => {
|
|
|
119
121
|
role="progressbar"
|
|
120
122
|
style={{width: `${progress}%`}}
|
|
121
123
|
aria-valuenow={progress}
|
|
122
|
-
aria-valuemin=
|
|
123
|
-
aria-valuemax=
|
|
124
|
+
aria-valuemin={0}
|
|
125
|
+
aria-valuemax={100}
|
|
124
126
|
/>
|
|
125
127
|
</div>
|
|
126
128
|
<div className="ms-2 text-secondary">{progress} %</div>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {FileUploadContextProvider} from "./FileUploadContext"
|
|
2
2
|
import FileUploadForm from "./FileUploadForm"
|
|
3
3
|
import {UploadButton} from "./UploadButton"
|
|
4
4
|
|
|
5
|
-
import "./file-
|
|
5
|
+
import "./file-input.scss"
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const FileInput = ({
|
|
9
9
|
onUploadComplete,
|
|
10
10
|
}: {
|
|
11
11
|
onUploadComplete?: (files: any) => void | Promise<void>
|
|
@@ -94,7 +94,9 @@ const upload_file = async(file, hash) => {
|
|
|
94
94
|
|
|
95
95
|
current_chunks_count++
|
|
96
96
|
|
|
97
|
-
log(
|
|
97
|
+
log(
|
|
98
|
+
`upload chunks ${current_chunks_count} chunk // ${total_bytes_read} total_bytes_read...`
|
|
99
|
+
)
|
|
98
100
|
|
|
99
101
|
// there are more bytes to be read
|
|
100
102
|
if (total_bytes_read < size) {
|
package/form/Form.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {FormProvider, SubmitHandler, UseFormReturn} from "react-hook-form"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
type FormProps = {
|
|
5
|
+
ref?: React.Ref<HTMLFormElement>;
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
onSubmit: SubmitHandler<any>;
|
|
8
|
+
className?: string;
|
|
9
|
+
form: UseFormReturn<any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Form = ({ref, children, onSubmit, className = "", ...form}: FormProps) => {
|
|
13
|
+
|
|
14
|
+
// const/*"needs-validation"*/
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<FormProvider {...form}>
|
|
18
|
+
<form ref={ref} onSubmit={onSubmit} className={cx(className)} noValidate>
|
|
19
|
+
{children}
|
|
20
|
+
</form>
|
|
21
|
+
</FormProvider>
|
|
22
|
+
)
|
|
23
|
+
}
|
package/form/Input.tsx
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
// import {NestedKeyOf} from "@rpcbase/client/types"
|
|
3
|
+
import _get from "lodash/get"
|
|
4
|
+
import {useFormContext} from "./hook-form"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type NestedKeys<T> = {
|
|
8
|
+
[K in keyof T & (string | number)]: T[K] extends object
|
|
9
|
+
? `${K}` | `${K}.${NestedKeys<T[K]>}`
|
|
10
|
+
: `${K}`;
|
|
11
|
+
}[keyof T & (string | number)];
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export type InputProps<T> = {
|
|
15
|
+
field: NestedKeys<T>;
|
|
16
|
+
label?: string;
|
|
17
|
+
hint?: string;
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
id?: string;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
className?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const Input = <T,>({
|
|
25
|
+
field,
|
|
26
|
+
label,
|
|
27
|
+
hint,
|
|
28
|
+
placeholder,
|
|
29
|
+
id: idProp,
|
|
30
|
+
className,
|
|
31
|
+
disabled: isDisabled,
|
|
32
|
+
...props
|
|
33
|
+
}: InputProps<T> & React.InputHTMLAttributes<HTMLInputElement>) => {
|
|
34
|
+
const form = useFormContext()
|
|
35
|
+
|
|
36
|
+
const id = idProp || `input-${field}`
|
|
37
|
+
|
|
38
|
+
const error = _get(form.formState.errors, field)
|
|
39
|
+
|
|
40
|
+
const {isSubmitting} = form.formState
|
|
41
|
+
|
|
42
|
+
const disabled = isDisabled || isSubmitting
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div className={className}>
|
|
46
|
+
{label && <label htmlFor={id}>{label}</label>}
|
|
47
|
+
<input
|
|
48
|
+
id={id}
|
|
49
|
+
className={cx("form-control form-control-sm", {
|
|
50
|
+
"is-invalid": !!error,
|
|
51
|
+
})}
|
|
52
|
+
type="text"
|
|
53
|
+
placeholder={placeholder}
|
|
54
|
+
disabled={disabled}
|
|
55
|
+
{...form.register(field)}
|
|
56
|
+
/>
|
|
57
|
+
{!error && hint && <div className="form-text">{hint}</div>}
|
|
58
|
+
{error && <div className="invalid-feedback">{error.message}</div>}
|
|
59
|
+
</div>
|
|
60
|
+
)
|
|
61
|
+
}
|
package/form/index.tsx
ADDED
package/package.json
CHANGED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import ActivityIndicator from "../ActivityIndicator"
|
|
2
|
-
import Modal from "../Modal"
|
|
3
|
-
|
|
4
|
-
import {FileUploadContextProvider} from "./FileUploadContext"
|
|
5
|
-
import FileUploadForm from "./FileUploadForm"
|
|
6
|
-
import UploadButton from "./UploadButton"
|
|
7
|
-
|
|
8
|
-
import "./file-upload.scss"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const FileUploadModal = ({onHide}) => {
|
|
12
|
-
const isLoading = false
|
|
13
|
-
|
|
14
|
-
const onHideFn = () => null
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<FileUploadContextProvider>
|
|
18
|
-
<Modal className="file-upload-modal" show scrollable={true} onHide={onHideFn}>
|
|
19
|
-
<Modal.Header className="close-top" closeButton>
|
|
20
|
-
<img
|
|
21
|
-
width={22}
|
|
22
|
-
height={22}
|
|
23
|
-
className="me-2 align-self-start mt-1"
|
|
24
|
-
src={`/static/icons/drive/file-upload-s.svg`}
|
|
25
|
-
/>
|
|
26
|
-
<div>
|
|
27
|
-
<div>File Upload</div>
|
|
28
|
-
<small className="text-secondary fw-normal">Upload any type of file, any size.</small>
|
|
29
|
-
</div>
|
|
30
|
-
</Modal.Header>
|
|
31
|
-
<Modal.Body className="py-2">
|
|
32
|
-
{isLoading && (
|
|
33
|
-
<div className="d-flex flex-row align-items-center">
|
|
34
|
-
<ActivityIndicator size={24} />
|
|
35
|
-
<div className="ms-2">Loading text...</div>
|
|
36
|
-
</div>
|
|
37
|
-
)}
|
|
38
|
-
|
|
39
|
-
<FileUploadForm />
|
|
40
|
-
</Modal.Body>
|
|
41
|
-
<Modal.Footer className="d-flex justify-content-between">
|
|
42
|
-
<div>
|
|
43
|
-
<a href="/docs/drives">/docs/drives</a>
|
|
44
|
-
</div>
|
|
45
|
-
|
|
46
|
-
<UploadButton />
|
|
47
|
-
</Modal.Footer>
|
|
48
|
-
</Modal>
|
|
49
|
-
</FileUploadContextProvider>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|