Implement options page

This commit is contained in:
hensm
2018-07-21 01:38:07 +01:00
parent 9f7bf780e5
commit c4ed13fb0b
8 changed files with 284 additions and 14 deletions

44
ext/src/options/index.css Normal file
View File

@@ -0,0 +1,44 @@
.category {
display: grid;
grid-template-columns: min-content min-content;
grid-column-gap: 20px;
grid-row-gap: 5px;
}
.category-name {}
.category-description {
color: graytext;
grid-column: span 2;
}
.option {
display: contents;
}
.option-label {
text-align: right;
white-space: nowrap;
display: inline-block;
}
.option > input {
align-self: center;
justify-self: flex-start;
}
#form {
display: flex;
flex-direction: column;
}
#buttons {
align-self: flex-end;
margin-block-start: 5px;
}
#buttons > :not(:last-child) {
margin-inline-end: 5px;
}
*:invalid {
box-shadow: 0 0 1.5px 1px red;
}

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="index.css">
<script src="bundle.js" defer></script>
</head>
<body>
<div id="root"></div>
</body>
</html>

141
ext/src/options/index.jsx Normal file
View File

@@ -0,0 +1,141 @@
"use strict";
import React, { Component } from "react";
import ReactDOM from "react-dom";
const _ = browser.i18n.getMessage;
class OptionsApp extends Component {
constructor (props) {
super(props);
this.state = {
isFormValid: true
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleFormChange = this.handleFormChange.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
}
/**
* Set stored option values to current state
*/
setStorage () {
return browser.storage.sync.set({
options: {
option_localMediaEnabled: this.state.option_localMediaEnabled
, option_localMediaServerPort: this.state.option_localMediaServerPort
}
});
}
/**
* Get current options state from storage and set initial
*/
async componentDidMount () {
const { options } = await browser.storage.sync.get("options");
if (options) {
this.setState({
...options
, isFormValid: this.form.checkValidity()
});
} else {
try {
await this.setStorage();
} catch (err) {
// TODO
}
}
}
async handleFormSubmit (ev) {
ev.preventDefault();
this.form.reportValidity();
try {
await this.setStorage();
} catch (err) {}
}
handleFormChange () {
this.setState({
isFormValid: this.form.checkValidity()
});
}
handleInputChange (ev) {
const val = do {
if (ev.target.type === "checkbox") {
ev.target.checked;
} else if (ev.target.type === "number") {
parseInt(ev.target.value);
} else {
ev.target.value;
}
};
console.log(ev.target.name);
this.setState({
[ ev.target.name ]: val
});
}
render () {
return (
<form id="form" ref={ form => { this.form = form; }}
onSubmit={ this.handleFormSubmit }
onChange={ this.handleFormChange }>
<fieldset className="category">
<legend className="category-name">
{ _("options_category_localMedia") }
</legend>
<p className="category-description">
{ _("options_category_localMedia_description") }
</p>
<label className="option">
<div className="option-label">
{ _("options_option_localMediaEnabled") }
</div>
<input name="option_localMediaEnabled"
type="checkbox"
checked={ this.state.option_localMediaEnabled }
onChange={ this.handleInputChange } />
</label>
<label className="option">
<div className="option-label">
{ _("options_option_localMediaServerPort") }
</div>
<input name="option_localMediaServerPort"
type="number"
required
min="1025"
max="65535"
value={ this.state.option_localMediaServerPort }
onChange={ this.handleInputChange } />
</label>
</fieldset>
<div id="buttons">
<button type="submit"
disabled={ !this.state.isFormValid }>
{ _("options_submit") }
</button>
</div>
</form>
);
}
}
ReactDOM.render(
<OptionsApp />
, document.querySelector("#root"));