Format options index.tsx

This commit is contained in:
hensm
2022-05-29 20:37:21 +01:00
parent 088c550987
commit 32a6b218f8

View File

@@ -14,28 +14,24 @@ import logger from "../../lib/logger";
import options, { Options } from "../../lib/options"; import options, { Options } from "../../lib/options";
import { REMOTE_MATCH_PATTERN_REGEX } from "../../lib/matchPattern"; import { REMOTE_MATCH_PATTERN_REGEX } from "../../lib/matchPattern";
const _ = browser.i18n.getMessage; const _ = browser.i18n.getMessage;
// macOS styles // macOS styles
browser.runtime.getPlatformInfo() browser.runtime.getPlatformInfo().then(platformInfo => {
.then(platformInfo => { const link = document.createElement("link");
const link = document.createElement("link"); link.rel = "stylesheet";
link.rel = "stylesheet";
switch (platformInfo.os) { switch (platformInfo.os) {
case "mac": { case "mac": {
link.href = "styles/mac.css"; link.href = "styles/mac.css";
break; break;
}
} }
}
if (link.href) { if (link.href) {
document.head.appendChild(link); document.head.appendChild(link);
} }
}); });
function getInputValue(input: HTMLInputElement) { function getInputValue(input: HTMLInputElement) {
switch (input.type) { switch (input.type) {
@@ -62,17 +58,15 @@ interface OptionsAppState {
platform?: string; platform?: string;
} }
class OptionsApp extends Component< class OptionsApp extends Component<OptionsAppProps, OptionsAppState> {
OptionsAppProps, OptionsAppState> { private form: HTMLFormElement | null = null;
private form: (HTMLFormElement | null) = null;
state: OptionsAppState = { state: OptionsAppState = {
hasLoaded: false hasLoaded: false,
, bridgeLoading: true bridgeLoading: true,
, bridgeLoadingTimedOut: false bridgeLoadingTimedOut: false,
, isFormValid: true isFormValid: true,
, hasSaved: false hasSaved: false
}; };
constructor(props: OptionsAppProps) { constructor(props: OptionsAppProps) {
@@ -85,16 +79,16 @@ class OptionsApp extends Component<
this.handleWhitelistChange = this.handleWhitelistChange.bind(this); this.handleWhitelistChange = this.handleWhitelistChange.bind(this);
this.getWhitelistItemPatternError = this.getWhitelistItemPatternError =
this.getWhitelistItemPatternError.bind(this); this.getWhitelistItemPatternError.bind(this);
} }
public async componentDidMount() { public async componentDidMount() {
this.setState({ this.setState({
hasLoaded: true hasLoaded: true,
, options: await options.getAll() options: await options.getAll(),
, platform: (await browser.runtime.getPlatformInfo()).os platform: (await browser.runtime.getPlatformInfo()).os
}); });
// Update options data if changed whilst page is open // Update options data if changed whilst page is open
options.addEventListener("changed", async () => { options.addEventListener("changed", async () => {
this.setState({ this.setState({
@@ -106,16 +100,16 @@ class OptionsApp extends Component<
const bridgeInfo = await bridge.getInfo(); const bridgeInfo = await bridge.getInfo();
this.setState({ this.setState({
bridgeInfo bridgeInfo,
, bridgeLoading: false bridgeLoading: false
}); });
} catch (err) { } catch (err) {
logger.error("Failed to fetch bridge/platform info."); logger.error("Failed to fetch bridge/platform info.");
if (err instanceof BridgeTimedOutError) { if (err instanceof BridgeTimedOutError) {
this.setState({ this.setState({
bridgeLoading: false bridgeLoading: false,
, bridgeLoadingTimedOut: true bridgeLoadingTimedOut: true
}); });
} else { } else {
this.setState({ this.setState({
@@ -132,60 +126,76 @@ class OptionsApp extends Component<
return ( return (
<div> <div>
<form id="form" ref={ form => { this.form = form; }} <form
onSubmit={ this.handleFormSubmit } id="form"
onChange={ this.handleFormChange }> ref={form => {
this.form = form;
<Bridge info={ this.state.bridgeInfo } }}
loading={ this.state.bridgeLoading } onSubmit={this.handleFormSubmit}
loadingTimedOut={ this.state.bridgeLoadingTimedOut } onChange={this.handleFormChange}
options={ this.state.options } >
onChange={ this.handleInputChange } /> <Bridge
info={this.state.bridgeInfo}
loading={this.state.bridgeLoading}
loadingTimedOut={this.state.bridgeLoadingTimedOut}
options={this.state.options}
onChange={this.handleInputChange}
/>
<fieldset className="category"> <fieldset className="category">
<legend className="category__name"> <legend className="category__name">
<h2>{ _("optionsMediaCategoryName") }</h2> <h2>{_("optionsMediaCategoryName")}</h2>
</legend> </legend>
<p className="category__description"> <p className="category__description">
{ _("optionsMediaCategoryDescription") } {_("optionsMediaCategoryDescription")}
</p> </p>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="mediaEnabled" <input
type="checkbox" name="mediaEnabled"
checked={ this.state.options?.mediaEnabled } type="checkbox"
onChange={ this.handleInputChange } /> checked={this.state.options?.mediaEnabled}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsMediaEnabled") } {_("optionsMediaEnabled")}
</div> </div>
</label> </label>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="mediaSyncElement" <input
type="checkbox" name="mediaSyncElement"
checked={ this.state.options?.mediaSyncElement } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options?.mediaSyncElement
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsMediaSyncElement") } {_("optionsMediaSyncElement")}
</div> </div>
<div className="option__description"> <div className="option__description">
{ _("optionsMediaSyncElementDescription") } {_("optionsMediaSyncElementDescription")}
</div> </div>
</label> </label>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="mediaStopOnUnload" <input
type="checkbox" name="mediaStopOnUnload"
checked={ this.state.options?.mediaStopOnUnload } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options?.mediaStopOnUnload
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsMediaStopOnUnload") } {_("optionsMediaStopOnUnload")}
</div> </div>
</label> </label>
@@ -193,67 +203,81 @@ class OptionsApp extends Component<
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="localMediaEnabled" <input
type="checkbox" name="localMediaEnabled"
checked={ this.state.options?.localMediaEnabled } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options?.localMediaEnabled
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsLocalMediaEnabled") } {_("optionsLocalMediaEnabled")}
</div> </div>
<div className="option__description"> <div className="option__description">
{ _("optionsLocalMediaCategoryDescription") } {_("optionsLocalMediaCategoryDescription")}
</div> </div>
</label> </label>
<label className="option"> <label className="option">
<div className="option__label"> <div className="option__label">
{ _("optionsLocalMediaServerPort") } {_("optionsLocalMediaServerPort")}
</div> </div>
<div className="option__control"> <div className="option__control">
<input name="localMediaServerPort" <input
type="number" name="localMediaServerPort"
required type="number"
min="1025" required
max="65535" min="1025"
value={ this.state.options?.localMediaServerPort } max="65535"
onChange={ this.handleInputChange } /> value={
this.state.options?.localMediaServerPort
}
onChange={this.handleInputChange}
/>
</div> </div>
</label> </label>
</fieldset> </fieldset>
<fieldset className="category"> <fieldset className="category">
<legend className="category__name"> <legend className="category__name">
<h2>{ _("optionsMirroringCategoryName") }</h2> <h2>{_("optionsMirroringCategoryName")}</h2>
</legend> </legend>
<p className="category__description"> <p className="category__description">
{ _("optionsMirroringCategoryDescription") } {_("optionsMirroringCategoryDescription")}
</p> </p>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="mirroringEnabled" <input
type="checkbox" name="mirroringEnabled"
checked={ this.state.options?.mirroringEnabled } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options?.mirroringEnabled
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsMirroringEnabled") } {_("optionsMirroringEnabled")}
</div> </div>
</label> </label>
<label className="option"> <label className="option">
<div className="option__label"> <div className="option__label">
{ _("optionsMirroringAppId") } {_("optionsMirroringAppId")}
</div> </div>
<div className="option__control"> <div className="option__control">
<input name="mirroringAppId" <input
type="text" name="mirroringAppId"
required type="text"
value={ this.state.options?.mirroringAppId } required
onChange={ this.handleInputChange } /> value={this.state.options?.mirroringAppId}
onChange={this.handleInputChange}
/>
<div className="option__description"> <div className="option__description">
{ _("optionsMirroringAppIdDescription") } {_("optionsMirroringAppIdDescription")}
</div> </div>
</div> </div>
</label> </label>
@@ -261,108 +285,145 @@ class OptionsApp extends Component<
<fieldset className="category"> <fieldset className="category">
<legend className="category__name"> <legend className="category__name">
<h2>{ _("optionsReceiverSelectorCategoryName") }</h2> <h2>{_("optionsReceiverSelectorCategoryName")}</h2>
</legend> </legend>
<p className="category__description"> <p className="category__description">
{ _("optionsReceiverSelectorCategoryDescription") } {_("optionsReceiverSelectorCategoryDescription")}
</p> </p>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="receiverSelectorWaitForConnection" <input
type="checkbox" name="receiverSelectorWaitForConnection"
checked={ this.state.options?.receiverSelectorWaitForConnection } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options
?.receiverSelectorWaitForConnection
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsReceiverSelectorWaitForConnection") } {_("optionsReceiverSelectorWaitForConnection")}
</div> </div>
<div className="option__description"> <div className="option__description">
{ _("optionsReceiverSelectorWaitForConnectionDescription") } {_(
"optionsReceiverSelectorWaitForConnectionDescription"
)}
</div> </div>
</label> </label>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="receiverSelectorCloseIfFocusLost" <input
type="checkbox" name="receiverSelectorCloseIfFocusLost"
checked={ this.state.options?.receiverSelectorCloseIfFocusLost } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options
?.receiverSelectorCloseIfFocusLost
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsReceiverSelectorCloseIfFocusLost") } {_("optionsReceiverSelectorCloseIfFocusLost")}
</div> </div>
</label> </label>
</fieldset> </fieldset>
<fieldset className="category"> <fieldset className="category">
<legend className="category__name"> <legend className="category__name">
<h2>{ _("optionsUserAgentWhitelistCategoryName") }</h2> <h2>
{_("optionsUserAgentWhitelistCategoryName")}
</h2>
</legend> </legend>
<p className="category__description"> <p className="category__description">
{ _("optionsUserAgentWhitelistCategoryDescription") } {_("optionsUserAgentWhitelistCategoryDescription")}
</p> </p>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="userAgentWhitelistEnabled" <input
type="checkbox" name="userAgentWhitelistEnabled"
checked={ this.state.options?.userAgentWhitelistEnabled } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options
?.userAgentWhitelistEnabled
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsUserAgentWhitelistEnabled") } {_("optionsUserAgentWhitelistEnabled")}
<span className="option__recommended"> <span className="option__recommended">
{ _("optionsOptionRecommended") } {_("optionsOptionRecommended")}
</span> </span>
</div> </div>
</label> </label>
<label className="option option--inline"> <label className="option option--inline">
<div className="option__control"> <div className="option__control">
<input name="userAgentWhitelistRestrictedEnabled" <input
type="checkbox" name="userAgentWhitelistRestrictedEnabled"
checked={ this.state.options?.userAgentWhitelistRestrictedEnabled } type="checkbox"
onChange={ this.handleInputChange } /> checked={
this.state.options
?.userAgentWhitelistRestrictedEnabled
}
onChange={this.handleInputChange}
/>
</div> </div>
<div className="option__label"> <div className="option__label">
{ _("optionsUserAgentWhitelistRestrictedEnabled") } {_(
"optionsUserAgentWhitelistRestrictedEnabled"
)}
<span className="option__recommended"> <span className="option__recommended">
{ _("optionsOptionRecommended") } {_("optionsOptionRecommended")}
</span> </span>
</div> </div>
<div className="option__description"> <div className="option__description">
{ _("optionsUserAgentWhitelistRestrictedEnabledDescription") } {_(
"optionsUserAgentWhitelistRestrictedEnabledDescription"
)}
</div> </div>
</label> </label>
<div className="option"> <div className="option">
<div className="option__label"> <div className="option__label">
{ _("optionsUserAgentWhitelistContent") } {_("optionsUserAgentWhitelistContent")}
</div> </div>
<div className="option__control"> <div className="option__control">
{ this.state.options?.userAgentWhitelist && {this.state.options?.userAgentWhitelist && (
<EditableList data={ this.state.options.userAgentWhitelist } <EditableList
onChange={ this.handleWhitelistChange } data={
itemPattern={ REMOTE_MATCH_PATTERN_REGEX } this.state.options
itemPatternError={ this.getWhitelistItemPatternError } /> } .userAgentWhitelist
}
onChange={this.handleWhitelistChange}
itemPattern={REMOTE_MATCH_PATTERN_REGEX}
itemPatternError={
this.getWhitelistItemPatternError
}
/>
)}
</div> </div>
</div> </div>
</fieldset> </fieldset>
<div id="buttons"> <div id="buttons">
<div id="status-line"> <div id="status-line">
{ this.state.hasSaved && _("optionsSaved") } {this.state.hasSaved && _("optionsSaved")}
</div> </div>
<button onClick={ this.handleReset } <button onClick={this.handleReset} type="button">
type="button"> {_("optionsReset")}
{ _("optionsReset") }
</button> </button>
<button type="submit" <button
// @ts-ignore type="submit"
default // @ts-ignore
disabled={ !this.state.isFormValid }> default
{ _("optionsSave") } disabled={!this.state.isFormValid}
>
{_("optionsSave")}
</button> </button>
</div> </div>
</form> </form>
@@ -370,7 +431,6 @@ class OptionsApp extends Component<
); );
} }
private handleReset() { private handleReset() {
this.setState({ this.setState({
options: { ...defaultOptions } options: { ...defaultOptions }
@@ -386,15 +446,18 @@ class OptionsApp extends Component<
if (this.state.options) { if (this.state.options) {
await options.setAll(this.state.options); await options.setAll(this.state.options);
this.setState({ this.setState(
hasSaved: true {
}, () => { hasSaved: true
window.setTimeout(() => { },
this.setState({ () => {
hasSaved: false window.setTimeout(() => {
}); this.setState({
}, 1000); hasSaved: false
}); });
}, 1000);
}
);
} }
} catch (err) { } catch (err) {
logger.error("Failed to save options"); logger.error("Failed to save options");