mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
Merge branch 'master' into core-integration
This commit is contained in:
commit
0dfbd5a556
@ -14,8 +14,8 @@ export default {
|
||||
},
|
||||
remotes: {
|
||||
mainApi: process.env.NODE_ENV !== "production" ? `http://${window.location.hostname}:3000` : defaultRemotesOrigins.main_api,
|
||||
streamingApi: defaultRemotesOrigins.streaming_api,
|
||||
websocketApi: process.env.NODE_ENV !== "production" ? `ws://${window.location.hostname}:3000` : defaultRemotesOrigins.websocket_api,
|
||||
streamingApi: process.env.NODE_ENV !== "production" ? `https://${window.location.hostname}:3002` : defaultRemotesOrigins.streaming_api,
|
||||
websocketApi: process.env.NODE_ENV !== "production" ? `ws://${window.location.hostname}:3001` : defaultRemotesOrigins.websocket_api,
|
||||
},
|
||||
app: {
|
||||
title: packagejson.name,
|
||||
|
@ -5,7 +5,7 @@ export default [
|
||||
{
|
||||
"id": "username",
|
||||
"group": "account.basicInfo",
|
||||
"type": "Button",
|
||||
"component": "Button",
|
||||
"icon": "AtSign",
|
||||
"title": "Username",
|
||||
"description": "Your username is the name you use to log in to your account.",
|
||||
@ -17,7 +17,7 @@ export default [
|
||||
{
|
||||
"id": "fullName",
|
||||
"group": "account.basicInfo",
|
||||
"type": "Input",
|
||||
"component": "Input",
|
||||
"icon": "Edit3",
|
||||
"title": "Name",
|
||||
"description": "Change your public name",
|
||||
@ -57,7 +57,7 @@ export default [
|
||||
{
|
||||
"id": "email",
|
||||
"group": "account.basicInfo",
|
||||
"type": "Input",
|
||||
"component": "Input",
|
||||
"icon": "Mail",
|
||||
"title": "Email",
|
||||
"description": "Change your email address",
|
||||
@ -87,7 +87,7 @@ export default [
|
||||
{
|
||||
"id": "avatar",
|
||||
"group": "account.profile",
|
||||
"type": "ImageUpload",
|
||||
"component": "ImageUpload",
|
||||
"icon": "Image",
|
||||
"title": "Avatar",
|
||||
"description": "Change your avatar",
|
||||
@ -95,7 +95,7 @@ export default [
|
||||
{
|
||||
"id": "cover",
|
||||
"group": "account.profile",
|
||||
"type": "ImageUpload",
|
||||
"component": "ImageUpload",
|
||||
"icon": "Image",
|
||||
"title": "Cover",
|
||||
"description": "Change your cover",
|
||||
@ -103,7 +103,7 @@ export default [
|
||||
{
|
||||
"id": "primaryBadge",
|
||||
"group": "account.profile",
|
||||
"type": "Select",
|
||||
"component": "Select",
|
||||
"icon": "Tag",
|
||||
"title": "Primary badge",
|
||||
"description": "Change your primary badge",
|
||||
@ -111,7 +111,7 @@ export default [
|
||||
{
|
||||
"id": "description",
|
||||
"group": "account.profile",
|
||||
"type": "TextArea",
|
||||
"component": "TextArea",
|
||||
"icon": "Edit3",
|
||||
"title": "Description",
|
||||
"description": "Change your description for your profile",
|
||||
@ -141,7 +141,7 @@ export default [
|
||||
{
|
||||
"id": "logout",
|
||||
"footer": true,
|
||||
"type": "Button",
|
||||
"component": "Button",
|
||||
"icon": "LogOut",
|
||||
"title": "Logout",
|
||||
"emitEvent": "session.logout",
|
||||
|
@ -7,7 +7,7 @@ export default [
|
||||
"id": "language",
|
||||
"storaged": true,
|
||||
"group": "general",
|
||||
"type": "Select",
|
||||
"component": "Select",
|
||||
"icon": "MdTranslate",
|
||||
"title": "Language",
|
||||
"description": "Choose a language for the application",
|
||||
@ -22,7 +22,7 @@ export default [
|
||||
"id": "forceMobileMode",
|
||||
"storaged": true,
|
||||
"group": "general",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "MdSmartphone",
|
||||
"title": "Force Mobile Mode",
|
||||
"description": "Force the application to run in mobile mode.",
|
||||
@ -32,7 +32,7 @@ export default [
|
||||
"id": "haptic_feedback",
|
||||
"storaged": true,
|
||||
"group": "general",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "MdVibration",
|
||||
"title": "Haptic Feedback",
|
||||
"description": "Enable haptic feedback on touch events.",
|
||||
@ -41,7 +41,7 @@ export default [
|
||||
"id": "selection_longPress_timeout",
|
||||
"storaged": true,
|
||||
"group": "general",
|
||||
"type": "Slider",
|
||||
"component": "Slider",
|
||||
"icon": "MdTimer",
|
||||
"title": "Selection press delay",
|
||||
"description": "Set the delay before the selection trigger is activated.",
|
||||
@ -62,7 +62,7 @@ export default [
|
||||
"id": "notifications_sound",
|
||||
"storaged": true,
|
||||
"group": "notifications",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "MdVolumeUp",
|
||||
"title": "Notifications Sound",
|
||||
"description": "Play a sound when a notification is received.",
|
||||
@ -71,7 +71,7 @@ export default [
|
||||
"id": "notifications_vibrate",
|
||||
"storaged": true,
|
||||
"group": "notifications",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "MdVibration",
|
||||
"title": "Vibration",
|
||||
"description": "Vibrate the device when a notification is received.",
|
||||
@ -81,7 +81,7 @@ export default [
|
||||
"id": "notifications_sound_volume",
|
||||
"storaged": true,
|
||||
"group": "notifications",
|
||||
"type": "Slider",
|
||||
"component": "Slider",
|
||||
"icon": "MdVolumeUp",
|
||||
"title": "Sound Volume",
|
||||
"description": "Set the volume of the sound when a notification is received.",
|
||||
@ -96,7 +96,7 @@ export default [
|
||||
"id": "edit_sidebar",
|
||||
"storaged": true,
|
||||
"group": "sidebar",
|
||||
"type": "Button",
|
||||
"component": "Button",
|
||||
"icon": "Edit",
|
||||
"title": "Edit Sidebar",
|
||||
"emitEvent": "edit_sidebar",
|
||||
@ -106,7 +106,7 @@ export default [
|
||||
"id": "collapseOnLooseFocus",
|
||||
"storaged": true,
|
||||
"group": "sidebar",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "Columns",
|
||||
"title": "Auto Collapse",
|
||||
"description": "Collapse the sidebar when loose focus",
|
||||
@ -116,7 +116,7 @@ export default [
|
||||
"id": "autoCollapseDelay",
|
||||
"storaged": true,
|
||||
"group": "sidebar",
|
||||
"type": "Slider",
|
||||
"component": "Slider",
|
||||
"icon": "Wh",
|
||||
"dependsOn": {
|
||||
"collapseOnLooseFocus": true
|
||||
|
@ -5,17 +5,33 @@ export default [
|
||||
"id": "reduceAnimations",
|
||||
"storaged": true,
|
||||
"group": "aspect",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "MdOutlineAnimation",
|
||||
"title": "Reduce animation",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"id": "auto_darkMode",
|
||||
"dependsOn": {
|
||||
"darkMode": false
|
||||
},
|
||||
"experimental": true,
|
||||
"storaged": true,
|
||||
"group": "aspect",
|
||||
"component": "Switch",
|
||||
"icon": "Moon",
|
||||
"title": "Auto dark mode",
|
||||
"emitEvent": "app.autoDarkModeToogle",
|
||||
},
|
||||
{
|
||||
"experimental": true,
|
||||
"dependsOn": {
|
||||
"auto_darkMode": false
|
||||
},
|
||||
"id": "darkMode",
|
||||
"storaged": true,
|
||||
"group": "aspect",
|
||||
"type": "Switch",
|
||||
"component": "Switch",
|
||||
"icon": "Moon",
|
||||
"title": "Dark mode",
|
||||
"emitEvent": "theme.applyVariant",
|
||||
@ -27,7 +43,7 @@ export default [
|
||||
"id": "primaryColor",
|
||||
"storaged": true,
|
||||
"group": "aspect",
|
||||
"type": "SliderColorPicker",
|
||||
"component": "SliderColorPicker",
|
||||
"title": "Primary color",
|
||||
"description": "Change primary color of the application.",
|
||||
"emitEvent": "modifyTheme",
|
||||
@ -42,7 +58,7 @@ export default [
|
||||
"id": "resetTheme",
|
||||
"storaged": true,
|
||||
"group": "aspect",
|
||||
"type": "Button",
|
||||
"component": "Button",
|
||||
"title": "Reset theme",
|
||||
"props": {
|
||||
"children": "Default Theme"
|
||||
|
@ -28,16 +28,16 @@ const ItemTypes = {
|
||||
|
||||
const SettingItem = (props) => {
|
||||
let { item } = props
|
||||
|
||||
const [loading, setLoading] = React.useState(true)
|
||||
const [value, setValue] = React.useState(item.defaultValue ?? false)
|
||||
const [delayedValue, setDelayedValue] = React.useState(null)
|
||||
const [disabled, setDisabled] = React.useState(false)
|
||||
|
||||
if (!item.type) {
|
||||
console.error(`Item [${item.id}] has no an type!`)
|
||||
return null
|
||||
}
|
||||
if (typeof ItemTypes[item.type] === "undefined") {
|
||||
console.error(`Item [${item.id}] has an invalid type: ${item.type}`)
|
||||
let SettingComponent = item.component
|
||||
|
||||
if (!SettingComponent) {
|
||||
console.error(`Item [${item.id}] has no an component!`)
|
||||
return null
|
||||
}
|
||||
|
||||
@ -100,6 +100,29 @@ const SettingItem = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
const onUnmount = () => {
|
||||
// unsubscribe eventBus events
|
||||
if (typeof item.dependsOn === "object") {
|
||||
for (let key in item.dependsOn) {
|
||||
window.app.eventBus.off(`setting.update.${key}`, onUpdateItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const checkDependsValidation = () => {
|
||||
return !Boolean(Object.keys(item.dependsOn).every((key) => {
|
||||
const storagedValue = window.app.settings.get(key)
|
||||
|
||||
console.debug(`Checking validation for [${key}] with now value [${storagedValue}]`)
|
||||
|
||||
if (typeof item.dependsOn[key] === "function") {
|
||||
return item.dependsOn[key](storagedValue)
|
||||
}
|
||||
|
||||
return storagedValue === item.dependsOn[key]
|
||||
}))
|
||||
}
|
||||
|
||||
const settingInitialization = async () => {
|
||||
if (item.storaged) {
|
||||
const storagedValue = window.app.settings.get(item.id)
|
||||
@ -111,17 +134,15 @@ const SettingItem = (props) => {
|
||||
}
|
||||
|
||||
if (typeof item.dependsOn === "object") {
|
||||
const dependsOptionsKeys = Object.keys(item.dependsOn)
|
||||
// create a event handler to watch changes
|
||||
Object.keys(item.dependsOn).forEach((key) => {
|
||||
window.app.eventBus.on(`setting.update.${key}`, () => {
|
||||
setDisabled(checkDependsValidation())
|
||||
})
|
||||
})
|
||||
|
||||
item.props.disabled = !Boolean(dependsOptionsKeys.every((key) => {
|
||||
const storagedValue = window.app.settings.get(key)
|
||||
|
||||
if (typeof item.dependsOn[key] === "function") {
|
||||
return item.dependsOn[key](storagedValue)
|
||||
}
|
||||
|
||||
return storagedValue === item.dependsOn[key]
|
||||
}))
|
||||
// by default check depends validation
|
||||
setDisabled(checkDependsValidation())
|
||||
}
|
||||
|
||||
if (typeof item.listenUpdateValue === "string") {
|
||||
@ -140,9 +161,19 @@ const SettingItem = (props) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
settingInitialization()
|
||||
|
||||
return onUnmount
|
||||
}, [])
|
||||
|
||||
switch (item.type.toLowerCase()) {
|
||||
if (typeof SettingComponent === "string") {
|
||||
if (typeof ItemTypes[SettingComponent] === "undefined") {
|
||||
console.error(`Item [${item.id}] has an invalid component: ${item.component}`)
|
||||
return null
|
||||
}
|
||||
|
||||
// fix props
|
||||
|
||||
switch (SettingComponent.toLowerCase()) {
|
||||
case "slidercolorpicker": {
|
||||
item.props.onChange = (color) => {
|
||||
item.props.color = color.hex
|
||||
@ -186,12 +217,20 @@ const SettingItem = (props) => {
|
||||
if (!item.props.children) {
|
||||
item.props.children = item.title ?? item.id
|
||||
}
|
||||
|
||||
item.props.value = item.defaultValue
|
||||
item.props.onClick = (event) => onUpdateItem(event)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// override with default item component
|
||||
SettingComponent = ItemTypes[SettingComponent]
|
||||
}
|
||||
|
||||
item.props["disabled"] = disabled
|
||||
|
||||
return <div key={item.id} className="settingItem">
|
||||
<div className="header">
|
||||
<div className="title">
|
||||
@ -230,7 +269,7 @@ const SettingItem = (props) => {
|
||||
</div>
|
||||
<div className="component">
|
||||
<div>
|
||||
{loading ? <div> Loading... </div> : React.createElement(ItemTypes[item.type], item.props)}
|
||||
{loading ? <div> Loading... </div> : React.createElement(SettingComponent, item.props)}
|
||||
</div>
|
||||
|
||||
{delayedValue && <div>
|
||||
|
@ -12,6 +12,11 @@ export default class StyleCore extends Core {
|
||||
currentVariant = null
|
||||
|
||||
events = {
|
||||
"app.autoDarkMode": (value) => {
|
||||
if (value === true) {
|
||||
this.handleAutoColorScheme()
|
||||
}
|
||||
},
|
||||
"theme.applyVariant": (value) => {
|
||||
this.applyVariant(value)
|
||||
this.setVariant(value)
|
||||
@ -33,6 +38,16 @@ export default class StyleCore extends Core {
|
||||
return document.documentElement.style.getPropertyValue("--themeVariant")
|
||||
}
|
||||
|
||||
handleAutoColorScheme() {
|
||||
const prefered = window.matchMedia("(prefers-color-scheme: light)")
|
||||
|
||||
if (window.app.settings.get("app.auto_darkMode") && !prefered.matches) {
|
||||
this.applyVariant("dark")
|
||||
}else {
|
||||
this.applyVariant("false")
|
||||
}
|
||||
}
|
||||
|
||||
initialize = async () => {
|
||||
let theme = this.getStoragedTheme()
|
||||
|
||||
@ -61,6 +76,11 @@ export default class StyleCore extends Core {
|
||||
|
||||
// apply variation
|
||||
this.applyVariant(variantKey)
|
||||
|
||||
// handle auto prefered color scheme
|
||||
if (window.app.settings.get("app.auto_darkMode")) {
|
||||
window.matchMedia("(prefers-color-scheme: light)").addListener(this.handleAutoColorScheme)
|
||||
}
|
||||
}
|
||||
|
||||
getRootVariables = () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user