Settings & yCore Optimization

This commit is contained in:
srgooglo 2020-02-13 21:57:00 +01:00
parent 76e5c4f801
commit e5873d8c34
16 changed files with 439 additions and 99 deletions

View File

@ -64,7 +64,6 @@ export default {
// Webpack Configuration
alias: {
ycore: resolve(__dirname, './src/@ycore/ycore_worker.js'),
ycstyle: resolve(__dirname, './src/@ycore/ycore_style.scss'),
api: resolve(__dirname, './src/services/'),
components: resolve(__dirname, './src/components'),
config: resolve(__dirname, './config/ycore.config.js'),

View File

@ -1,26 +1,34 @@
[
const fromStorage = JSON.parse(localStorage.getItem('app_settings'))
function StorageValued(e){
const Ite = fromStorage.map(item => {
return item.SettingID === e? item.value : null
})
const fr = Ite.filter(Boolean)
return fr.toString()
}
export default [
{
"SettingID": "strict_lightMode",
"title": "Strict Light Mode",
"description": "Force the app to apply full light mode theme when the light mode is activated... (Experimental)",
"value": false
"value": StorageValued('strict_lightMode') || false
},
{
"SettingID": "force_collapse",
"title": "Collapsed Default",
"description": "Force the app to apply collapse mode when an component has updated",
"value": false
"value": StorageValued('force_collapse') || false
},
{
"SettingID": "force_showDevLogs",
"title": "Show Functions Logs",
"description": "Show all console logs... [Developer]",
"value": true
"value": StorageValued('force_showDevLogs') || true
},
{
"SettingID": "sessions_noexpire",
"title": "No expire session",
"description": "Force the app to not expire any session... [Developer]",
"value": true
"value": StorageValued('sessions_noexpire') || true
}
]

View File

@ -14,6 +14,12 @@ const database = [
name: 'Main',
route: '/main',
},
{
id: '2',
icon: 'user',
name: 'App Settings',
route: '/settings'
}
]

View File

@ -1,27 +0,0 @@
import { Mock, Constant, qs, randomAvatar } from './_utils'
import jwt from 'jsonwebtoken';
import keys from '../config/keys.js';
const { ApiPrefix } = Constant
module.exports = {
[`POST ${ApiPrefix}/user/login`](req, res) {
var ExpireTime = '1556952'
const now = new Date()
now.setDate(now.getDate() + 1)
const { UserID, UserToken } = req.body
const frame = { UserID, UserToken, deadline: now.getTime()}
jwt.sign(
frame,
keys.secretOrKey,
{ expiresIn: ExpireTime },
(err, token) => {
res.cookie('token', token, { maxAge: ExpireTime, httpOnly: false }),
res.json({ success: true, token: token })
}
)
},
}

View File

@ -43,11 +43,11 @@ export function UpdateSDCP() {
const e2 = btoa(Nsdcp)
const n = e1.localeCompare(e2)
if (!e2) {
console.log(prefix, 'API Returned empty response! We recommend to logout')
ycore.DevOptions.ShowFunctionsLogs? console.log(prefix, 'API Returned empty response! We recommend to logout') : null
return
}
if (e1 == e2) {
console.log(prefix, 'SDCP Equality')
ycore.DevOptions.ShowFunctionsLogs? console.log(prefix, 'SDCP Equality') : null
}else{
ycore.DevOptions.ShowFunctionsLogs? console.log(prefix, 'SDCP Update detected ! => ', n) : null
ycore.DevOptions.ShowFunctionsLogs? console.debug(`Compare versions => NEW ${[e1]} || OLD ${[e2]} `) : null

View File

@ -169,7 +169,7 @@ export const GetUserToken = {
if (!FB) {
final = FC
}
console.log(final)
ycore.DevOptions.ShowFunctionsLogs ? console.debug(final) : null
return final
},
raw: function () {

View File

@ -4,12 +4,14 @@ import * as antd from "antd"
import './libs.js'
export * from "./libs.js"
import * as AppSettings from '../../globals/settings.js'
export var DevOptions = AppSettings;
var package_json = require("../../package.json");
var config = require("config");
export var { router } = require("utils")
export var endpoints = config.Endpoints;
export var DevOptions = config.DevOptions;
export var yConfig = config.yConfig;
export function booleanFix(e){

View File

@ -9,7 +9,7 @@ const userData = ycore.SDCP();
function isOwnProfile(id){
if(id == userData.username){
console.log('Is your own profile !!')
ycore.DevOptions.ShowFunctionsLogs ? console.log('Is your own profile !!'): null
return true
}
return false
@ -93,7 +93,7 @@ class UserProfile extends React.Component {
const c1 = rp['0'].username.toLowerCase()
const c2 = string.toLowerCase()
if (c1 !== c2) {
console.log(`Using aproximate user! => ${c1} / ${c2}`)
ycore.DevOptions.ShowFunctionsLogs ? console.log(`Using aproximate user! => ${c1} / ${c2}`) : null
ycore.crouter.native(`@${c1}`)
}
ycore.GetUserPosts(rp['0'].user_id, (exception, response) => {

View File

@ -4,28 +4,21 @@ import { pathMatchRegexp } from 'utils'
import Error404 from '../404.js'
import * as ycore from 'ycore'
const userData = ycore.SDCP()
class PageIndexer extends PureComponent {
componentDidMount(){
}
render() {
const {location} = this.props
const matchUser = pathMatchRegexp("/@:id", location.pathname);
const matchSearch = pathMatchRegexp("/s/:id", location.pathname);
if (matchUser) {
console.log(`User matched! ${location.pathname}`)
ycore.DevOptions.ShowFunctionsLogs ? console.log(`User matched! ${location.pathname}`) : null
return(<div>
<UserProfile regx={matchUser} />
</div>)
}
if (matchSearch) {
console.log(`Search matched! ${location.pathname}`)
ycore.DevOptions.ShowFunctionsLogs ? console.log(`Search matched! ${location.pathname}`) : null
return(<div>
<UserProfile regx={matchSearch} />
</div>)

View File

@ -1,50 +0,0 @@
import { pathMatchRegexp } from 'utils'
import api from 'api'
const { queryUser } = api
export default {
namespace: 'userDetail',
state: {
data: {},
},
subscriptions: {
setup({ dispatch, history }) {
history.listen(({ pathname }) => {
const match = pathMatchRegexp('/:user', pathname)
if (match) {
dispatch({ type: 'query', payload: { id: match[1] } })
}
})
},
},
effects: {
*query({ payload }, { call, put }) {
const data = yield call(queryUser, payload)
const { success, message, status, ...other } = data
if (success) {
yield put({
type: 'querySuccess',
payload: {
data: other,
},
})
} else {
throw data
}
},
},
reducers: {
querySuccess(state, { payload }) {
const { data } = payload
return {
...state,
data,
}
},
},
}

View File

@ -32,7 +32,6 @@ class Main extends React.Component {
feedParsed.map(item=> {
const {id, postText, post_time, publisher, postFile, postFileName} = item
const paylodd = {user: publisher.username, ago: post_time, avatar: publisher.avatar, content: postText, file: postFile, postFileName: postFileName, publisher: publisher }
ycore.DevOptions.ShowFunctionsLogs? console.log([item], paylodd) : null
return <PostCard payload={paylodd} key={id} />
})
)

View File

@ -0,0 +1,92 @@
import React, { Component, Fragment } from 'react';
import { List, Icon, Switch, Button, notification } from 'antd';
import Settings from '../../../../globals/settings.js'
import { DevOptions, ControlBar } from 'ycore'
import update from 'immutability-helper'
class Base extends Component {
constructor(props){
super(props),
this.state = {
SettingRepo: Settings,
backupSettings: JSON.parse(localStorage.getItem('app_settings')) || Settings,
forSave: false
}
}
componentDidMount(){
if (!localStorage.getItem('app_settings')) {
DevOptions.ShowFunctionsLogs? console.warn('The settings for this app in your Account isnt set yet, Using stock settings...') : null
}
}
SettingRender = data =>{
try{
const {SettingRepo} = this.state
return(
<List
itemLayout="horizontal"
dataSource={data}
renderItem={item => (
<List.Item actions={item.actions} >
<List.Item.Meta title={item.title} description={item.description} />
<Switch checkedChildren={'Enabled'} unCheckedChildren={'Disabled'} checked={item.value} onChange={() => this.onChange(item)} />
</List.Item>
)}
/>
)
}
catch (err){
return console.log(err)
}
}
handleControlBar(){
const ListControls = [
(<div>
<Button type="done" icon='save' onClick={() => this.saveChanges()} >Save</Button>
<Button type="dashed" icon="close" shape="circle" onClick={() => this.handleCancel()}></Button>
</div>
)
]
ControlBar.set(ListControls)
}
handleCancel(){
const back = this.state.backupSettings;
this.setState({ SettingRepo: back, forSave: false})
DevOptions.ShowFunctionsLogs? console.log(`Restored ${JSON.stringify(back)}`) : null
ControlBar.close()
}
saveChanges(){
localStorage.setItem('app_settings', JSON.stringify(this.state.SettingRepo))
this.setState({ forSave: false })
notification.success({
message: 'Settings saved',
description:'The configuration has been saved, it may for some configuration to make changes you need to reload the application',
})
ControlBar.close()
}
onChange(item) {
try {
this.handleControlBar()
const to = !item.value
const updatedValue = [...this.state.SettingRepo]
.map(ita => ita === item? Object.assign(ita, { "value": to }) : ita);
this.setState({SettingRepo: updatedValue, forSave: true})
DevOptions.ShowFunctionsLogs? console.log(`Changing ${item.SettingID} to value ${to}`) : null
} catch (err) {
console.log(err)
}
}
render() {
return (
<Fragment>
<div>
<h1><Icon type="global" /> Behaviors</h1>
{this.SettingRender(this.state.SettingRepo)}
</div>
</Fragment>
);
}
}
export default Base;

View File

@ -0,0 +1,49 @@
import * as antd from 'antd';
import React, { Component, Fragment } from 'react';
class NotificationView extends Component {
getData = () => {
const Action = (
<antd.Switch
checkedChildren={'open'}
unCheckedChildren={'close'}
defaultChecked
/>
);
return [
{
title: 'Title 1',
description: 'Description 1',
actions: [Action],
},
{
title: 'Title 2',
description: 'Description 2',
actions: [Action],
},
{
title: 'Title 3',
description: 'Description 3',
actions: [Action],
},
];
};
render() {
const data = this.getData();
return (
<Fragment>
<antd.List
itemLayout="horizontal"
dataSource={data}
renderItem={item => (
<antd.List.Item actions={item.actions}>
<antd.List.Item.Meta title={item.title} description={item.description} />
</antd.List.Item>
)} />
</Fragment>
);
}
}
export default NotificationView;

View File

@ -0,0 +1,85 @@
import React, { Component, Fragment } from 'react';
import { List } from 'antd';
const passwordStrength = {
strong: (
<span className="strong">
Strong
</span>
),
medium: (
<span className="medium">
Medium
</span>
),
weak: (
<span className="weak">
Weak
</span>
),
};
class SecurityView extends Component {
getData = () => [
{
title: <h1>Password</h1>,
description: (
<Fragment>
<p>Something</p>
{passwordStrength.strong}
</Fragment>
),
actions: [
<a key="Modify">
Modify
</a>,
],
},
{
title: <h1>Security question</h1>,
description: 'Security cuesting seting',
actions: [
<a key="Set">
Set
</a>,
],
},
{
title: 'Mail',
description: 'YourEmail@jeje.com',
actions: [
<a key="Modify">
Modify
</a>,
],
},
{
title: 'mfa',
description: 'mfa settings',
actions: [
<a key="bind">
Bind
</a>,
],
},
];
render() {
const data = this.getData();
return (
<Fragment>
<List
itemLayout="horizontal"
dataSource={data}
renderItem={item => (
<List.Item actions={item.actions}>
<List.Item.Meta title={item.title} description={item.description} />
</List.Item>
)}
/>
</Fragment>
);
}
}
export default SecurityView;

View File

@ -0,0 +1,86 @@
import React from 'react';
import { GridContent } from '@ant-design/pro-layout';
import { Menu, Typography, Icon } from 'antd';
import styles from './style.less';
import NotificationView from './components/notification.js';
import SecurityView from './components/security.js';
import Base from './components/base.js'
const { Item } = Menu;
const menuMap = {
base: 'App',
security: 'Security',
notification: 'Notification',
};
const { Title } = Typography;
class GeneralSettings extends React.Component {
constructor(props) {
super(props);
this.state = {
mode: 'inline',
selectKey: 'base',
};
}
getMenu = () => {
return Object.keys(menuMap).map(item => <Item key={item}>{menuMap[item]}</Item>);
};
selectKey = (key) => {
this.setState({
selectKey: key,
});
};
renderChildren = () => {
const { selectKey } = this.state;
switch (selectKey) {
case 'base':
return <Base />;
case 'security':
return <SecurityView />;
case 'notification':
return <NotificationView />;
default:
break;
}
return null;
};
render() {
const { mode, selectKey } = this.state;
return (
<div>
<Title className={styles.titleHead}><Icon type="setting" /> Settings</Title>
<GridContent>
<div
className={styles.main}
ref={ref => {
if (ref) {
this.main = ref;
}
}}
>
<div className={styles.leftMenu}>
<Menu
mode={mode}
selectedKeys={[selectKey]}
onClick={({ key }) => this.selectKey(key)}
>
{this.getMenu()}
</Menu>
</div>
<div className={styles.right}>
{this.renderChildren()}
</div>
</div>
</GridContent>
</div>
);
}
}
export default GeneralSettings

View File

@ -0,0 +1,98 @@
@import '~themes/vars.less';
.titleHead{
font-family: "Nunito", sans-serif;
}
.main {
display: flex;
width: 100%;
height: 100%;
overflow: auto;
background-color: @menu-bg;
.leftMenu {
width: 224px;
border-right: @border-width-base @border-style-base @border-color-split;
:global {
.ant-menu-inline {
border: none;
}
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
font-weight: bold;
}
}
}
.right {
flex: 1;
padding-top: 8px;
padding-right: 40px;
padding-bottom: 8px;
padding-left: 40px;
.title {
margin-bottom: 12px;
color: @heading-color;
font-weight: 500;
font-size: 20px;
line-height: 28px;
}
}
:global {
.ant-list-split .ant-list-item:last-child {
border-bottom: 1px solid @border-color-split;
}
.ant-list-item {
padding-top: 14px;
padding-bottom: 14px;
}
}
}
:global {
.ant-list-item-meta {
// 账号绑定图标
.taobao {
display: block;
color: #ff4000;
font-size: 48px;
line-height: 48px;
border-radius: @border-radius-base;
}
.dingding {
margin: 2px;
padding: 6px;
color: #fff;
font-size: 32px;
line-height: 32px;
background-color: #2eabff;
border-radius: @border-radius-base;
}
.alipay {
color: #2eabff;
font-size: 48px;
line-height: 48px;
border-radius: @border-radius-base;
}
}
// 密码强度
font.strong {
color: @success-color;
}
font.medium {
color: @warning-color;
}
font.weak {
color: @error-color;
}
}
@media screen and (max-width: @screen-md) {
.main {
flex-direction: column;
.leftMenu {
width: 100%;
border: none;
}
.right {
padding: 40px;
}
}
}