mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
update: app theme update
This commit is contained in:
parent
9b4c382df2
commit
224d46e20f
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
# production
|
# production
|
||||||
/dist
|
/dist
|
||||||
/out
|
|
||||||
/api
|
|
||||||
|
|
||||||
# umi
|
# umi
|
||||||
/src/.umi
|
/src/.umi
|
||||||
|
@ -13,6 +13,7 @@ export default defineConfig({
|
|||||||
loading: 'components/Loader/Loader.js',
|
loading: 'components/Loader/Loader.js',
|
||||||
},
|
},
|
||||||
dva: { immer: true },
|
dva: { immer: true },
|
||||||
|
antd: {},
|
||||||
nodeModulesTransform: {
|
nodeModulesTransform: {
|
||||||
type: 'none',
|
type: 'none',
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
|
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
|
||||||
"title": "Comty™",
|
"title": "Comty™",
|
||||||
"DevBuild": true,
|
"DevBuild": true,
|
||||||
"version": "0.4.04",
|
"version": "0.8.08",
|
||||||
"stage": "dev-pre",
|
"stage": "dev-pre",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "RageStudio",
|
"author": "RageStudio",
|
||||||
|
@ -25,7 +25,6 @@ export let Swapper = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@connect(({ app }) => ({ app }))
|
@connect(({ app }) => ({ app }))
|
||||||
export default class Overlay extends React.PureComponent {
|
export default class Overlay extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|
||||||
z-index: 40;
|
z-index: 40;
|
||||||
float: left;
|
float: left;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -22,7 +22,7 @@
|
|||||||
float: right;
|
float: right;
|
||||||
.ant-menu {
|
.ant-menu {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: @AppTheme_global_color;
|
color: unset;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
// margin: 0 0 0 5px;
|
// margin: 0 0 0 5px;
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,19 @@ import verbosity from 'core/libs/verbosity'
|
|||||||
export const OVERLAY_BADPOSITION = `Invalid overlay position! Was expected "primary" or "secondary"`
|
export const OVERLAY_BADPOSITION = `Invalid overlay position! Was expected "primary" or "secondary"`
|
||||||
export const INTERNAL_PROCESS_FAILED = `An internal error has occurred! `
|
export const INTERNAL_PROCESS_FAILED = `An internal error has occurred! `
|
||||||
export const INVALID_DATA = `A function has been executed with invalid data and has caused an error!`
|
export const INVALID_DATA = `A function has been executed with invalid data and has caused an error!`
|
||||||
|
export const INVALID_PROPS = `Some props failed!`
|
||||||
// HANDLERS
|
// HANDLERS
|
||||||
export const onError = {
|
export const onError = {
|
||||||
internal_proccess: (...rest) => {
|
internal_proccess: (...rest) => {
|
||||||
verbosity.error(...rest)
|
verbosity.error(...rest)
|
||||||
notify.warn(INTERNAL_PROCESS_FAILED, ...rest)
|
notify.open({
|
||||||
|
message: INTERNAL_PROCESS_FAILED,
|
||||||
|
description:
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', margin: 'auto' }}>
|
||||||
|
<div style={{ margin: '10px 0' }}> {JSON.stringify(...rest)} </div>
|
||||||
|
</div>,
|
||||||
|
|
||||||
|
})
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
invalid_data: (error, expecting) => {
|
invalid_data: (error, expecting) => {
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
// JSON.prune : a function to stringify any object without overflow
|
|
||||||
// two additional optional parameters :
|
|
||||||
// - the maximal depth (default : 6)
|
|
||||||
// - the maximal length of arrays (default : 50)
|
|
||||||
// You can also pass an "options" object.
|
|
||||||
// examples :
|
|
||||||
// var json = JSON.prune(window)
|
|
||||||
// var arr = Array.apply(0,Array(1000)); var json = JSON.prune(arr, 4, 20)
|
|
||||||
// var json = JSON.prune(window.location, {inheritedProperties:true})
|
|
||||||
// Web site : http://dystroy.org/JSON.prune/
|
|
||||||
// JSON.prune on github : https://github.com/Canop/JSON.prune
|
|
||||||
// This was discussed here : http://stackoverflow.com/q/13861254/263525
|
|
||||||
// The code is based on Douglas Crockford's code : https://github.com/douglascrockford/JSON-js/blob/master/json2.js
|
|
||||||
// No effort was done to support old browsers. JSON.prune will fail on IE8.
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var DEFAULT_MAX_DEPTH = 6;
|
|
||||||
var DEFAULT_ARRAY_MAX_LENGTH = 50;
|
|
||||||
var DEFAULT_PRUNED_VALUE = '"-pruned-"';
|
|
||||||
var seen; // Same variable used for all stringifications
|
|
||||||
var iterator; // either forEachEnumerableOwnProperty, forEachEnumerableProperty or forEachProperty
|
|
||||||
|
|
||||||
// iterates on enumerable own properties (default behavior)
|
|
||||||
var forEachEnumerableOwnProperty = function(obj, callback) {
|
|
||||||
for (var k in obj) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(obj, k)) callback(k);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// iterates on enumerable properties
|
|
||||||
var forEachEnumerableProperty = function(obj, callback) {
|
|
||||||
for (var k in obj) callback(k);
|
|
||||||
};
|
|
||||||
// iterates on properties, even non enumerable and inherited ones
|
|
||||||
// This is dangerous
|
|
||||||
var forEachProperty = function(obj, callback, excluded) {
|
|
||||||
if (obj==null) return;
|
|
||||||
excluded = excluded || {};
|
|
||||||
Object.getOwnPropertyNames(obj).forEach(function(k){
|
|
||||||
if (!excluded[k]) {
|
|
||||||
callback(k);
|
|
||||||
excluded[k] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
forEachProperty(Object.getPrototypeOf(obj), callback, excluded);
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.defineProperty(Date.prototype, "toPrunedJSON", {value:Date.prototype.toJSON});
|
|
||||||
|
|
||||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
|
||||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
|
||||||
meta = { // table of character substitutions
|
|
||||||
'\b': '\\b',
|
|
||||||
'\t': '\\t',
|
|
||||||
'\n': '\\n',
|
|
||||||
'\f': '\\f',
|
|
||||||
'\r': '\\r',
|
|
||||||
'"' : '\\"',
|
|
||||||
'\\': '\\\\'
|
|
||||||
};
|
|
||||||
|
|
||||||
function quote(string) {
|
|
||||||
escapable.lastIndex = 0;
|
|
||||||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
|
||||||
var c = meta[a];
|
|
||||||
return typeof c === 'string'
|
|
||||||
? c
|
|
||||||
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
|
||||||
}) + '"' : '"' + string + '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var prune = function (value, depthDecr, arrayMaxLength) {
|
|
||||||
var prunedString = DEFAULT_PRUNED_VALUE;
|
|
||||||
var replacer;
|
|
||||||
if (typeof depthDecr == "object") {
|
|
||||||
var options = depthDecr;
|
|
||||||
depthDecr = options.depthDecr;
|
|
||||||
arrayMaxLength = options.arrayMaxLength;
|
|
||||||
iterator = options.iterator || forEachEnumerableOwnProperty;
|
|
||||||
if (options.allProperties) iterator = forEachProperty;
|
|
||||||
else if (options.inheritedProperties) iterator = forEachEnumerableProperty
|
|
||||||
if ("prunedString" in options) {
|
|
||||||
prunedString = options.prunedString;
|
|
||||||
}
|
|
||||||
if (options.replacer) {
|
|
||||||
replacer = options.replacer;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
iterator = forEachEnumerableOwnProperty;
|
|
||||||
}
|
|
||||||
seen = [];
|
|
||||||
depthDecr = depthDecr || DEFAULT_MAX_DEPTH;
|
|
||||||
arrayMaxLength = arrayMaxLength || DEFAULT_ARRAY_MAX_LENGTH;
|
|
||||||
function str(key, holder, depthDecr) {
|
|
||||||
var i, k, v, length, partial, value = holder[key];
|
|
||||||
|
|
||||||
if (value && typeof value === 'object' && typeof value.toPrunedJSON === 'function') {
|
|
||||||
value = value.toPrunedJSON(key);
|
|
||||||
}
|
|
||||||
if (value && typeof value.toJSON === 'function') {
|
|
||||||
value = value.toJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (typeof value) {
|
|
||||||
case 'string':
|
|
||||||
return quote(value);
|
|
||||||
case 'number':
|
|
||||||
return isFinite(value) ? String(value) : 'null';
|
|
||||||
case 'boolean':
|
|
||||||
case 'null':
|
|
||||||
return String(value);
|
|
||||||
case 'object':
|
|
||||||
if (!value) {
|
|
||||||
return 'null';
|
|
||||||
}
|
|
||||||
if (depthDecr<=0 || seen.indexOf(value)!==-1) {
|
|
||||||
if (replacer) {
|
|
||||||
var replacement = replacer(value, prunedString, true);
|
|
||||||
return replacement===undefined ? undefined : ''+replacement;
|
|
||||||
}
|
|
||||||
return prunedString;
|
|
||||||
}
|
|
||||||
seen.push(value);
|
|
||||||
partial = [];
|
|
||||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
|
||||||
length = Math.min(value.length, arrayMaxLength);
|
|
||||||
for (i = 0; i < length; i += 1) {
|
|
||||||
partial[i] = str(i, value, depthDecr-1) || 'null';
|
|
||||||
}
|
|
||||||
v = '[' + partial.join(',') + ']';
|
|
||||||
if (replacer && value.length>arrayMaxLength) return replacer(value, v, false);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
if (value instanceof RegExp) {
|
|
||||||
return quote(value.toString());
|
|
||||||
}
|
|
||||||
iterator(value, function(k) {
|
|
||||||
try {
|
|
||||||
v = str(k, value, depthDecr-1);
|
|
||||||
if (v) partial.push(quote(k) + ':' + v);
|
|
||||||
} catch (e) {
|
|
||||||
// this try/catch due to forbidden accessors on some objects
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return '{' + partial.join(',') + '}';
|
|
||||||
case 'function':
|
|
||||||
case 'undefined':
|
|
||||||
return replacer ? replacer(value, undefined, false) : undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str('', {'': value}, depthDecr);
|
|
||||||
};
|
|
||||||
|
|
||||||
prune.log = function() {
|
|
||||||
console.log.apply(console, Array.prototype.map.call(arguments, function(v) {
|
|
||||||
return JSON.parse(JSON.prune(v));
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
prune.forEachProperty = forEachProperty; // you might want to also assign it to Object.forEachProperty
|
|
||||||
|
|
||||||
export default prune
|
|
@ -16,7 +16,7 @@ const LayoutMap = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@withRouter
|
@withRouter
|
||||||
@connect(({ loading }) => ({ loading }))
|
@connect(({ app, loading }) => ({ app, loading }))
|
||||||
class BaseLayout extends PureComponent {
|
class BaseLayout extends PureComponent {
|
||||||
previousPath = ''
|
previousPath = ''
|
||||||
|
|
||||||
@ -33,14 +33,13 @@ class BaseLayout extends PureComponent {
|
|||||||
NProgress.done()
|
NProgress.done()
|
||||||
this.previousPath = currentPath
|
this.previousPath = currentPath
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{config.app_config.siteName}</title>
|
<title>{config.app_config.siteName}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
{Loader(loading)}
|
{Loader(loading)}
|
||||||
<Container>{children}</Container>
|
<Container>{children}</Container>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,11 @@ import styles from './PrimaryLayout.less'
|
|||||||
|
|
||||||
const { Content } = antd.Layout
|
const { Content } = antd.Layout
|
||||||
const { Sider, Control, Overlay } = MyLayout
|
const { Sider, Control, Overlay } = MyLayout
|
||||||
|
const isActive = (key) => { return key? key.active : false }
|
||||||
|
|
||||||
@withRouter
|
@withRouter
|
||||||
@connect(({ app, loading }) => ({ app, loading }))
|
@connect(({ app, loading }) => ({ app, loading }))
|
||||||
class PrimaryLayout extends React.PureComponent {
|
class PrimaryLayout extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -30,7 +31,6 @@ class PrimaryLayout extends React.PureComponent {
|
|||||||
isMobile: false,
|
isMobile: false,
|
||||||
},
|
},
|
||||||
window.PrimaryComponent = this;
|
window.PrimaryComponent = this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -54,49 +54,53 @@ class PrimaryLayout extends React.PureComponent {
|
|||||||
store.set('collapsed', !fromStore)
|
store.set('collapsed', !fromStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderThemeComponents() {
|
|
||||||
const currentTheme = theme.get()
|
|
||||||
if (!currentTheme) return false
|
|
||||||
if (currentTheme.backgroundImage) {
|
|
||||||
return currentTheme.backgroundImage.active? <div style={{
|
|
||||||
backgroundImage: `url(${currentTheme.backgroundImage.src})`,
|
|
||||||
transition: "all 150ms linear",
|
|
||||||
position: 'absolute',
|
|
||||||
width: '100vw',
|
|
||||||
height: '100vh',
|
|
||||||
backgroundRepeat: "repeat-x",
|
|
||||||
backgroundSize: "cover",
|
|
||||||
backgroundPositionY: "center",
|
|
||||||
overflow: "hidden",
|
|
||||||
opacity: currentTheme.backgroundImage.opacity
|
|
||||||
}} /> : null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
render() {
|
render() {
|
||||||
const { location, dispatch, children } = this.props
|
const { location, dispatch, children } = this.props
|
||||||
const { collapsed, isMobile } = this.state
|
const { collapsed, isMobile } = this.state
|
||||||
const { onCollapseChange } = this
|
const { onCollapseChange } = this
|
||||||
|
const currentTheme = theme.get()
|
||||||
|
const breakpoint = {
|
||||||
|
xs: '480px',
|
||||||
|
sm: '576px',
|
||||||
|
md: '768px',
|
||||||
|
lg: '992px',
|
||||||
|
xl: '1200px',
|
||||||
|
xxl: '1600px',
|
||||||
|
}
|
||||||
|
|
||||||
const SiderProps = {
|
const SiderProps = {
|
||||||
breakpoint:{
|
breakpoint,
|
||||||
xs: '480px',
|
|
||||||
sm: '576px',
|
|
||||||
md: '768px',
|
|
||||||
lg: '992px',
|
|
||||||
xl: '1200px',
|
|
||||||
xxl: '1600px',
|
|
||||||
},
|
|
||||||
isMobile,
|
isMobile,
|
||||||
collapsed,
|
collapsed,
|
||||||
onCollapseChange
|
onCollapseChange,
|
||||||
|
theme: isActive(currentTheme["darkmode"])? "dark" : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const OverlayProps = {
|
||||||
|
breakpoint,
|
||||||
|
isMobile,
|
||||||
|
theme: isActive(currentTheme["darkmode"])? "dark" : null
|
||||||
|
}
|
||||||
|
|
||||||
|
window.DarkMode = isActive(currentTheme["darkmode"])? true : false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Control />
|
<Control />
|
||||||
{this.renderThemeComponents()}
|
{isActive(currentTheme['backgroundImage'])? <div style={{
|
||||||
<antd.Layout id="primaryLayout" className={classnames(styles.primary_layout, {[styles.mobile]: isMobile})}>
|
backgroundImage: `url(${currentTheme.backgroundImage.src})`,
|
||||||
|
transition: "all 150ms linear",
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100vw',
|
||||||
|
height: '100vh',
|
||||||
|
backgroundRepeat: "repeat-x",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundPositionY: "center",
|
||||||
|
overflow: "hidden",
|
||||||
|
opacity: currentTheme.backgroundImage.opacity
|
||||||
|
}} /> : null}
|
||||||
|
<antd.Layout id="app" className={isActive(currentTheme['darkmode'])? "dark_mode" : null }>
|
||||||
<Sider {...SiderProps} />
|
<Sider {...SiderProps} />
|
||||||
<div className={styles.primary_layout_container}>
|
<div className={styles.primary_layout_container}>
|
||||||
<PageTransition
|
<PageTransition
|
||||||
@ -111,7 +115,7 @@ class PrimaryLayout extends React.PureComponent {
|
|||||||
</Content>
|
</Content>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
</div>
|
</div>
|
||||||
<Overlay />
|
<Overlay {...OverlayProps} />
|
||||||
</antd.Layout>
|
</antd.Layout>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
|
@ -1,31 +1,5 @@
|
|||||||
@import '~theme/index.less';
|
@import '~theme/index.less';
|
||||||
|
|
||||||
.primary_layout {
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
background-size: cover;
|
|
||||||
background-position-y: center;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: transparent;
|
|
||||||
margin: auto;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
|
|
||||||
transition: all @__Global_Components_transitions_dur linear;
|
|
||||||
|
|
||||||
&.mobile{
|
|
||||||
>.primary_layout_container {
|
|
||||||
padding: 0;
|
|
||||||
overflow-y: overlay;
|
|
||||||
overflow-x: hidden;
|
|
||||||
min-width: unset;
|
|
||||||
}
|
|
||||||
.primary_layout_content{
|
|
||||||
padding: 35px 15px 15px 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRIMARY LAYOUT
|
// PRIMARY LAYOUT
|
||||||
.primary_layout_container {
|
.primary_layout_container {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
@ -31,7 +31,6 @@ export default {
|
|||||||
app_theme: store.get(app_config.appTheme_container) || [],
|
app_theme: store.get(app_config.appTheme_container) || [],
|
||||||
notifications: [],
|
notifications: [],
|
||||||
locationQuery: {},
|
locationQuery: {},
|
||||||
|
|
||||||
},
|
},
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
setup({ dispatch }) {
|
setup({ dispatch }) {
|
||||||
@ -116,24 +115,28 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
*updateTheme({payload}, {put, select}){
|
*updateTheme({payload}, {put, select}){
|
||||||
if (!payload) return false;
|
if (!payload) return false
|
||||||
let container = yield select(state => state.app.app_theme);
|
let container = yield select(state => state.app.app_theme)
|
||||||
let container_2 = []
|
let style_keys = []
|
||||||
|
let tmp = []
|
||||||
|
|
||||||
|
container.forEach((e)=>{style_keys[e.key] = e.value})
|
||||||
|
|
||||||
const containerlength = Object.entries(container).length
|
if(!style_keys[payload.key]){
|
||||||
|
tmp.push({key: payload.key, value: payload.value})
|
||||||
if (container && containerlength > 1) {
|
|
||||||
container.forEach(e =>{
|
|
||||||
let tmp = {key: e.key}
|
|
||||||
e.key === payload.key? (tmp.value = payload.value) : (tmp.value = e.value)
|
|
||||||
container_2.push(tmp)
|
|
||||||
})
|
|
||||||
|
|
||||||
}else{
|
|
||||||
container_2 = [payload]
|
|
||||||
}
|
}
|
||||||
|
container.forEach((e) => {
|
||||||
|
let obj = {}
|
||||||
|
if(e.key === payload.key){
|
||||||
|
obj = { key: payload.key, value: payload.value }
|
||||||
|
}else{
|
||||||
|
obj = { key: e.key, value: e.value }
|
||||||
|
}
|
||||||
|
tmp.push(obj)
|
||||||
|
})
|
||||||
|
|
||||||
return container_2? yield put({ type: 'handleUpdateTheme', payload: container_2 }) : null
|
|
||||||
|
return tmp? yield put({ type: 'handleUpdateTheme', payload: tmp }) : null
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
reducers: {
|
reducers: {
|
||||||
|
@ -4,6 +4,9 @@ import * as antd from 'antd'
|
|||||||
|
|
||||||
@connect(({ app }) => ({ app }))
|
@connect(({ app }) => ({ app }))
|
||||||
class PageIndex extends React.PureComponent {
|
class PageIndex extends React.PureComponent {
|
||||||
|
constructor(props){
|
||||||
|
super(props)
|
||||||
|
}
|
||||||
state = {
|
state = {
|
||||||
app_state: null
|
app_state: null
|
||||||
}
|
}
|
||||||
@ -39,9 +42,10 @@ class PageIndex extends React.PureComponent {
|
|||||||
|
|
||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<antd.Card title="APP STATE">
|
<antd.Card theme={window.DarkMode? "dark" : null} title="APP STATE">
|
||||||
{AppState()}
|
{AppState()}
|
||||||
</antd.Card>
|
</antd.Card>
|
||||||
|
|
||||||
|
@ -5,39 +5,30 @@ import themeSettings from 'globals/theme_settings'
|
|||||||
import {connect} from 'umi'
|
import {connect} from 'umi'
|
||||||
import styles from './index.less'
|
import styles from './index.less'
|
||||||
|
|
||||||
import { SketchPicker } from 'react-color';
|
import { onError } from 'core/libs/errorhandler'
|
||||||
import { theme, getOptimalOpacityFromIMG, get_style_rule_value } from 'core/libs/style'
|
import { theme, getOptimalOpacityFromIMG, get_style_rule_value } from 'core/libs/style'
|
||||||
import { urlToBase64, imageToBase64, arrayToObject } from 'core'
|
import { urlToBase64, imageToBase64, arrayToObject } from 'core'
|
||||||
import exportDataAsFile from 'core/libs/interface/export_data'
|
import exportDataAsFile from 'core/libs/interface/export_data'
|
||||||
|
|
||||||
class BackgroundColor extends React.Component{
|
class ThemeConfigurator extends React.Component{
|
||||||
state = {
|
|
||||||
selected: "#fff"
|
componentDidMount(){
|
||||||
}
|
this.applyStoraged()
|
||||||
sendChanges(){
|
|
||||||
this.props.changeColor(this.state.selected)
|
|
||||||
}
|
|
||||||
selectColor = (color) =>{
|
|
||||||
this.setState({selected: color.hex})
|
|
||||||
}
|
|
||||||
render(){
|
|
||||||
return <>
|
|
||||||
<SketchPicker
|
|
||||||
color={this.state.selected}
|
|
||||||
onChangeComplete={this.selectColor}
|
|
||||||
/>
|
|
||||||
<antd.Button onClick={() => this.sendChanges()}> Change </antd.Button>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@connect(({ app }) => ({ app }))
|
|
||||||
class DarkMode extends React.Component{
|
|
||||||
state = {
|
|
||||||
model: { active: false, autoTime: '' }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyStoraged(){
|
||||||
|
const storaged = theme.get()
|
||||||
|
if(storaged && this.state){
|
||||||
|
storaged[this.state.key]? this.setState({ model: storaged[this.state.key]}) : onError.internal_proccess(`"Config key" or "Dispatcher" is missing`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
promiseState = async state => new Promise(resolve => this.setState(state, resolve));
|
||||||
|
|
||||||
handleUpdate(payload){
|
handleUpdate(payload){
|
||||||
|
if(!this.state.key || !this.props.dispatch) {
|
||||||
|
return onError.internal_proccess(`"Config key" or "Dispatcher" is missing`)
|
||||||
|
}
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
payload = this.state.model
|
payload = this.state.model
|
||||||
}
|
}
|
||||||
@ -45,13 +36,33 @@ class DarkMode extends React.Component{
|
|||||||
this.props.dispatch({
|
this.props.dispatch({
|
||||||
type: 'app/updateTheme',
|
type: 'app/updateTheme',
|
||||||
payload: {
|
payload: {
|
||||||
key: 'darkmode',
|
key: this.state.key,
|
||||||
value: payload
|
value: payload
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleErase(){
|
||||||
|
this.handleUpdate({})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleExport(){
|
||||||
|
exportDataAsFile({data: JSON.stringify(this.state.model), type: 'text/json'})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@connect(({ app }) => ({ app }))
|
||||||
|
class DarkMode extends ThemeConfigurator{
|
||||||
|
constructor(props){
|
||||||
|
super(props),
|
||||||
|
this.state = {
|
||||||
|
key: "darkmode",
|
||||||
|
model: { active: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
render(){
|
render(){
|
||||||
const promiseState = async state => new Promise(resolve => this.setState(state, resolve));
|
|
||||||
return <>
|
return <>
|
||||||
<div>
|
<div>
|
||||||
<h2><Icons.Moon /> Dark Mode</h2>
|
<h2><Icons.Moon /> Dark Mode</h2>
|
||||||
@ -63,8 +74,7 @@ class DarkMode extends React.Component{
|
|||||||
<antd.Switch
|
<antd.Switch
|
||||||
checkedChildren="Enabled"
|
checkedChildren="Enabled"
|
||||||
unCheckedChildren="Disabled"
|
unCheckedChildren="Disabled"
|
||||||
loading={this.state.processing}
|
onChange={(e) => {this.promiseState(prevState => ({ model: { ...prevState.model, active: e }})).then(() => this.handleUpdate())}}
|
||||||
onChange={(e) => {promiseState(prevState => ({ model: { ...prevState.model, active: e }})).then(() => this.handleUpdate())}}
|
|
||||||
checked={this.state.model.active}
|
checked={this.state.model.active}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -76,14 +86,55 @@ class DarkMode extends React.Component{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@connect(({ app }) => ({ app }))
|
||||||
|
class Colors extends ThemeConfigurator{
|
||||||
|
constructor(props){
|
||||||
|
super(props),
|
||||||
|
this.state = {
|
||||||
|
key: "darkmode",
|
||||||
|
model: { active: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
render(){
|
||||||
|
return <>
|
||||||
|
<div>
|
||||||
|
<h2><Icons.Moon /> Dark Mode</h2>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className={styles.background_image_controls} >
|
||||||
|
<div>
|
||||||
|
<h4><Icons.Eye />Enabled</h4>
|
||||||
|
<antd.Switch
|
||||||
|
checkedChildren="Enabled"
|
||||||
|
unCheckedChildren="Disabled"
|
||||||
|
onChange={(e) => {this.promiseState(prevState => ({ model: { ...prevState.model, active: e }})).then(() => this.handleUpdate())}}
|
||||||
|
checked={this.state.model.active}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@connect(({ app }) => ({ app }))
|
@connect(({ app }) => ({ app }))
|
||||||
class BackgroundImage extends React.Component{
|
class BackgroundImage extends ThemeConfigurator{
|
||||||
state = {
|
constructor(props){
|
||||||
customURL: '',
|
super(props),
|
||||||
fileURL: null,
|
this.state = {
|
||||||
processing: null,
|
key: "backgroundImage",
|
||||||
model: { active: false, opacity: null, src: null }
|
model: { active: false, opacity: null, src: null },
|
||||||
|
|
||||||
|
textColor: this.rgbToScheme(getComputedStyle(document.getElementById("app")).color),
|
||||||
|
overlayColor: this.rgbToScheme(getComputedStyle(document.getElementById("app")).backgroundColor),
|
||||||
|
|
||||||
|
processing: null,
|
||||||
|
customURL: '',
|
||||||
|
fileURL: null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFileUpload = info => {
|
handleFileUpload = info => {
|
||||||
@ -106,28 +157,6 @@ class BackgroundImage extends React.Component{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUpdate(payload){
|
|
||||||
if (!payload) {
|
|
||||||
payload = this.state.model
|
|
||||||
}
|
|
||||||
this.setState({ model: payload, processing: false })
|
|
||||||
this.props.dispatch({
|
|
||||||
type: 'app/updateTheme',
|
|
||||||
payload: {
|
|
||||||
key: 'backgroundImage',
|
|
||||||
value: payload
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleErase(){
|
|
||||||
this.handleUpdate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleExport(){
|
|
||||||
exportDataAsFile({data: JSON.stringify(this.state.model), type: 'text/json'})
|
|
||||||
}
|
|
||||||
|
|
||||||
proccessBackground(data){
|
proccessBackground(data){
|
||||||
getOptimalOpacityFromIMG({textColor: this.state.textColor, overlayColor: this.state.overlayColor, img: data}, (res) => {
|
getOptimalOpacityFromIMG({textColor: this.state.textColor, overlayColor: this.state.overlayColor, img: data}, (res) => {
|
||||||
this.handleUpdate({active: true, src: this.state.fileURL, opacity: res})
|
this.handleUpdate({active: true, src: this.state.fileURL, opacity: res})
|
||||||
@ -135,7 +164,7 @@ class BackgroundImage extends React.Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
schemeToRGB(values){
|
schemeToRGB(values){
|
||||||
const scheme = values || { r: '0', g: '0', b: '0' }
|
const scheme = values? values : { r: '0', g: '0', b: '0' }
|
||||||
const r = scheme.r || '0'
|
const r = scheme.r || '0'
|
||||||
const g = scheme.g || '0'
|
const g = scheme.g || '0'
|
||||||
const b = scheme.b || '0'
|
const b = scheme.b || '0'
|
||||||
@ -146,27 +175,8 @@ class BackgroundImage extends React.Component{
|
|||||||
const values = rgb.replace(/[^\d,]/g, '').split(',');
|
const values = rgb.replace(/[^\d,]/g, '').split(',');
|
||||||
return {r: values[0], g: values[1], b: values[2]}
|
return {r: values[0], g: values[1], b: values[2]}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(){
|
|
||||||
const storaged = theme.get()
|
|
||||||
|
|
||||||
if(storaged){
|
|
||||||
this.setState({ model: storaged["backgroundImage"] })
|
|
||||||
}
|
|
||||||
|
|
||||||
let textColor = this.rgbToScheme(get_style_rule_value('#root', 'color'))
|
|
||||||
let overlayColor = this.rgbToScheme(get_style_rule_value('#root', 'backgroundColor'))
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
textColor: textColor,
|
|
||||||
overlayColor: overlayColor
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const promiseState = async state => new Promise(resolve => this.setState(state, resolve));
|
|
||||||
|
|
||||||
const PreviewModel = () => {
|
const PreviewModel = () => {
|
||||||
return(
|
return(
|
||||||
<div>
|
<div>
|
||||||
@ -200,7 +210,7 @@ class BackgroundImage extends React.Component{
|
|||||||
checkedChildren="Enabled"
|
checkedChildren="Enabled"
|
||||||
unCheckedChildren="Disabled"
|
unCheckedChildren="Disabled"
|
||||||
loading={this.state.processing}
|
loading={this.state.processing}
|
||||||
onChange={(e) => {promiseState(prevState => ({ model: { ...prevState.model, active: e }})).then(() => this.handleUpdate())}}
|
onChange={(e) => {this.promiseState(prevState => ({ model: { ...prevState.model, active: e }})).then(() => this.handleUpdate())}}
|
||||||
checked={this.state.model.active}
|
checked={this.state.model.active}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -266,30 +276,17 @@ class BackgroundImage extends React.Component{
|
|||||||
@connect(({ app }) => ({ app }))
|
@connect(({ app }) => ({ app }))
|
||||||
export default class ThemeSettings extends React.Component{
|
export default class ThemeSettings extends React.Component{
|
||||||
state = {
|
state = {
|
||||||
helper_visible: false,
|
helper_fragment: null
|
||||||
helper_fragment: null,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
helper = {
|
|
||||||
open: (e) => {
|
|
||||||
this.setState({ helper_visible: true, helper_fragment: e })
|
|
||||||
},
|
|
||||||
close: () => {
|
|
||||||
this.setState({ helper_visible: false, helper_fragment: null })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const settingClick = {
|
const idToComponent = {
|
||||||
backgroundImage: () => this.helper.open(<BackgroundImage />),
|
backgroundImage: <BackgroundImage />,
|
||||||
overlay: () => this.helper.open(<BackgroundColor />) ,
|
darkmode: <DarkMode />,
|
||||||
darkmode: () => this.helper.open(<DarkMode />)
|
color: <Colors />,
|
||||||
}
|
|
||||||
|
|
||||||
const isActive = (key) => {
|
|
||||||
return key? key.active : false
|
|
||||||
}
|
}
|
||||||
|
const handleClick = (key) => key? this.setState({helper_fragment: idToComponent[key]}) : null
|
||||||
|
const isActive = (key) => { return key? key.active : false }
|
||||||
return(
|
return(
|
||||||
<div>
|
<div>
|
||||||
<h2><Icons.Layers/> Theme</h2>
|
<h2><Icons.Layers/> Theme</h2>
|
||||||
@ -298,7 +295,7 @@ export default class ThemeSettings extends React.Component{
|
|||||||
dataSource={themeSettings}
|
dataSource={themeSettings}
|
||||||
renderItem={item => (
|
renderItem={item => (
|
||||||
<div style={{ margin: '10px 0 10px 0' }} >
|
<div style={{ margin: '10px 0 10px 0' }} >
|
||||||
<antd.Card size="small" bodyStyle={{ width: '100%' }} style={{ display: "flex", flexDirection: "row", margin: 'auto', borderRadius: '12px' }} hoverable onClick={settingClick[item.id]}>
|
<antd.Card size="small" bodyStyle={{ width: '100%' }} style={{ display: "flex", flexDirection: "row", margin: 'auto', borderRadius: '12px' }} hoverable onClick={() => handleClick(item.id)}>
|
||||||
<h3>{item.icon}{item.title} <div style={{ float: "right" }}><antd.Tag color={isActive(arrayToObject(this.props.app.app_theme)[item.id])? "green" : "default"} > {isActive(arrayToObject(this.props.app.app_theme)[item.id])? "Enabled" : "Disabled"} </antd.Tag></div></h3>
|
<h3>{item.icon}{item.title} <div style={{ float: "right" }}><antd.Tag color={isActive(arrayToObject(this.props.app.app_theme)[item.id])? "green" : "default"} > {isActive(arrayToObject(this.props.app.app_theme)[item.id])? "Enabled" : "Disabled"} </antd.Tag></div></h3>
|
||||||
<p>{item.description}</p>
|
<p>{item.description}</p>
|
||||||
</antd.Card>
|
</antd.Card>
|
||||||
@ -310,8 +307,8 @@ export default class ThemeSettings extends React.Component{
|
|||||||
placement="right"
|
placement="right"
|
||||||
width="700px"
|
width="700px"
|
||||||
closable={true}
|
closable={true}
|
||||||
onClose={this.helper.close}
|
onClose={() => this.setState({ helper_fragment: null })}
|
||||||
visible={this.state.helper_visible}
|
visible={this.state.helper_fragment? true : false}
|
||||||
>
|
>
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{this.state.helper_fragment}
|
{this.state.helper_fragment}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
@import '../../../node_modules/antd/lib/style/themes/default.less';
|
@import '../../../node_modules/antd/lib/style/themes/default.less';
|
||||||
|
|
||||||
// -------- Colors -----------
|
// -------- Colors -----------
|
||||||
@primary-color: @blue-6;
|
@primary-color: #fff;
|
||||||
@info-color: @blue-6;
|
@info-color: @blue-6;
|
||||||
@success-color: @green-6;
|
@success-color: @green-6;
|
||||||
@processing-color: @blue-6;
|
@processing-color: @blue-6;
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
@import './components/Menssaging.less';
|
@import './components/Menssaging.less';
|
||||||
@import './components/PostCard.less';
|
@import './components/PostCard.less';
|
||||||
|
|
||||||
@AppTheme_global_color: rgb(51, 51, 51);
|
|
||||||
@AppTheme_global_color_accent: rgb(162, 162, 162);
|
@AppTheme_global_color_accent: rgb(162, 162, 162);
|
||||||
|
|
||||||
|
@AppTheme_global_color: rgb(51, 51, 51);
|
||||||
@AppTheme_global_background: rgb(248, 246, 248);
|
@AppTheme_global_background: rgb(248, 246, 248);
|
||||||
|
|
||||||
@AppTheme_global_color_dark: rgb(162, 162, 162);
|
@AppTheme_global_color_dark: rgb(162, 162, 162);
|
||||||
@ -71,11 +72,45 @@
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root {
|
#app {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: @AppTheme_global_color!important;
|
color: @AppTheme_global_color!important;
|
||||||
background-color: @AppTheme_global_background!important;
|
background-color: @AppTheme_global_background!important;
|
||||||
--accent_color: @AppTheme_global_color_accent;
|
background-repeat: repeat-x;
|
||||||
|
background-size: cover;
|
||||||
|
background-position-y: center;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: transparent;
|
||||||
|
margin: auto;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
|
||||||
|
transition: all @__Global_Components_transitions_dur linear;
|
||||||
|
|
||||||
|
&.dark_mode{
|
||||||
|
color: @AppTheme_global_color_dark!important;
|
||||||
|
background-color: @AppTheme_global_background_dark!important;
|
||||||
|
|
||||||
|
:global{
|
||||||
|
.ant-card{
|
||||||
|
background: @AppTheme_global_background_dark!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mobile{
|
||||||
|
>.primary_layout_container {
|
||||||
|
padding: 0;
|
||||||
|
overflow-y: overlay;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-width: unset;
|
||||||
|
}
|
||||||
|
.primary_layout_content{
|
||||||
|
padding: 35px 15px 15px 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -89,8 +124,6 @@ body {
|
|||||||
|
|
||||||
font-family: @__Global_texted_font;
|
font-family: @__Global_texted_font;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: @bp-small){
|
@media (max-width: @bp-small){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user