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
|
||||
/dist
|
||||
/out
|
||||
/api
|
||||
|
||||
# umi
|
||||
/src/.umi
|
||||
|
@ -13,6 +13,7 @@ export default defineConfig({
|
||||
loading: 'components/Loader/Loader.js',
|
||||
},
|
||||
dva: { immer: true },
|
||||
antd: {},
|
||||
nodeModulesTransform: {
|
||||
type: 'none',
|
||||
},
|
||||
|
@ -3,7 +3,7 @@
|
||||
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
|
||||
"title": "Comty™",
|
||||
"DevBuild": true,
|
||||
"version": "0.4.04",
|
||||
"version": "0.8.08",
|
||||
"stage": "dev-pre",
|
||||
"description": "",
|
||||
"author": "RageStudio",
|
||||
|
@ -25,7 +25,6 @@ export let Swapper = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@connect(({ app }) => ({ app }))
|
||||
export default class Overlay extends React.PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -22,7 +22,7 @@
|
||||
float: right;
|
||||
.ant-menu {
|
||||
font-weight: 700;
|
||||
color: @AppTheme_global_color;
|
||||
color: unset;
|
||||
vertical-align: middle;
|
||||
// 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 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_PROPS = `Some props failed!`
|
||||
// HANDLERS
|
||||
export const onError = {
|
||||
internal_proccess: (...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
|
||||
},
|
||||
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
|
||||
@connect(({ loading }) => ({ loading }))
|
||||
@connect(({ app, loading }) => ({ app, loading }))
|
||||
class BaseLayout extends PureComponent {
|
||||
previousPath = ''
|
||||
|
||||
@ -33,14 +33,13 @@ class BaseLayout extends PureComponent {
|
||||
NProgress.done()
|
||||
this.previousPath = currentPath
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Helmet>
|
||||
<title>{config.app_config.siteName}</title>
|
||||
</Helmet>
|
||||
{Loader(loading)}
|
||||
<Container>{children}</Container>
|
||||
{Loader(loading)}
|
||||
<Container>{children}</Container>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
@ -19,10 +19,11 @@ import styles from './PrimaryLayout.less'
|
||||
|
||||
const { Content } = antd.Layout
|
||||
const { Sider, Control, Overlay } = MyLayout
|
||||
const isActive = (key) => { return key? key.active : false }
|
||||
|
||||
@withRouter
|
||||
@connect(({ app, loading }) => ({ app, loading }))
|
||||
class PrimaryLayout extends React.PureComponent {
|
||||
class PrimaryLayout extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -30,7 +31,6 @@ class PrimaryLayout extends React.PureComponent {
|
||||
isMobile: false,
|
||||
},
|
||||
window.PrimaryComponent = this;
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -54,49 +54,53 @@ class PrimaryLayout extends React.PureComponent {
|
||||
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() {
|
||||
const { location, dispatch, children } = this.props
|
||||
const { collapsed, isMobile } = this.state
|
||||
const { onCollapseChange } = this
|
||||
const currentTheme = theme.get()
|
||||
const breakpoint = {
|
||||
xs: '480px',
|
||||
sm: '576px',
|
||||
md: '768px',
|
||||
lg: '992px',
|
||||
xl: '1200px',
|
||||
xxl: '1600px',
|
||||
}
|
||||
|
||||
const SiderProps = {
|
||||
breakpoint:{
|
||||
xs: '480px',
|
||||
sm: '576px',
|
||||
md: '768px',
|
||||
lg: '992px',
|
||||
xl: '1200px',
|
||||
xxl: '1600px',
|
||||
},
|
||||
breakpoint,
|
||||
isMobile,
|
||||
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 (
|
||||
<React.Fragment>
|
||||
<Control />
|
||||
{this.renderThemeComponents()}
|
||||
<antd.Layout id="primaryLayout" className={classnames(styles.primary_layout, {[styles.mobile]: isMobile})}>
|
||||
{isActive(currentTheme['backgroundImage'])? <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}
|
||||
<antd.Layout id="app" className={isActive(currentTheme['darkmode'])? "dark_mode" : null }>
|
||||
<Sider {...SiderProps} />
|
||||
<div className={styles.primary_layout_container}>
|
||||
<PageTransition
|
||||
@ -111,7 +115,7 @@ class PrimaryLayout extends React.PureComponent {
|
||||
</Content>
|
||||
</PageTransition>
|
||||
</div>
|
||||
<Overlay />
|
||||
<Overlay {...OverlayProps} />
|
||||
</antd.Layout>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
@ -1,31 +1,5 @@
|
||||
@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_container {
|
||||
background-color: transparent;
|
||||
|
@ -31,7 +31,6 @@ export default {
|
||||
app_theme: store.get(app_config.appTheme_container) || [],
|
||||
notifications: [],
|
||||
locationQuery: {},
|
||||
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch }) {
|
||||
@ -116,24 +115,28 @@ export default {
|
||||
});
|
||||
},
|
||||
*updateTheme({payload}, {put, select}){
|
||||
if (!payload) return false;
|
||||
let container = yield select(state => state.app.app_theme);
|
||||
let container_2 = []
|
||||
if (!payload) return false
|
||||
let container = yield select(state => state.app.app_theme)
|
||||
let style_keys = []
|
||||
let tmp = []
|
||||
|
||||
const containerlength = Object.entries(container).length
|
||||
container.forEach((e)=>{style_keys[e.key] = e.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]
|
||||
if(!style_keys[payload.key]){
|
||||
tmp.push({key: payload.key, value: payload.value})
|
||||
}
|
||||
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: {
|
||||
|
@ -4,6 +4,9 @@ import * as antd from 'antd'
|
||||
|
||||
@connect(({ app }) => ({ app }))
|
||||
class PageIndex extends React.PureComponent {
|
||||
constructor(props){
|
||||
super(props)
|
||||
}
|
||||
state = {
|
||||
app_state: null
|
||||
}
|
||||
@ -39,9 +42,10 @@ class PageIndex extends React.PureComponent {
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<antd.Card title="APP STATE">
|
||||
<antd.Card theme={window.DarkMode? "dark" : null} title="APP STATE">
|
||||
{AppState()}
|
||||
</antd.Card>
|
||||
|
||||
|
@ -5,39 +5,30 @@ import themeSettings from 'globals/theme_settings'
|
||||
import {connect} from 'umi'
|
||||
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 { urlToBase64, imageToBase64, arrayToObject } from 'core'
|
||||
import exportDataAsFile from 'core/libs/interface/export_data'
|
||||
|
||||
class BackgroundColor extends React.Component{
|
||||
state = {
|
||||
selected: "#fff"
|
||||
}
|
||||
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>
|
||||
</>
|
||||
}
|
||||
}
|
||||
class ThemeConfigurator extends React.Component{
|
||||
|
||||
@connect(({ app }) => ({ app }))
|
||||
class DarkMode extends React.Component{
|
||||
state = {
|
||||
model: { active: false, autoTime: '' }
|
||||
componentDidMount(){
|
||||
this.applyStoraged()
|
||||
}
|
||||
|
||||
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){
|
||||
if(!this.state.key || !this.props.dispatch) {
|
||||
return onError.internal_proccess(`"Config key" or "Dispatcher" is missing`)
|
||||
}
|
||||
if (!payload) {
|
||||
payload = this.state.model
|
||||
}
|
||||
@ -45,13 +36,33 @@ class DarkMode extends React.Component{
|
||||
this.props.dispatch({
|
||||
type: 'app/updateTheme',
|
||||
payload: {
|
||||
key: 'darkmode',
|
||||
key: this.state.key,
|
||||
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(){
|
||||
const promiseState = async state => new Promise(resolve => this.setState(state, resolve));
|
||||
return <>
|
||||
<div>
|
||||
<h2><Icons.Moon /> Dark Mode</h2>
|
||||
@ -63,8 +74,7 @@ class DarkMode extends React.Component{
|
||||
<antd.Switch
|
||||
checkedChildren="Enabled"
|
||||
unCheckedChildren="Disabled"
|
||||
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}
|
||||
/>
|
||||
</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 }))
|
||||
class BackgroundImage extends React.Component{
|
||||
state = {
|
||||
customURL: '',
|
||||
fileURL: null,
|
||||
processing: null,
|
||||
model: { active: false, opacity: null, src: null }
|
||||
class BackgroundImage extends ThemeConfigurator{
|
||||
constructor(props){
|
||||
super(props),
|
||||
this.state = {
|
||||
key: "backgroundImage",
|
||||
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 => {
|
||||
@ -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){
|
||||
getOptimalOpacityFromIMG({textColor: this.state.textColor, overlayColor: this.state.overlayColor, img: data}, (res) => {
|
||||
this.handleUpdate({active: true, src: this.state.fileURL, opacity: res})
|
||||
@ -135,7 +164,7 @@ class BackgroundImage extends React.Component{
|
||||
}
|
||||
|
||||
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 g = scheme.g || '0'
|
||||
const b = scheme.b || '0'
|
||||
@ -147,26 +176,7 @@ class BackgroundImage extends React.Component{
|
||||
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(){
|
||||
const promiseState = async state => new Promise(resolve => this.setState(state, resolve));
|
||||
|
||||
const PreviewModel = () => {
|
||||
return(
|
||||
<div>
|
||||
@ -200,7 +210,7 @@ class BackgroundImage extends React.Component{
|
||||
checkedChildren="Enabled"
|
||||
unCheckedChildren="Disabled"
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
@ -266,30 +276,17 @@ class BackgroundImage extends React.Component{
|
||||
@connect(({ app }) => ({ app }))
|
||||
export default class ThemeSettings extends React.Component{
|
||||
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(){
|
||||
const settingClick = {
|
||||
backgroundImage: () => this.helper.open(<BackgroundImage />),
|
||||
overlay: () => this.helper.open(<BackgroundColor />) ,
|
||||
darkmode: () => this.helper.open(<DarkMode />)
|
||||
}
|
||||
|
||||
const isActive = (key) => {
|
||||
return key? key.active : false
|
||||
const idToComponent = {
|
||||
backgroundImage: <BackgroundImage />,
|
||||
darkmode: <DarkMode />,
|
||||
color: <Colors />,
|
||||
}
|
||||
const handleClick = (key) => key? this.setState({helper_fragment: idToComponent[key]}) : null
|
||||
const isActive = (key) => { return key? key.active : false }
|
||||
return(
|
||||
<div>
|
||||
<h2><Icons.Layers/> Theme</h2>
|
||||
@ -298,7 +295,7 @@ export default class ThemeSettings extends React.Component{
|
||||
dataSource={themeSettings}
|
||||
renderItem={item => (
|
||||
<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>
|
||||
<p>{item.description}</p>
|
||||
</antd.Card>
|
||||
@ -310,8 +307,8 @@ export default class ThemeSettings extends React.Component{
|
||||
placement="right"
|
||||
width="700px"
|
||||
closable={true}
|
||||
onClose={this.helper.close}
|
||||
visible={this.state.helper_visible}
|
||||
onClose={() => this.setState({ helper_fragment: null })}
|
||||
visible={this.state.helper_fragment? true : false}
|
||||
>
|
||||
<React.Fragment>
|
||||
{this.state.helper_fragment}
|
||||
|
@ -2,7 +2,7 @@
|
||||
@import '../../../node_modules/antd/lib/style/themes/default.less';
|
||||
|
||||
// -------- Colors -----------
|
||||
@primary-color: @blue-6;
|
||||
@primary-color: #fff;
|
||||
@info-color: @blue-6;
|
||||
@success-color: @green-6;
|
||||
@processing-color: @blue-6;
|
||||
|
@ -11,8 +11,9 @@
|
||||
@import './components/Menssaging.less';
|
||||
@import './components/PostCard.less';
|
||||
|
||||
@AppTheme_global_color: rgb(51, 51, 51);
|
||||
@AppTheme_global_color_accent: rgb(162, 162, 162);
|
||||
|
||||
@AppTheme_global_color: rgb(51, 51, 51);
|
||||
@AppTheme_global_background: rgb(248, 246, 248);
|
||||
|
||||
@AppTheme_global_color_dark: rgb(162, 162, 162);
|
||||
@ -71,11 +72,45 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#root {
|
||||
#app {
|
||||
overflow: hidden;
|
||||
color: @AppTheme_global_color!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 {
|
||||
@ -89,8 +124,6 @@ body {
|
||||
|
||||
font-family: @__Global_texted_font;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: @bp-small){
|
||||
|
Loading…
x
Reference in New Issue
Block a user