support custom components

This commit is contained in:
srgooglo 2022-05-31 00:32:04 +02:00
parent 321131d529
commit 5e9678aa3b
4 changed files with 85 additions and 73 deletions

View File

@ -5,7 +5,7 @@ export default [
{ {
"id": "username", "id": "username",
"group": "account.basicInfo", "group": "account.basicInfo",
"type": "Button", "component": "Button",
"icon": "AtSign", "icon": "AtSign",
"title": "Username", "title": "Username",
"description": "Your username is the name you use to log in to your account.", "description": "Your username is the name you use to log in to your account.",
@ -17,7 +17,7 @@ export default [
{ {
"id": "fullName", "id": "fullName",
"group": "account.basicInfo", "group": "account.basicInfo",
"type": "Input", "component": "Input",
"icon": "Edit3", "icon": "Edit3",
"title": "Name", "title": "Name",
"description": "Change your public name", "description": "Change your public name",
@ -57,7 +57,7 @@ export default [
{ {
"id": "email", "id": "email",
"group": "account.basicInfo", "group": "account.basicInfo",
"type": "Input", "component": "Input",
"icon": "Mail", "icon": "Mail",
"title": "Email", "title": "Email",
"description": "Change your email address", "description": "Change your email address",
@ -87,7 +87,7 @@ export default [
{ {
"id": "avatar", "id": "avatar",
"group": "account.profile", "group": "account.profile",
"type": "ImageUpload", "component": "ImageUpload",
"icon": "Image", "icon": "Image",
"title": "Avatar", "title": "Avatar",
"description": "Change your avatar", "description": "Change your avatar",
@ -95,7 +95,7 @@ export default [
{ {
"id": "cover", "id": "cover",
"group": "account.profile", "group": "account.profile",
"type": "ImageUpload", "component": "ImageUpload",
"icon": "Image", "icon": "Image",
"title": "Cover", "title": "Cover",
"description": "Change your cover", "description": "Change your cover",
@ -103,7 +103,7 @@ export default [
{ {
"id": "primaryBadge", "id": "primaryBadge",
"group": "account.profile", "group": "account.profile",
"type": "Select", "component": "Select",
"icon": "Tag", "icon": "Tag",
"title": "Primary badge", "title": "Primary badge",
"description": "Change your primary badge", "description": "Change your primary badge",
@ -111,7 +111,7 @@ export default [
{ {
"id": "description", "id": "description",
"group": "account.profile", "group": "account.profile",
"type": "TextArea", "component": "TextArea",
"icon": "Edit3", "icon": "Edit3",
"title": "Description", "title": "Description",
"description": "Change your description for your profile", "description": "Change your description for your profile",
@ -141,7 +141,7 @@ export default [
{ {
"id": "logout", "id": "logout",
"footer": true, "footer": true,
"type": "Button", "component": "Button",
"icon": "LogOut", "icon": "LogOut",
"title": "Logout", "title": "Logout",
"emitEvent": "session.logout", "emitEvent": "session.logout",

View File

@ -7,7 +7,7 @@ export default [
"id": "language", "id": "language",
"storaged": true, "storaged": true,
"group": "general", "group": "general",
"type": "Select", "component": "Select",
"icon": "MdTranslate", "icon": "MdTranslate",
"title": "Language", "title": "Language",
"description": "Choose a language for the application", "description": "Choose a language for the application",
@ -22,7 +22,7 @@ export default [
"id": "forceMobileMode", "id": "forceMobileMode",
"storaged": true, "storaged": true,
"group": "general", "group": "general",
"type": "Switch", "component": "Switch",
"icon": "MdSmartphone", "icon": "MdSmartphone",
"title": "Force Mobile Mode", "title": "Force Mobile Mode",
"description": "Force the application to run in mobile mode.", "description": "Force the application to run in mobile mode.",
@ -32,7 +32,7 @@ export default [
"id": "haptic_feedback", "id": "haptic_feedback",
"storaged": true, "storaged": true,
"group": "general", "group": "general",
"type": "Switch", "component": "Switch",
"icon": "MdVibration", "icon": "MdVibration",
"title": "Haptic Feedback", "title": "Haptic Feedback",
"description": "Enable haptic feedback on touch events.", "description": "Enable haptic feedback on touch events.",
@ -41,7 +41,7 @@ export default [
"id": "selection_longPress_timeout", "id": "selection_longPress_timeout",
"storaged": true, "storaged": true,
"group": "general", "group": "general",
"type": "Slider", "component": "Slider",
"icon": "MdTimer", "icon": "MdTimer",
"title": "Selection press delay", "title": "Selection press delay",
"description": "Set the delay before the selection trigger is activated.", "description": "Set the delay before the selection trigger is activated.",
@ -62,7 +62,7 @@ export default [
"id": "notifications_sound", "id": "notifications_sound",
"storaged": true, "storaged": true,
"group": "notifications", "group": "notifications",
"type": "Switch", "component": "Switch",
"icon": "MdVolumeUp", "icon": "MdVolumeUp",
"title": "Notifications Sound", "title": "Notifications Sound",
"description": "Play a sound when a notification is received.", "description": "Play a sound when a notification is received.",
@ -71,7 +71,7 @@ export default [
"id": "notifications_vibrate", "id": "notifications_vibrate",
"storaged": true, "storaged": true,
"group": "notifications", "group": "notifications",
"type": "Switch", "component": "Switch",
"icon": "MdVibration", "icon": "MdVibration",
"title": "Vibration", "title": "Vibration",
"description": "Vibrate the device when a notification is received.", "description": "Vibrate the device when a notification is received.",
@ -81,7 +81,7 @@ export default [
"id": "notifications_sound_volume", "id": "notifications_sound_volume",
"storaged": true, "storaged": true,
"group": "notifications", "group": "notifications",
"type": "Slider", "component": "Slider",
"icon": "MdVolumeUp", "icon": "MdVolumeUp",
"title": "Sound Volume", "title": "Sound Volume",
"description": "Set the volume of the sound when a notification is received.", "description": "Set the volume of the sound when a notification is received.",
@ -96,7 +96,7 @@ export default [
"id": "edit_sidebar", "id": "edit_sidebar",
"storaged": true, "storaged": true,
"group": "sidebar", "group": "sidebar",
"type": "Button", "component": "Button",
"icon": "Edit", "icon": "Edit",
"title": "Edit Sidebar", "title": "Edit Sidebar",
"emitEvent": "edit_sidebar", "emitEvent": "edit_sidebar",
@ -106,7 +106,7 @@ export default [
"id": "collapseOnLooseFocus", "id": "collapseOnLooseFocus",
"storaged": true, "storaged": true,
"group": "sidebar", "group": "sidebar",
"type": "Switch", "component": "Switch",
"icon": "Columns", "icon": "Columns",
"title": "Auto Collapse", "title": "Auto Collapse",
"description": "Collapse the sidebar when loose focus", "description": "Collapse the sidebar when loose focus",
@ -116,7 +116,7 @@ export default [
"id": "autoCollapseDelay", "id": "autoCollapseDelay",
"storaged": true, "storaged": true,
"group": "sidebar", "group": "sidebar",
"type": "Slider", "component": "Slider",
"icon": "Wh", "icon": "Wh",
"dependsOn": { "dependsOn": {
"collapseOnLooseFocus": true "collapseOnLooseFocus": true

View File

@ -5,7 +5,7 @@ export default [
"id": "reduceAnimations", "id": "reduceAnimations",
"storaged": true, "storaged": true,
"group": "aspect", "group": "aspect",
"type": "Switch", "component": "Switch",
"icon": "MdOutlineAnimation", "icon": "MdOutlineAnimation",
"title": "Reduce animation", "title": "Reduce animation",
"experimental": true "experimental": true
@ -15,7 +15,7 @@ export default [
"id": "darkMode", "id": "darkMode",
"storaged": true, "storaged": true,
"group": "aspect", "group": "aspect",
"type": "Switch", "component": "Switch",
"icon": "Moon", "icon": "Moon",
"title": "Dark mode", "title": "Dark mode",
"emitEvent": "theme.applyVariant", "emitEvent": "theme.applyVariant",
@ -27,7 +27,7 @@ export default [
"id": "primaryColor", "id": "primaryColor",
"storaged": true, "storaged": true,
"group": "aspect", "group": "aspect",
"type": "SliderColorPicker", "component": "SliderColorPicker",
"title": "Primary color", "title": "Primary color",
"description": "Change primary color of the application.", "description": "Change primary color of the application.",
"emitEvent": "modifyTheme", "emitEvent": "modifyTheme",
@ -42,7 +42,7 @@ export default [
"id": "resetTheme", "id": "resetTheme",
"storaged": true, "storaged": true,
"group": "aspect", "group": "aspect",
"type": "Button", "component": "Button",
"title": "Reset theme", "title": "Reset theme",
"props": { "props": {
"children": "Default Theme" "children": "Default Theme"

View File

@ -28,16 +28,15 @@ const ItemTypes = {
const SettingItem = (props) => { const SettingItem = (props) => {
let { item } = props let { item } = props
const [loading, setLoading] = React.useState(true) const [loading, setLoading] = React.useState(true)
const [value, setValue] = React.useState(item.defaultValue ?? false) const [value, setValue] = React.useState(item.defaultValue ?? false)
const [delayedValue, setDelayedValue] = React.useState(null) const [delayedValue, setDelayedValue] = React.useState(null)
if (!item.type) { let SettingComponent = item.component
console.error(`Item [${item.id}] has no an type!`)
return null if (!SettingComponent) {
} console.error(`Item [${item.id}] has no an component!`)
if (typeof ItemTypes[item.type] === "undefined") {
console.error(`Item [${item.id}] has an invalid type: ${item.type}`)
return null return null
} }
@ -142,54 +141,67 @@ const SettingItem = (props) => {
settingInitialization() settingInitialization()
}, []) }, [])
switch (item.type.toLowerCase()) {
case "slidercolorpicker": {
item.props.onChange = (color) => {
item.props.color = color.hex
}
item.props.onChangeComplete = (color) => {
onUpdateItem(color.hex)
}
item.props.color = value if (typeof SettingComponent === "string") {
if (typeof ItemTypes[SettingComponent] === "undefined") {
console.error(`Item [${item.id}] has an invalid component: ${item.component}`)
return null
}
break // fix props
}
case "textarea": { switch (SettingComponent.toLowerCase()) {
item.props.defaultValue = value case "slidercolorpicker": {
item.props.onPressEnter = (event) => dispatchUpdate(event.target.value) item.props.onChange = (color) => {
item.props.onChange = (event) => onUpdateItem(event.target.value) item.props.color = color.hex
break }
} item.props.onChangeComplete = (color) => {
case "input": { onUpdateItem(color.hex)
item.props.defaultValue = value }
item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
item.props.onChange = (event) => onUpdateItem(event.target.value) item.props.color = value
break
} break
case "switch": { }
item.props.checked = value case "textarea": {
item.props.onClick = (event) => onUpdateItem(event) item.props.defaultValue = value
break item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
} item.props.onChange = (event) => onUpdateItem(event.target.value)
case "select": { break
item.props.onChange = (value) => onUpdateItem(value) }
item.props.defaultValue = value case "input": {
break item.props.defaultValue = value
} item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
case "slider": { item.props.onChange = (event) => onUpdateItem(event.target.value)
item.props.defaultValue = value break
item.props.onAfterChange = (value) => onUpdateItem(value) }
break case "switch": {
} item.props.checked = value
default: { item.props.onClick = (event) => onUpdateItem(event)
if (!item.props.children) { break
item.props.children = item.title ?? item.id }
case "select": {
item.props.onChange = (value) => onUpdateItem(value)
item.props.defaultValue = value
break
}
case "slider": {
item.props.defaultValue = value
item.props.onAfterChange = (value) => onUpdateItem(value)
break
}
default: {
if (!item.props.children) {
item.props.children = item.title ?? item.id
}
item.props.value = item.defaultValue
item.props.onClick = (event) => onUpdateItem(event)
break
} }
item.props.value = item.defaultValue
item.props.onClick = (event) => onUpdateItem(event)
break
} }
// override with default item component
SettingComponent = ItemTypes[SettingComponent]
} }
return <div key={item.id} className="settingItem"> return <div key={item.id} className="settingItem">
@ -230,7 +242,7 @@ const SettingItem = (props) => {
</div> </div>
<div className="component"> <div className="component">
<div> <div>
{loading ? <div> Loading... </div> : React.createElement(ItemTypes[item.type], item.props)} {loading ? <div> Loading... </div> : React.createElement(SettingComponent, item.props)}
</div> </div>
{delayedValue && <div> {delayedValue && <div>