improve PostCreator uploader

This commit is contained in:
SrGooglo 2023-02-24 14:33:15 +00:00
parent 4b9dfe2919
commit 8a9c802dcb
2 changed files with 209 additions and 153 deletions

View File

@ -18,14 +18,13 @@ const DEFAULT_POST_POLICY = {
}
export default (props) => {
const api = window.app.api.withEndpoints("main")
const api = window.app.cores.api.withEndpoints("main")
const creatorRef = React.useRef(null)
const [pending, setPending] = React.useState([])
const [loading, setLoading] = React.useState(false)
const [uploaderVisible, setUploaderVisible] = React.useState(false)
const [focused, setFocused] = React.useState(false)
const [postMessage, setPostMessage] = React.useState("")
const [postAttachments, setPostAttachments] = React.useState([])
@ -45,12 +44,25 @@ export default (props) => {
setPostingPolicy(policy)
}
const canSubmit = () => {
const messageLengthValid = postMessage.length !== 0 && postMessage.length < postingPolicy.maxMessageLength
if (pending.length !== 0) {
return false
}
if (!messageLengthValid && postAttachments.length === 0) {
return false
}
return true
}
const submit = async () => {
if (!canSubmit()) return
setLoading(true)
setUploaderVisible(false)
setFocused(false)
const payload = {
message: postMessage,
@ -78,7 +90,7 @@ export default (props) => {
const onUploadFile = async (req) => {
// hide uploader
//setUploaderVisible(false)
toogleUploaderVisibility(false)
// get file data
const file = req.file
@ -103,20 +115,6 @@ export default (props) => {
}
}
const canSubmit = () => {
const messageLengthValid = postMessage.length !== 0 && postMessage.length < postingPolicy.maxMessageLength
if (pending.length !== 0) {
return false
}
if (!messageLengthValid && postAttachments.length === 0) {
return false
}
return true
}
const removeAttachment = (file_uid) => {
setPostAttachments(postAttachments.filter((file) => file.uid !== file_uid))
}
@ -145,22 +143,13 @@ export default (props) => {
}
}
const onDrop = (event) => {
event.preventDefault()
setUploaderVisible(true)
console.log(event)
const files = event.dataTransfer.files
console.log(files)
}
const onUploaderChange = (change) => {
setFileList(change.fileList)
switch (change.file.status) {
case "uploading": {
toogleUploaderVisibility(false)
setPending([...pending, change.file.uid])
uploaderScrollToEnd()
@ -175,6 +164,7 @@ export default (props) => {
// update post data
addAttachment(change.file.response.files)
// scroll to end
uploaderScrollToEnd()
break
@ -200,12 +190,14 @@ export default (props) => {
setPostMessage(event.target.value)
}
const toggleUploader = (to) => {
setUploaderVisible(to ?? !uploaderVisible)
}
const toogleUploaderVisibility = (to) => {
to = to ?? !uploaderVisible
const toggleFocus = (to) => {
setFocused(to ?? !focused)
if (to === uploaderVisible) {
return
}
setUploaderVisible(to ?? !uploaderVisible)
}
const handleKeyDown = (e) => {
@ -221,7 +213,6 @@ export default (props) => {
const handlePaste = ({ clipboardData }) => {
if (clipboardData && clipboardData.items.length > 0) {
const isValidFormat = (fileType) => DEFAULT_ACCEPTED_FILES.includes(fileType)
toggleUploader(true)
for (let index = 0; index < clipboardData.items.length; index++) {
if (!isValidFormat(clipboardData.items[index].type)) {
@ -276,13 +267,50 @@ export default (props) => {
</div>
}
const handleDrag = (event) => {
event.preventDefault()
event.stopPropagation()
console.log(event)
if (event.type === "dragenter") {
toogleUploaderVisibility(true)
} else if (event.type === "dragleave") {
// check if mouse is over the uploader or outside the creatorRef
if (uploaderVisible && !creatorRef.current.contains(event.target)) {
toogleUploaderVisibility(false)
}
}
}
const handleUploadClick = () => {
// create a new dialog
const dialog = document.createElement("input")
// set the dialog type to file
dialog.type = "file"
// set the dialog accept to the accepted files
dialog.accept = postingPolicy.acceptedMimeTypes
dialog.multiple = true
// add a listener to the dialog
dialog.addEventListener("change", (event) => {
console.log(event)
})
// click the dialog
dialog.click()
}
React.useEffect(() => {
fetchUploadPolicy()
creatorRef.current.addEventListener("paste", handlePaste)
document.addEventListener("paste", handlePaste)
return () => {
creatorRef.current.removeEventListener("paste", handlePaste)
document.removeEventListener("paste", handlePaste)
}
}, [])
@ -292,15 +320,10 @@ export default (props) => {
}, [pending])
return <div
className="postCreator"
className={"postCreator"}
ref={creatorRef}
onDrop={onDrop}
onMouseEnter={() => {
toggleFocus(true)
}}
onMouseLeave={() => {
toggleFocus(false)
}}
onDragEnter={handleDrag}
onDragLeave={handleDrag}
>
<div className="textInput">
<div className="avatar">
@ -327,36 +350,46 @@ export default (props) => {
</div>
</div>
<div className={classnames("actions", { ["hided"]: !focused && !uploaderVisible })}>
<div>
<antd.Button
type={uploaderVisible ? "default" : "primary"}
disabled={loading}
onClick={() => {
toggleUploader()
}}
icon={<Icons.Upload />}
/>
</div>
</div>
<div className={classnames("uploader", { ["hided"]: !uploaderVisible })}>
<antd.Upload
<div className={classnames("uploader", { ["visible"]: uploaderVisible })}>
<antd.Upload.Dragger
openFileDialogOnClick={false}
maxCount={postingPolicy.maximunFilesPerRequest}
onChange={onUploaderChange}
customRequest={onUploadFile}
listType="picture-card"
accept={postingPolicy.acceptedMimeTypes}
itemRender={renderUploadPreviewItem}
fileList={fileList}
listType="picture-card"
itemRender={renderUploadPreviewItem}
multiple
>
<Icons.Plus />
</antd.Upload>
<div className="hint">
<h3>Drag and drop files here</h3>
<span>Max {humanSize.fromBytes(postingPolicy.maximumFileSize)}</span>
</div>
</antd.Upload.Dragger>
</div>
<div className="hint">
<span>Max {humanSize.fromBytes(postingPolicy.maximumFileSize)}</span>
</div>
<div className="actions">
<antd.Button
type="primary"
disabled={loading}
onClick={handleUploadClick}
icon={<Icons.Upload />}
/>
<antd.Button
type="primary"
disabled={loading}
icon={<Icons.MdPoll />}
/>
<antd.Button
type="primary"
disabled={loading}
icon={<Icons.MdPrivacyTip />}
/>
</div>
</div>
}
}

View File

@ -1,28 +1,35 @@
.postCreator {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 15px;
background-color: var(--background-color-accent);
z-index: 55;
max-width: 600px;
border-radius: 7px;
background-color: var(--background-color-accent);
padding: 15px;
transition: all 250ms ease-in-out;
.actions {
display: inline-flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
height: 40px;
overflow: hidden;
width: 100%;
transition: all 150ms ease-in-out;
color: var(--text-color) !important;
>div {
.ant-btn {
margin-left: 10px;
font-size: 1rem;
@ -31,75 +38,112 @@
color: var(--text-color) !important;
}
}
&.hided {
height: 0;
}
}
.uploader {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
padding: 10px;
overflow: hidden;
overflow-x: scroll;
transition: all 150ms ease-in-out;
border: 1px solid var(--border-color);
padding: 10px;
&.visible {
position: absolute;
top: 0;
left: 0;
opacity: 1;
width: 100%;
height: 100%;
>div {
margin-left: 10px;
font-size: 1rem;
z-index: 150;
svg {
margin: 0 !important;
}
}
&.hided {
height: 0px;
opacity: 0;
}
.ant-upload {
span {
width: 100%;
}
svg {
margin: 0 !important;
}
.ant-upload-select-picture-card {
background-color: transparent !important;
}
}
.ant-upload.ant-upload-select-picture-card {
display: flex;
align-self: center;
padding: 0;
align-items: center;
justify-content: center;
width: 10vw;
height: 10vw;
border: 0;
margin-bottom: 0;
.ant-upload-drag {
width: 100%;
height: 100%;
border-color: var(--border-color);
background-color: transparent !important;
opacity: 1;
}
.ant-upload-list {
opacity: 0;
}
}
.ant-upload-list-picture-card .ant-upload-list-item-uploading.ant-upload-list-item {
.ant-upload-drag {
opacity: 0;
width: 0;
height: 0;
background-color: transparent !important;
border: 0;
}
.ant-upload-wrapper {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
background-color: transparent;
backdrop-filter: blur(8px);
width: 100%;
height: 100%;
overflow: hidden;
.ant-upload-list {
display: flex;
flex-direction: row;
width: 100%;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
align-items: center;
justify-content: flex-start;
border-radius: 10px;
.ant-upload-list-item-container {
background-color: black;
width: 10vw;
height: 10vw;
margin-left: 10px;
border-radius: 7px;
}
}
}
.ant-upload-list-item-actions {
@ -113,30 +157,7 @@
font-size: 2rem;
}
.ant-upload-list {
display: flex;
flex-direction: row;
width: 100%;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
align-items: center;
justify-content: flex-start;
border-radius: 10px;
}
.ant-upload-list-picture-card-container {
width: 10vw;
height: 10vw;
}
.hint {
display: flex;
flex-direction: column;
@ -144,9 +165,6 @@
justify-content: center;
align-self: center;
width: 10vw;
height: 10vw;
text-align: center;
background-color: transparent;
@ -235,9 +253,10 @@
.textInput {
display: flex;
width: 100%;
transition: height 150ms ease-in-out;
background-color: var(--background-color-accent);
transition: all 150ms ease-in-out;
svg {
margin: 0 !important;
@ -256,8 +275,12 @@
}
}
.ant-input {
color: var(--background-color-contrast);
textarea {
color: var(--text-color);
}
textarea::placeholder {
color: rgb(var(--bg_color_4));
}
.textArea {
@ -301,12 +324,12 @@
background-color: var(--background-color-accent);
}
.ant-input:hover {
border-color: #1890ff;
}
.ant-input-affix-wrapper {
height: 100%;
border: 0;
outline: 0;
box-shadow: none;
}
}
}