Skip to content

Commit

Permalink
Add file upload functionality
Browse files Browse the repository at this point in the history
Fixes Niek#465

Add file upload functionality to chat interface.

* **Chat.svelte**
  - Add a file input element for uploading files.
  - Handle file input change event to read the file.
  - Update the `submitForm` function to include file data in the request.

* **ChatOptionMenu.svelte**
  - Add an option to upload files in the dropdown menu.
  - Handle file input change event to read the file.

* **ApiUtil.svelte**
  - Add a new endpoint for file uploads.

* **Storage.svelte**
  - Add a function to handle file uploads and store them appropriately.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/Niek/chatgpt-web/issues/465?shareId=XXXX-XXXX-XXXX-XXXX).
  • Loading branch information
Ryan526 committed Sep 25, 2024
1 parent c2e2a53 commit 819de8f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/lib/ApiUtil.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
const endpointGenerations = import.meta.env.VITE_ENDPOINT_GENERATIONS || '/v1/images/generations'
const endpointModels = import.meta.env.VITE_ENDPOINT_MODELS || '/v1/models'
const endpointEmbeddings = import.meta.env.VITE_ENDPOINT_EMBEDDINGS || '/v1/embeddings'
const endpointFileUploads = import.meta.env.VITE_ENDPOINT_FILE_UPLOADS || '/v1/files'
const petalsBase = import.meta.env.VITE_PEDALS_WEBSOCKET || 'wss://chat.petals.dev'
const endpointPetals = import.meta.env.VITE_PEDALS_WEBSOCKET || '/api/v2/generate'
Expand All @@ -13,6 +14,7 @@
export const getEndpointGenerations = ():string => endpointGenerations
export const getEndpointModels = ():string => endpointModels
export const getEndpointEmbeddings = ():string => endpointEmbeddings
export const getEndpointFileUploads = ():string => endpointFileUploads
export const getPetalsBase = ():string => petalsBase
export const getPetalsWebsocket = ():string => endpointPetals
</script>
</script>
23 changes: 22 additions & 1 deletion src/lib/Chat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
let recording = false
let lastSubmitRecorded = false
let fileInput: HTMLInputElement
$: chat = $chatsStorage.find((chat) => chat.id === chatId) as Chat
$: chatSettings = chat?.settings
let showSettingsModal
Expand Down Expand Up @@ -217,6 +219,21 @@
chatRequest.controller.abort()
}
const handleFileInputChange = (event: Event) => {
const input = event.target as HTMLInputElement
const file = input.files?.[0]
if (file) {
const reader = new FileReader()
reader.onload = (e) => {
const content = e.target?.result as string
const fileMessage: Message = { role: 'user', content, uuid: uuidv4() }
addMessage(chatId, fileMessage)
submitForm()
}
reader.readAsText(file)
}
}
const submitForm = async (recorded: boolean = false, skipInput: boolean = false, fillMessage: Message|undefined = undefined): Promise<void> => {
// Compose the system prompt message if there are no messages yet - disabled for now
if (chatRequest.updating) return
Expand Down Expand Up @@ -426,6 +443,10 @@
<p class="control queue">
<button title="Queue message, don't send yet" class:is-disabled={chatRequest.updating} class="button is-ghost" on:click|preventDefault={addNewMessage}><span class="icon"><Fa icon={faArrowUpFromBracket} /></span></button>
</p>
<p class="control file-upload">
<input type="file" accept=".pdf,.jpg,.jpeg,.png,.gif,.bmp,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.csv" on:change={handleFileInputChange} bind:this={fileInput} style="display: none;" />
<button title="Upload File" class="button" type="button" on:click={() => fileInput.click()}><span class="icon"><Fa icon={faArrowUpFromBracket} /></span></button>
</p>
{#if chatRequest.updating}
<p class="control send">
<button title="Cancel Response" class="button is-danger" type="button" on:click={cancelRequest}><span class="icon">
Expand Down Expand Up @@ -453,4 +474,4 @@
</div>
</Footer>
</div>
{/if}
{/if}
20 changes: 20 additions & 0 deletions src/lib/ChatOptionMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
let showChatMenu = false
let chatFileInput
let profileFileInput
let fileInput
const importChatFromFile = (e) => {
close()
Expand Down Expand Up @@ -157,6 +158,21 @@
reader.readAsText(image)
}
const handleFileInputChange = (event: Event) => {
const input = event.target as HTMLInputElement
const file = input.files?.[0]
if (file) {
const reader = new FileReader()
reader.onload = (e) => {
const content = e.target?.result as string
const fileMessage = { role: 'user', content, uuid: uuidv4() }
addMessage(chatId, fileMessage)
submitForm()
}
reader.readAsText(file)
}
}
</script>

<div class="dropdown {style}" class:is-active={showChatMenu} use:clickOutside={() => { showChatMenu = false }}>
Expand Down Expand Up @@ -207,6 +223,9 @@
<a href={'#'} class="dropdown-item" class:is-disabled={!hasActiveModels()} on:click|preventDefault={() => { if (chatId) close(); profileFileInput.click() }}>
<span class="menu-icon"><Fa icon={faUpload}/></span> Restore Profile JSON
</a>
<a href={'#'} class="dropdown-item" class:is-disabled={!chatId} on:click|preventDefault={() => { if (chatId) close(); fileInput.click() }}>
<span class="menu-icon"><Fa icon={faUpload}/></span> Upload File
</a>
<hr class="dropdown-divider">
<a href={'#'} class="dropdown-item" class:is-disabled={!chatId} on:click|preventDefault={() => { if (chatId) close(); delChat() }}>
<span class="menu-icon"><Fa icon={faTrash}/></span> Delete Chat
Expand All @@ -232,3 +251,4 @@

<input style="display:none" type="file" accept=".json" on:change={(e) => importChatFromFile(e)} bind:this={chatFileInput} >
<input style="display:none" type="file" accept=".json" on:change={(e) => importProfileFromFile(e)} bind:this={profileFileInput} >
<input style="display:none" type="file" accept=".pdf,.jpg,.jpeg,.png,.gif,.bmp,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.csv" on:change={handleFileInputChange} bind:this={fileInput} >
10 changes: 10 additions & 0 deletions src/lib/Storage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -581,5 +581,15 @@
modelMapStore[requestedModel] = responseModel
latestModelMap.set(modelMapStore)
}
export const handleFileUpload = async (chatId: number, file: File): Promise<void> => {
const reader = new FileReader()
reader.onload = (e) => {
const content = e.target?.result as string
const fileMessage: Message = { role: 'user', content, uuid: uuidv4() }
addMessage(chatId, fileMessage)
}
reader.readAsText(file)
}
</script>

0 comments on commit 819de8f

Please sign in to comment.