Added Settings Webui (view only), rewrite of API, Fixes #14, Fixes #2, now Testing

This commit is contained in:
2018-02-20 21:51:49 -05:00
parent d4966f597b
commit 840a965877
19 changed files with 689 additions and 209 deletions

View File

@@ -0,0 +1,65 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { withStyles } from 'material-ui/styles';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import {connect} from 'react-redux';
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: 0,
},
paper: {
padding: 16,
textAlign: 'left',
color: theme.palette.text.primary,
},
floatRight: {
float: 'right',
}
});
class ClientSettingsTab extends React.PureComponent {
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<Grid container spacing={8}>
<Grid item xs={12} sm={4}>
<Paper className={classes.paper}>HTTP Address: <span className={classes.floatRight}>{this.props.settingsFile["HTTPAddrIP"]} </span></Paper>
<Paper className={classes.paper}>HTTP Port: <span className={classes.floatRight}>{this.props.settingsFile["HTTPAddr"]} </span> </Paper>
<Paper className={classes.paper}>Use Proxy: <span className={classes.floatRight}>{String(this.props.settingsFile["UseProxy"])} </span> </Paper>
<Paper className={classes.paper}>Base URL: <span className={classes.floatRight}>{this.props.settingsFile["BaseURL"]} </span> </Paper>
</Grid>
<Grid item xs={12} sm={4}>
<Paper className={classes.paper}>Client Username: <span className={classes.floatRight}>{this.props.settingsFile["ClientUsername"]} </span> </Paper>
<Paper className={classes.paper}>Client Password: <span className={classes.floatRight}>{this.props.settingsFile["ClientPassword"]} </span> </Paper>
</Grid>
<Grid item xs={12} sm={4}>
</Grid>
</Grid>
</div>
);
}
}
const mapStateToProps = state => {
return {
settingsFile: state.settingsFile,
};
}
export default withStyles(styles)(connect(mapStateToProps)(ClientSettingsTab))

View File

@@ -0,0 +1,83 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { withStyles } from 'material-ui/styles';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import {connect} from 'react-redux';
let logLevel = "None"
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: 0,
},
paper: {
padding: 16,
textAlign: 'left',
color: theme.palette.text.primary,
},
floatRight: {
float: 'right',
}
});
class LoggingSettingsTab extends React.Component {
componentWillMount = () => {
switch (String(this.props.settingsFile["LoggingLevel"])) { //Options = Debug 5, Info 4, Warn 3, Error 2, Fatal 1, Panic 0
case "0":
logLevel = "Panic"
case "1":
logLevel = "Fatal"
case "2":
logLevel = "Error"
case "3":
logLevel = "Warn"
case "4":
logLevel = "Info"
case "5":
logLevel = "Debug"
}
}
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<Grid container spacing={8}>
<Grid item xs={12} sm={4}>
<Paper className={classes.paper}>Logging Output: <span className={classes.floatRight}>{this.props.settingsFile["LoggingOutput"]} </span></Paper>
<Paper className={classes.paper}>Logging Level: <span className={classes.floatRight}>{logLevel} </span> </Paper>
</Grid>
<Grid item xs={12} sm={4}>
</Grid>
<Grid item xs={12} sm={4}>
</Grid>
</Grid>
</div>
);
}
}
const mapStateToProps = state => {
return {
settingsFile: state.settingsFile,
};
}
export default withStyles(styles)(connect(mapStateToProps)(LoggingSettingsTab))

View File

@@ -0,0 +1,36 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { withStyles } from 'material-ui/styles';
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: 0,
},
paper: {
padding: 16,
textAlign: 'left',
color: theme.palette.text.primary,
},
floatRight: {
float: 'right',
}
});
class NotesTab extends React.PureComponent {
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
Here will be notes/news/links, etc, maybe pull from github?
</div>
);
}
}
export default withStyles(styles)(NotesTab)

View File

@@ -0,0 +1,64 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { withStyles } from 'material-ui/styles';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import {connect} from 'react-redux';
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: 0,
},
paper: {
padding: 16,
textAlign: 'left',
color: theme.palette.text.primary,
},
floatRight: {
float: 'right',
}
});
class ServerSettingsTab extends React.PureComponent {
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<Grid container spacing={8}>
<Grid item xs={12} sm={4}>
<Paper className={classes.paper}>Scan Folder for Torrent Files: <span className={classes.floatRight}>{this.props.settingsFile["TorrentWatchFolder"]} </span></Paper>
<Paper className={classes.paper}>Folder that stores Uploaded Torrents: <span className={classes.floatRight}>{this.props.settingsFile["TFileUploadFolder"]} </span> </Paper>
<Paper className={classes.paper}>Default Move Folder: <span className={classes.floatRight}>{String(this.props.settingsFile["DefaultMoveFolder"])} </span> </Paper>
</Grid>
<Grid item xs={12} sm={4}>
<Paper className={classes.paper}>Automatic stop seeding Ratio: <span className={classes.floatRight}>{this.props.settingsFile["SeedRatioStop"]} </span> </Paper>
</Grid>
<Grid item xs={12} sm={4}>
</Grid>
</Grid>
</div>
);
}
}
const mapStateToProps = state => {
return {
settingsFile: state.settingsFile,
};
}
export default withStyles(styles)(connect(mapStateToProps)(ServerSettingsTab))

View File

@@ -0,0 +1,87 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Button from 'material-ui/Button';
import TextField from 'material-ui/TextField';
import { withStyles } from 'material-ui/styles';
import PropTypes from 'prop-types';
import List, {
ListItem,
ListItemIcon,
ListItemSecondaryAction,
ListItemText,
} from 'material-ui/List';
import Dialog, {
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from 'material-ui/Dialog';
import ReactTooltip from 'react-tooltip'
import Icon from 'material-ui/Icon';
import IconButton from 'material-ui/IconButton';
import SettingsIcon from 'material-ui-icons/Settings';
import SettingsModalLayout from './settingsModalLayout'
//Redux
import {connect} from 'react-redux';
import * as actionTypes from '../../../store/actions';
const button = {
fontSize: '60px',
marginLeft: '20px',
marginRight: '20px',
}
const inlineStyle = {
display: 'inline-block',
backdrop: 'static',
}
class AddSettingsModal extends React.Component {
settingsModalOpenState = () => {
let settingsFileRequest = {
MessageType: "settingsFileRequest",
}
ws.send(JSON.stringify(settingsFileRequest))
console.log("Opening Settings Modal")
this.props.settingsModalOpenState(true)
}
render() {
const { classes, onRequestClose, handleRequestClose, handleSubmit } = this.props;
return (
<div style={inlineStyle}>
<IconButton onClick={this.settingsModalOpenState} color="primary" data-tip="Settings Modal" style={button} aria-label="Settings Modal">
<ReactTooltip place="top" type="light" effect="float" />
<SettingsIcon />
</IconButton>
<Dialog fullScreen open={this.props.settingsModalOpen} onRequestClose={this.handleRequestClose}>
<DialogTitle>Manage Settings</DialogTitle>
<SettingsModalLayout />
</Dialog>
</div>
);
}
};
const mapStateToProps = state => {
return {
settingsModalOpen: state.settingsModalOpen,
}
}
const mapDispatchToProps = dispatch => {
return {
settingsModalOpenState: (settingsModalOpen) => dispatch({type: actionTypes.SETTINGS_MODAL_OPEN_STATE, settingsModalOpen}),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AddSettingsModal)

View File

@@ -0,0 +1,56 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Button from 'material-ui/Button';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import {connect} from 'react-redux';
import ClientSettingsTab from './SettingsModalContentTabs/clientSettingsTab';
import LoggingSettingsTab from './SettingsModalContentTabs/loggingSettingsTab';
import NotesTab from './SettingsModalContentTabs/notesTab';
import ServerSettingsTab from './SettingsModalContentTabs/serverSettingsTab';
class SettingsModalContent extends React.Component {
handleChange = (event, value) => {
console.log("HandleChange", event, value)
};
componentDidMount = () => {
console.log("settingsFile", this.props.settingsFile)
}
render() {
switch(this.props.selectedMenuItem){
case 0:
return <NotesTab />
case 1:
return <ClientSettingsTab />
case 2:
return <LoggingSettingsTab />
case 3:
return <ServerSettingsTab />
default:
return <NotesTab />
}
}
}
const mapStateToProps = state => {
return {
settingsFile: state.settingsFile,
};
}
export default connect(mapStateToProps)(SettingsModalContent)

View File

@@ -0,0 +1,146 @@
import React from 'react';
import ReactDOM from 'react-dom';
//css for react grid
import '../../../../node_modules/react-grid-layout/css/styles.css';
import '../../../../node_modules/react-resizable/css/styles.css';
//react-grid for layout
import RGL, { WidthProvider } from 'react-grid-layout';
import PropTypes from 'prop-types';
import _ from 'lodash';
//Redux
import {connect} from 'react-redux';
import * as actionTypes from '../../../store/actions';
//interior items
import TextField from 'material-ui/TextField';
import { withStyles } from 'material-ui/styles';
import ReactTooltip from 'react-tooltip'
import Icon from 'material-ui/Icon';
import SettingsMenuList from './settingsModalList.js';
import SettingsModalContent from './settingsModalContent';
import IconButton from 'material-ui/IconButton';
import Button from 'material-ui/Button';
import Dialog, {
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from 'material-ui/Dialog';
const ReactGridLayout = WidthProvider(RGL);
const background = {
backgroundColor: '#e5e5e5',
boxShadow: '0 0 20px #000',
}
const button = {
fontSize: '60px',
paddingRight: '20px',
paddingLeft: '20px',
}
const smallButton = {
width: '36px',
height: '36px',
padding: '5px',
}
const inlineStyle = {
display: 'inline-block',
backdrop: 'static',
}
class SettingsModalLayout extends React.Component {
static propTypes = {
onLayoutChange: PropTypes.func.isRequired
};
static defaultProps = {
className: "layout",
items: 4,
rowHeight: 100,
onLayoutChange: function() {},
cols: 8,
draggableCancel: '.NoDrag',
draggableHandle: '.DragHandle'
};
constructor(props) {
super(props);
var layout = [
{i: 'b', x: 0, y: 0, w: 1, h: 5, static: true},
{i: 'c', x: 1, y: 0, w: 7, h: 5, minW: 4, minH: 3, static: true},
];
this.state = {
layout ,
textValue: "",
selectedMenuItem: 0,
};
};
onLayoutChange(layout) {
this.props.onLayoutChange(layout);
}
handleSettingsModalClose = () => {
this.props.settingsModalOpenState(false)
}
changeMenuSelection = (menuItem) => {
this.setState({selectedMenuItem: menuItem})
}
render() {
return (
<div style={inlineStyle}>
<DialogContent>
<ReactGridLayout layout={this.state.layout} onLayoutChange={this.onLayoutChange}
{...this.props}>
<div key="b" style={background} className="DragHandle">
<SettingsMenuList changeMenuSelection={this.changeMenuSelection} />
</div>
<div key="c" style={background} className="DragHandle">
<SettingsModalContent selectedMenuItem={this.state.selectedMenuItem} />
</div>
</ReactGridLayout>
</DialogContent>
<DialogActions>
<Button onClick={this.handleSettingsModalClose} color="primary">
Close
</Button>
</DialogActions>
</div>
);
}
};
const mapStateToProps = state => {
return {
settingsModalOpen: state.settingsModalOpen,
};
}
const mapDispatchToProps = dispatch => {
return {
settingsModalOpenState: (settingsModalOpen) => dispatch({type: actionTypes.SETTINGS_MODAL_OPEN_STATE, settingsModalOpen}),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SettingsModalLayout)

View File

@@ -0,0 +1,102 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Button from 'material-ui/Button';
import TextField from 'material-ui/TextField';
import { withStyles } from 'material-ui/styles';
import PropTypes from 'prop-types';
import List, {
ListItem,
ListItemIcon,
ListItemSecondaryAction,
ListItemText,
} from 'material-ui/List';
import Dialog, {
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from 'material-ui/Dialog';
import InsertLinkIcon from 'material-ui-icons/Link';
import ReactTooltip from 'react-tooltip'
import Icon from 'material-ui/Icon';
import IconButton from 'material-ui/IconButton';
import RSSTorrentIcon from 'material-ui-icons/RssFeed';
import AddRSSIcon from 'material-ui-icons/AddCircle';
import DeleteIcon from 'material-ui-icons/Delete';
//Redux
import {connect} from 'react-redux';
import * as actionTypes from '../../../store/actions';
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: '#e5e5e5',
},
icons: {
width: '40px',
height: '40px',
},
inactiveIcon: {
width: '40px',
height: '40px',
color: 'red',
},
active: {
backgroundColor: '#80b3ff',
}
});
const inlineStyle = {
display: 'inline-block',
backdrop: 'static',
}
class SettingsMenuList extends React.Component {
constructor(props){
super(props)
this.state = {
activeIndex: 0
}
}
changeMenuSelection = (listItem) => {
console.log("Menu Selection", listItem)
this.setState({activeIndex: listItem})
this.props.changeMenuSelection(listItem)
console.log("ACTIVEINDEX", this.state.activeIndex)
}
render() {
const { classes } = this.props;
return (
<div style={inlineStyle}>
<List component="nav">
<ListItem className={this.state.activeIndex==0 ? classes.active: null} button onClick={() => this.changeMenuSelection(0)}>
<ListItemText primary="News/About" />
</ListItem>
<ListItem className={this.state.activeIndex==1 ? classes.active: null} button onClick={() => this.changeMenuSelection(1)}>
<ListItemText primary="Client Connect" />
</ListItem>
<ListItem className={this.state.activeIndex==2 ? classes.active: null} button onClick={() => this.changeMenuSelection(2)}>
<ListItemText primary="Logging" />
</ListItem>
<ListItem className={this.state.activeIndex==3 ? classes.active: null} button onClick={() => this.changeMenuSelection(3)}>
<ListItemText primary="Server Settings" />
</ListItem>
</List>
</div>
);
}
};
export default withStyles(styles)(SettingsMenuList)