implement ImageUploader

This commit is contained in:
SrGooglo 2022-12-09 14:20:02 +00:00
parent 6643109708
commit d829c5c604
12 changed files with 112 additions and 67 deletions

View File

@ -1 +0,0 @@
export { default as UnsplashBrowser } from "./unsplashBrowser"

View File

@ -1,14 +0,0 @@
import React from "react"
export default (props) => {
const [searchValue, setSearchValue] = React.useState("")
const [results, setResults] = React.useState([])
return <div className="unsplashBrowser">
<h1>Search in Unsplash</h1>
<div>
</div>
</div>
}

View File

@ -1,7 +1,6 @@
import React from "react"
import * as antd from "antd"
import { UnsplashBrowser } from "./components"
import loadable from "@loadable/component"
import "./index.less"
@ -82,41 +81,9 @@ export default [
"group": "aspect",
"title": "Background image",
"description": "Change background image of the application. You can use a local image or a remote image (URL).",
"component": (props) => {
const [validUrl, setValidUrl] = React.useState(true)
const submitUrl = (e) => {
const url = e.target.value
// validate if value recived is url
if (!url.match(/^(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9]+\.[a-zA-Z]+(\.[a-zA-Z]+)?(\/.*)?$/)) {
setValidUrl(false)
antd.message.error("Invalid URL")
return
}
props.ctx.dispatchUpdate(url)
}
const onClickSearchUnsplash = () => {
antd.message.warn("This feature is not implemented yet.")
return false
window.app.SidedrawerController.open("unsplashBrowser", UnsplashBrowser)
}
return <div className="backgroundImageSetting">
<antd.Input
placeholder="https://example.com/image.png"
onPressEnter={submitUrl}
status={validUrl ? "default" : "error"}
/>
or
<antd.Button
onClick={onClickSearchUnsplash}
>
Search on Unsplash
</antd.Button>
</div>
"component": loadable(() => import("../components/ImageUploader")),
"props": {
"noPreview": true,
},
"emitEvent": "modifyTheme",
"emissionValueUpdate": (value) => {

View File

@ -0,0 +1,65 @@
import React from "react"
import { Button, Input, Upload } from "antd"
import { Icons } from "components/Icons"
import "./index.less"
export default (props) => {
const [value, setValue] = React.useState(props.ctx.currentValue)
const uploadImage = async (req) => {
const formData = new FormData()
formData.append("files", req.file)
const request = await window.app.api.withEndpoints("main").post.upload(formData, undefined).catch((error) => {
console.error(error)
antd.message.error(error)
return false
})
if (request) {
setValue(request.files[0].url)
props.ctx.dispatchUpdate(request.files[0].url)
}
}
return <div className="imageUploader">
{
!props.noPreview && value && <div className="uploadPreview">
<img src={value} />
</div>
}
<Input.Group compact>
<Input
placeholder="Image URL..."
value={value}
onChange={(e) => setValue(e.target.value)}
onPressEnter={() => props.ctx.dispatchUpdate(value)}
/>
<Button
icon={<Icons.Save />}
onClick={() => props.ctx.dispatchUpdate(value)}
/>
</Input.Group>
or
<Upload
customRequest={uploadImage}
multiple={false}
accept="image/*"
progress={false}
fileList={[]}
>
<Button
icon={<Icons.Upload />}
>
Upload
</Button>
</Upload>
</div>
}

View File

@ -0,0 +1,32 @@
.imageUploader {
display: flex;
flex-direction: column;
align-items: center;
.uploadPreview {
width: 100px;
margin-bottom: 10px;
img {
width: 100%;
height: 100%;
border-radius: 8px;
}
}
.ant-input-group {
display: inline-flex;
flex-direction: row;
width: 100%;
.ant-btn {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
svg {
margin: 0!important;
}
}
}
}

View File

@ -1,5 +1,5 @@
import AppSettings from "./app"
import AccountSettings from "./account"
import ProfileSettings from "./profile"
import SecuritySettings from "./security"
import NotificationsSettings from "./notifications"
import ApparenceSettings from "./apparence"
@ -11,10 +11,10 @@ export default {
label: "App",
settings: AppSettings
},
account: {
profile: {
icon: "User",
label: "Profile",
settings: AccountSettings
settings: ProfileSettings
},
apparence: {
icon: "Eye",

View File

@ -1,5 +1,6 @@
import React from "react"
import { User } from "models"
import loadable from "@loadable/component"
export default [
{
@ -94,10 +95,10 @@ export default [
{
"id": "avatar",
"group": "account.profile",
"component": "Input",
"icon": "Image",
"title": "Avatar",
"description": "Change your avatar (Upload an image or use an URL)",
"component": loadable(() => import("../components/ImageUploader")),
"defaultValue": async () => {
const userData = await User.data()
return userData.avatar
@ -113,6 +114,7 @@ export default [
})
if (result) {
app.message.success("Avatar updated")
return result
}
},
@ -121,10 +123,10 @@ export default [
{
"id": "cover",
"group": "account.profile",
"component": "Input",
"icon": "Image",
"title": "Cover",
"description": "Change your profile cover (Upload an image or use an URL)",
"component": loadable(() => import("../components/ImageUploader")),
"defaultValue": async () => {
const userData = await User.data()
return userData.cover
@ -140,19 +142,12 @@ export default [
})
if (result) {
app.message.success("Cover updated")
return result
}
},
"debounced": true,
},
{
"id": "cover",
"group": "account.profile",
"component": "ImageUpload",
"icon": "Image",
"title": "Cover",
"description": "Change your cover",
},
{
"id": "description",
"group": "account.profile",

View File

@ -10,7 +10,7 @@ export default [
"title": "Change Password",
"description": "Change your password",
"icon": "Lock",
"component": loadable(() => import("./components/changePassword")),
"component": loadable(() => import("../components/changePassword")),
},
{
"id": "two-factor-authentication",
@ -26,7 +26,7 @@ export default [
"title": "Sessions",
"description": "Manage your active sessions",
"icon": "Monitor",
"component": loadable(() => import("./components/sessions")),
"component": loadable(() => import("../components/sessions")),
},
{
"id": "logout",

View File

@ -298,6 +298,7 @@ const SettingItem = (props) => {
{loading ? <div> Loading... </div> : React.createElement(SettingComponent, {
...item.props,
ctx: {
currentValue: value,
dispatchUpdate,
onUpdateItem,
}