diff --git a/.umirc.js b/.umirc.js
index da950f3a..9412f468 100644
--- a/.umirc.js
+++ b/.umirc.js
@@ -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'),
diff --git a/globals/settings.json b/globals/settings.js
similarity index 59%
rename from globals/settings.json
rename to globals/settings.js
index 1a1b85dd..5f78d590 100644
--- a/globals/settings.json
+++ b/globals/settings.js
@@ -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
}
]
\ No newline at end of file
diff --git a/mock/route.js b/mock/route.js
index bc8d31b2..8a0145f8 100644
--- a/mock/route.js
+++ b/mock/route.js
@@ -14,6 +14,12 @@ const database = [
name: 'Main',
route: '/main',
},
+ {
+ id: '2',
+ icon: 'user',
+ name: 'App Settings',
+ route: '/settings'
+ }
]
diff --git a/mock/user.js b/mock/user.js
deleted file mode 100644
index 92ef41c0..00000000
--- a/mock/user.js
+++ /dev/null
@@ -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 })
- }
- )
- },
-
-
-}
diff --git a/src/@ycore/libs/ycore_sdcp/pre.js b/src/@ycore/libs/ycore_sdcp/pre.js
index 797b7a8e..07a292ce 100644
--- a/src/@ycore/libs/ycore_sdcp/pre.js
+++ b/src/@ycore/libs/ycore_sdcp/pre.js
@@ -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
diff --git a/src/@ycore/libs/yulio_id/pre.js b/src/@ycore/libs/yulio_id/pre.js
index af852e40..e5d8f9d9 100644
--- a/src/@ycore/libs/yulio_id/pre.js
+++ b/src/@ycore/libs/yulio_id/pre.js
@@ -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 () {
diff --git a/src/@ycore/ycore_worker.js b/src/@ycore/ycore_worker.js
index ac1044c8..960f1b09 100644
--- a/src/@ycore/ycore_worker.js
+++ b/src/@ycore/ycore_worker.js
@@ -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){
diff --git a/src/components/UserProfile/index.js b/src/components/UserProfile/index.js
index eebbcfb9..bf74d818 100644
--- a/src/components/UserProfile/index.js
+++ b/src/components/UserProfile/index.js
@@ -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) => {
diff --git a/src/pages/$page/index.js b/src/pages/$page/index.js
index bfa36133..bd1b35ee 100644
--- a/src/pages/$page/index.js
+++ b/src/pages/$page/index.js
@@ -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(
)
}
if (matchSearch) {
- console.log(`Search matched! ${location.pathname}`)
+ ycore.DevOptions.ShowFunctionsLogs ? console.log(`Search matched! ${location.pathname}`) : null
return(
)
diff --git a/src/pages/$page/model/detail.js b/src/pages/$page/model/detail.js
deleted file mode 100644
index 7543c66c..00000000
--- a/src/pages/$page/model/detail.js
+++ /dev/null
@@ -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,
- }
- },
- },
-}
\ No newline at end of file
diff --git a/src/pages/main/index.js b/src/pages/main/index.js
index 087bfd41..83162799 100644
--- a/src/pages/main/index.js
+++ b/src/pages/main/index.js
@@ -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
})
)
diff --git a/src/pages/settings/components/base.js b/src/pages/settings/components/base.js
new file mode 100644
index 00000000..ab14d826
--- /dev/null
+++ b/src/pages/settings/components/base.js
@@ -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(
+ (
+
+
+ this.onChange(item)} />
+
+ )}
+ />
+ )
+ }
+ catch (err){
+ return console.log(err)
+ }
+ }
+ handleControlBar(){
+ const ListControls = [
+ (
+
+
+
+ )
+ ]
+ 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 (
+
+
+
Behaviors
+ {this.SettingRender(this.state.SettingRepo)}
+
+
+ );
+ }
+}
+
+export default Base;
diff --git a/src/pages/settings/components/notification.js b/src/pages/settings/components/notification.js
new file mode 100644
index 00000000..26bd3277
--- /dev/null
+++ b/src/pages/settings/components/notification.js
@@ -0,0 +1,49 @@
+import * as antd from 'antd';
+import React, { Component, Fragment } from 'react';
+
+class NotificationView extends Component {
+ getData = () => {
+ const Action = (
+
+ );
+ 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 (
+
+ (
+
+
+
+ )} />
+
+ );
+ }
+}
+
+export default NotificationView;
diff --git a/src/pages/settings/components/security.js b/src/pages/settings/components/security.js
new file mode 100644
index 00000000..e1937669
--- /dev/null
+++ b/src/pages/settings/components/security.js
@@ -0,0 +1,85 @@
+import React, { Component, Fragment } from 'react';
+import { List } from 'antd';
+
+const passwordStrength = {
+ strong: (
+
+ Strong
+
+ ),
+ medium: (
+
+ Medium
+
+ ),
+ weak: (
+
+ Weak
+
+ ),
+};
+
+class SecurityView extends Component {
+ getData = () => [
+ {
+ title: Password
,
+ description: (
+
+ Something
+ {passwordStrength.strong}
+
+ ),
+ actions: [
+
+ Modify
+ ,
+ ],
+ },
+ {
+ title: Security question
,
+ description: 'Security cuesting seting',
+ actions: [
+
+ Set
+ ,
+ ],
+ },
+ {
+ title: 'Mail',
+ description: 'YourEmail@jeje.com',
+ actions: [
+
+ Modify
+ ,
+ ],
+ },
+ {
+ title: 'mfa',
+ description: 'mfa settings',
+ actions: [
+
+ Bind
+ ,
+ ],
+ },
+ ];
+
+ render() {
+ const data = this.getData();
+ return (
+
+ (
+
+
+
+ )}
+ />
+
+ );
+ }
+}
+
+export default SecurityView;
diff --git a/src/pages/settings/index.js b/src/pages/settings/index.js
new file mode 100644
index 00000000..9854e57c
--- /dev/null
+++ b/src/pages/settings/index.js
@@ -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 => - {menuMap[item]}
);
+ };
+
+ selectKey = (key) => {
+ this.setState({
+ selectKey: key,
+ });
+ };
+
+ renderChildren = () => {
+ const { selectKey } = this.state;
+ switch (selectKey) {
+ case 'base':
+ return ;
+ case 'security':
+ return ;
+ case 'notification':
+ return ;
+ default:
+ break;
+ }
+
+ return null;
+ };
+
+ render() {
+ const { mode, selectKey } = this.state;
+ return (
+
+
Settings
+
+ {
+ if (ref) {
+ this.main = ref;
+ }
+ }}
+ >
+
+
+
+
+ {this.renderChildren()}
+
+
+
+
+ );
+ }
+}
+
+export default GeneralSettings
diff --git a/src/pages/settings/style.less b/src/pages/settings/style.less
new file mode 100644
index 00000000..e7b494f5
--- /dev/null
+++ b/src/pages/settings/style.less
@@ -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;
+ }
+ }
+}