Skip to content

Commit 7773d34

Browse files
committed
Requested changes done and cleaned up the code
1 parent 5ef1c5c commit 7773d34

File tree

5 files changed

+88
-125
lines changed

5 files changed

+88
-125
lines changed

src/App.tsx

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,43 +31,21 @@ const App = () => {
3131
message:
3232
"Great! Now please upload a profile picture (JPEG or PNG) or provide a URL.",
3333
path: "file_upload_validation",
34-
chatDisabled: true, // Set to true if you want to disable text input
35-
validateTextInput: (userInput?: string) => {
36-
console.log("validateTextInput called with userInput:", userInput);
37-
38-
if (userInput && userInput.trim().length > 0) {
39-
// Optionally, validate if the input is a valid URL
40-
// For simplicity, we'll accept any non-empty text
41-
return { success: true };
42-
}
43-
44-
return {
45-
success: false,
46-
promptContent:
47-
"Please provide a valid URL or upload a file.",
48-
promptDuration: 3000,
49-
promptType: "error",
50-
};
51-
},
34+
chatDisabled: true, // Text input is disabled
5235
validateFileInput: (file?: File) => {
53-
return validateFile(file); // Validate file input
36+
return validateFile(file); // Validation is handled here
5437
},
5538
file: async ({ files }) => {
5639
console.log("Files received:", files);
57-
40+
5841
if (files && files[0]) {
59-
const validationResult = validateFile(files[0]);
60-
if (!validationResult.success) {
61-
console.error(validationResult.promptContent);
62-
// Return early to prevent success
63-
return { success: false };
64-
}
6542
console.log("File uploaded successfully:", files[0]);
6643
} else {
6744
console.error("No file provided.");
6845
}
6946
},
7047
} as InputValidatorBlock,
48+
7149

7250
file_upload_validation: {
7351
message:

src/core/useRcbPlugin.ts

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { getValidator } from "../utils/getValidator";
1818
/**
1919
* Plugin hook that handles all the core logic.
2020
*
21-
* @param pluginConfig Configurations for the plugin.
21+
* @param pluginConfig configurations for the plugin
2222
*/
2323
const useRcbPlugin = (pluginConfig?: PluginConfig) => {
2424
const { showToast } = useToasts();
@@ -45,7 +45,7 @@ const useRcbPlugin = (pluginConfig?: PluginConfig) => {
4545
getBotId(),
4646
getFlow(),
4747
"validateTextInput"
48-
);
48+
);
4949
if (!validator) {
5050
return;
5151
}
@@ -85,51 +85,49 @@ const useRcbPlugin = (pluginConfig?: PluginConfig) => {
8585
setNumPluginToasts((prev) => prev + 1);
8686
};
8787

88-
/**
89-
* Handles the user uploading a file event.
90-
*
91-
* @param event Event emitted when user uploads a file.
92-
*/
93-
// useRcbPlugin.ts
94-
9588
const handleUserUploadFile = (event: Event): void => {
9689
const rcbEvent = event as RcbUserUploadFileEvent;
9790
const file: File | undefined = rcbEvent.data?.files?.[0];
98-
91+
9992
if (!file) {
100-
console.error("No file uploaded.");
101-
event.preventDefault();
102-
return;
93+
console.error("No file uploaded.");
94+
event.preventDefault();
95+
return;
10396
}
104-
97+
10598
const validator = getValidator<File>(
106-
rcbEvent,
107-
getBotId(),
108-
getFlow(),
109-
"validateFileInput"
99+
rcbEvent,
100+
getBotId(),
101+
getFlow(),
102+
"validateFileInput"
110103
);
111-
104+
112105
if (!validator) {
113-
console.error("Validator not found for file input.");
114-
return;
106+
console.error("Validator not found for file input.");
107+
return;
115108
}
116-
109+
117110
const validationResult = validator(file);
118-
111+
119112
if (!validationResult.success) {
120-
console.error("Validation failed:", validationResult);
121-
if (validationResult.promptContent) {
122-
showToast(validationResult.promptContent, validationResult.promptDuration ?? 3000);
123-
}
124-
event.preventDefault();
125-
return;
113+
console.error("Validation failed:", validationResult);
114+
if (validationResult.promptContent) {
115+
showToast(
116+
validationResult.promptContent,
117+
validationResult.promptDuration ?? 3000
118+
);
119+
}
120+
event.preventDefault();
121+
return;
126122
}
127-
123+
128124
console.log("Validation successful:", validationResult);
129125
};
130126

131127
/**
132128
* Handles the dismiss toast event.
129+
*
130+
* @param event Event emitted when toast is dismissed.
133131
*/
134132
const handleDismissToast = (): void => {
135133
setNumPluginToasts((prev) => prev - 1);

src/types/InputValidatorBlock.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
// src/types/InputValidatorBlock.ts
2-
31
import { Block } from "react-chatbotify";
42
import { ValidationResult } from "./ValidationResult";
53

64
/**
7-
* Extends the Block from React ChatBotify to support inputValidator attribute.
5+
* Extends the Block from React ChatBotify to support inputValidator attributes.
86
*/
9-
10-
export type InputValidatorBlock = Omit<Block, "file"> & {
11-
file?: (params: { files?: FileList }) => void | Promise<void>;
7+
export type InputValidatorBlock = Block & {
128
validateTextInput?: (userInput?: string) => ValidationResult;
13-
validateFileInput?: (file?: File) => ValidationResult;
14-
};
9+
validateFileInput?: (files?: FileList) => ValidationResult; // Accepts multiple files
10+
};

src/utils/getValidator.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// src/utils/getValidator.ts
2-
31
import { Flow, RcbUserSubmitTextEvent, RcbUserUploadFileEvent } from "react-chatbotify";
42
import { InputValidatorBlock } from "../types/InputValidatorBlock";
53
import { ValidationResult } from "../types/ValidationResult";
@@ -23,25 +21,15 @@ export const getValidator = <T = string | File>(
2321
currFlow: Flow,
2422
validatorType: "validateTextInput" | "validateFileInput" = "validateTextInput"
2523
): ((input: T) => ValidationResult) | undefined => {
26-
if (!event.detail) {
27-
return;
28-
}
29-
30-
const { botId, currPath } = event.detail;
31-
32-
if (currBotId !== botId) {
33-
return;
34-
}
35-
36-
if (!currPath) {
37-
return;
24+
if (!event.detail?.currPath || currBotId !== event.detail.botId) {
25+
return;
3826
}
39-
40-
const currBlock = currFlow[currPath] as InputValidatorBlock;
27+
28+
const currBlock = currFlow[event.detail.currPath] as InputValidatorBlock;
4129
if (!currBlock) {
42-
return;
30+
return;
4331
}
44-
32+
4533
const validator = currBlock[validatorType] as ((input: T) => ValidationResult) | undefined;
4634
return typeof validator === "function" ? validator : undefined;
47-
};
35+
};

src/utils/validateFile.ts

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
11
import { ValidationResult } from "../types/ValidationResult";
22

33
/**
4-
* Validates the uploaded file.
5-
* Ensures the file is of allowed type and size, and rejects non-file inputs.
4+
* Validates uploaded files.
5+
* Ensures each file is of an allowed type and size, and rejects invalid inputs.
66
*/
7-
export const validateFile = (file?: File): ValidationResult => {
7+
export const validateFile = (input?: File | FileList): ValidationResult => {
88
const allowedTypes = ["image/jpeg", "image/png"];
99
const maxSizeInBytes = 5 * 1024 * 1024; // 5MB
10-
11-
// Check if no file is provided
12-
if (!file) {
13-
return {
14-
success: false,
15-
promptContent: "No file uploaded.",
16-
promptDuration: 3000,
17-
promptType: "error",
18-
};
19-
}
20-
21-
// Check if the file is empty
22-
if (file.size === 0) {
23-
return {
24-
success: false,
25-
promptContent: "The uploaded file is empty. Please upload a valid file.",
26-
promptDuration: 3000,
27-
promptType: "error",
28-
};
29-
}
30-
31-
// Validate file type
32-
if (!allowedTypes.includes(file.type)) {
33-
return {
34-
success: false,
35-
promptContent: "Only JPEG or PNG files are allowed.",
36-
promptType: "error",
37-
};
10+
const files: File[] = input instanceof FileList ? Array.from(input) : input ? [input] : [];
11+
12+
// Check if no files are provided
13+
if (files.length === 0) {
14+
return {
15+
success: false,
16+
promptContent: "No files uploaded.",
17+
promptDuration: 3000,
18+
promptType: "error",
19+
};
3820
}
39-
40-
// Validate file size
41-
if (file.size > maxSizeInBytes) {
42-
return {
43-
success: false,
44-
promptContent: "File size must be less than 5MB.",
45-
promptType: "error",
46-
};
21+
22+
// Validate each file
23+
for (const file of files) {
24+
// Check if the file is empty
25+
if (file.size === 0) {
26+
return {
27+
success: false,
28+
promptContent: `The file "${file.name}" is empty. Please upload a valid file.`,
29+
promptDuration: 3000,
30+
promptType: "error",
31+
};
32+
}
33+
34+
// Validate file type
35+
if (!allowedTypes.includes(file.type)) {
36+
return {
37+
success: false,
38+
promptContent: `The file "${file.name}" is not a valid type. Only JPEG or PNG files are allowed.`,
39+
promptType: "error",
40+
};
41+
}
42+
43+
// Validate file size
44+
if (file.size > maxSizeInBytes) {
45+
return {
46+
success: false,
47+
promptContent: `The file "${file.name}" exceeds the 5MB size limit.`,
48+
promptType: "error",
49+
};
50+
}
4751
}
48-
52+
4953
return { success: true };
50-
};
51-
54+
};

0 commit comments

Comments
 (0)