Merge branch 'master' into core-integration

This commit is contained in:
srgooglo 2022-05-31 01:12:56 +02:00 committed by GitHub
commit e970a892f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 163 additions and 88 deletions

View File

@ -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,

View File

@ -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",

View File

@ -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

View File

@ -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"

View File

@ -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,58 +161,76 @@ const SettingItem = (props) => {
React.useEffect(() => {
settingInitialization()
return onUnmount
}, [])
switch (item.type.toLowerCase()) {
case "slidercolorpicker": {
item.props.onChange = (color) => {
item.props.color = color.hex
}
item.props.onChangeComplete = (color) => {
onUpdateItem(color.hex)
}
if (typeof SettingComponent === "string") {
if (typeof ItemTypes[SettingComponent] === "undefined") {
console.error(`Item [${item.id}] has an invalid component: ${item.component}`)
return null
}
item.props.color = value
// fix props
break
}
case "textarea": {
item.props.defaultValue = value
item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
item.props.onChange = (event) => onUpdateItem(event.target.value)
break
}
case "input": {
item.props.defaultValue = value
item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
item.props.onChange = (event) => onUpdateItem(event.target.value)
break
}
case "switch": {
item.props.checked = value
item.props.onClick = (event) => onUpdateItem(event)
break
}
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
switch (SettingComponent.toLowerCase()) {
case "slidercolorpicker": {
item.props.onChange = (color) => {
item.props.color = color.hex
}
item.props.onChangeComplete = (color) => {
onUpdateItem(color.hex)
}
item.props.color = value
break
}
case "textarea": {
item.props.defaultValue = value
item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
item.props.onChange = (event) => onUpdateItem(event.target.value)
break
}
case "input": {
item.props.defaultValue = value
item.props.onPressEnter = (event) => dispatchUpdate(event.target.value)
item.props.onChange = (event) => onUpdateItem(event.target.value)
break
}
case "switch": {
item.props.checked = value
item.props.onClick = (event) => onUpdateItem(event)
break
}
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]
}
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>

View File

@ -106,11 +106,11 @@ export class RouteRender extends EvitePureComponent {
export class RenderCore extends Core {
progressBar = progressBar.configure({ parent: "html", showSpinner: false })
publicMethods = {
bindContexts: RenderCore.bindContexts,
}
initialize = () => {
const defaultTransitionDelay = 150

View File

@ -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)
@ -28,11 +33,21 @@ export default class StyleCore extends Core {
publicMethods = {
style: this
}
static get currentVariant() {
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 = () => {