Skip to content

Commit

Permalink
Merge pull request snek-at#3 from getcronit/main
Browse files Browse the repository at this point in the history
feat: add file upload functionality to TextField component
  • Loading branch information
schettn authored Jun 24, 2024
2 parents cdcf90a + bced0db commit 8ecc9fe
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/jaen/src/contexts/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ export const PageProvider: React.FC<
jaenPage,
jaenPages
}}>
<input
id="page-file-upload-input"
type="file"
style={{display: 'none'}}
/>
{children}
</PageContext.Provider>
)
Expand Down
56 changes: 56 additions & 0 deletions packages/jaen/src/fields/TextField/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {FaItalic} from '@react-icons/all-files/fa/FaItalic'
import {FaUnderline} from '@react-icons/all-files/fa/FaUnderline'
import {FaLink} from '@react-icons/all-files/fa/FaLink'
import {FaUnlink} from '@react-icons/all-files/fa/FaUnlink'
import {FaFileUpload} from '@react-icons/all-files/fa/FaFileUpload'

import {useDebouncedCallback} from 'use-debounce'

Expand All @@ -21,6 +22,7 @@ import {TuneSelectorButton} from '../../components/TuneSelectorButton/TuneSelect
import {connectField} from '../../connectors'
import {useNotificationsContext} from '../../contexts/notifications'
import {HighlightTooltip} from '../components/HighlightTooltip/HighlightTooltip'
import {uploadFile} from '../../utils/open-storage-gateway'

const cleanRichText = (
text: string,
Expand Down Expand Up @@ -138,6 +140,46 @@ export const TextField = connectField<string, TextFieldProps>(
handleTextSave(evt.currentTarget.innerHTML)
}, [])

const handleFileChange = async (
event: Event & {target: {files: FileList | null}}
) => {
const fileInput = document.getElementById(
'page-file-upload-input'
) as HTMLInputElement

const file = event.target.files?.[0]
if (file) {
const randomId = Math.random().toString(36).substring(7)

// The 'download' attribute is used to set the filename when downloading the file
// This only works on same-origin URLs, hence it doesn't work with the Open Storage Gateway
document.execCommand(
'insertHTML',
false,
`<a id="${randomId}" download="${file.name}" href="#" target="_blank">${file.name}</a>`
)

const {fileUrl} = await uploadFile(file)

const link = document.getElementById(randomId)

if (link) {
link.setAttribute('href', fileUrl)
link.removeAttribute('id')
} else {
throw new Error('Could not find link element')
}
}

if (fileInput) {
// Optionally reset file input to allow re-uploading the same file
fileInput.value = ''

// Unregister listener
fileInput.removeEventListener('change', handleFileChange)
}
}

const alignmentTune: TuneOption = {
type: 'groupTune',
name: 'alignment',
Expand Down Expand Up @@ -223,6 +265,20 @@ export const TextField = connectField<string, TextFieldProps>(
onTune: () => {
document.execCommand('unlink', false)
}
},
{
name: 'file',
Icon: FaFileUpload,
onTune: async () => {
const fileInput = document.getElementById('page-file-upload-input')

if (fileInput) {
// Register listener to handle file upload
fileInput.addEventListener('change', handleFileChange)

fileInput.click()
}
}
}
]
}
Expand Down

0 comments on commit 8ecc9fe

Please sign in to comment.