mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-10 01:29:58 +00:00
Narrow linting rules and fix for eslintrc for js files
This commit is contained in:
@@ -4,14 +4,23 @@
|
||||
import React, { Component } from "react";
|
||||
import semver from "semver";
|
||||
|
||||
import options, { Options } from "../../lib/options";
|
||||
import { Options } from "../../lib/options";
|
||||
|
||||
import { BridgeInfo } from "../../lib/bridge";
|
||||
import { getNextEllipsis } from "../../lib/utils";
|
||||
|
||||
import logger from "../../lib/logger";
|
||||
|
||||
const _ = browser.i18n.getMessage;
|
||||
|
||||
interface Release {
|
||||
url: string;
|
||||
tag_name: string;
|
||||
html_url: string;
|
||||
assets: Array<{
|
||||
content_type: string;
|
||||
html_url: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface BridgeStatsProps {
|
||||
info: BridgeInfo;
|
||||
@@ -20,45 +29,42 @@ interface BridgeStatsProps {
|
||||
const BridgeStats = (props: BridgeStatsProps) => (
|
||||
<table className="bridge__stats">
|
||||
<tr>
|
||||
<th>{ _("optionsBridgeStatsName") }</th>
|
||||
<td>{ props.info.name }</td>
|
||||
<th>{_("optionsBridgeStatsName")}</th>
|
||||
<td>{props.info.name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{ _("optionsBridgeStatsVersion") }</th>
|
||||
<td>{ props.info.version }</td>
|
||||
<th>{_("optionsBridgeStatsVersion")}</th>
|
||||
<td>{props.info.version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{ _("optionsBridgeStatsExpectedVersion") }</th>
|
||||
<td>{ props.info.expectedVersion }</td>
|
||||
<th>{_("optionsBridgeStatsExpectedVersion")}</th>
|
||||
<td>{props.info.expectedVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{ _("optionsBridgeStatsCompatibility") }</th>
|
||||
<th>{_("optionsBridgeStatsCompatibility")}</th>
|
||||
<td>
|
||||
{ props.info.isVersionCompatible
|
||||
{props.info.isVersionCompatible
|
||||
? props.info.isVersionExact
|
||||
? _("optionsBridgeCompatible")
|
||||
: _("optionsBridgeLikelyCompatible")
|
||||
: _("optionsBridgeIncompatible") }
|
||||
: _("optionsBridgeIncompatible")}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{ _("optionsBridgeStatsRecommendedAction") }</th>
|
||||
<th>{_("optionsBridgeStatsRecommendedAction")}</th>
|
||||
<td>
|
||||
{
|
||||
props.info.isVersionCompatible
|
||||
? _("optionsBridgeNoAction")
|
||||
: props.info.isVersionOlder
|
||||
? _("optionsBridgeOlderAction")
|
||||
: props.info.isVersionNewer
|
||||
? _("optionsBridgeNewerAction")
|
||||
: _("optionsBridgeNoAction")
|
||||
}
|
||||
{props.info.isVersionCompatible
|
||||
? _("optionsBridgeNoAction")
|
||||
: props.info.isVersionOlder
|
||||
? _("optionsBridgeOlderAction")
|
||||
: props.info.isVersionNewer
|
||||
? _("optionsBridgeNewerAction")
|
||||
: _("optionsBridgeNoAction")}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
);
|
||||
|
||||
|
||||
interface BridgeProps {
|
||||
info?: BridgeInfo;
|
||||
loading: boolean;
|
||||
@@ -76,17 +82,17 @@ interface BridgeState {
|
||||
}
|
||||
|
||||
export default class Bridge extends Component<BridgeProps, BridgeState> {
|
||||
private updateData: any;
|
||||
private updateData?: Release;
|
||||
private updateStatusTimeout?: number;
|
||||
|
||||
constructor(props: BridgeProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isCheckingUpdates: false
|
||||
, isUpdateAvailable: false
|
||||
, wasErrorCheckingUpdates: false
|
||||
, checkUpdatesEllipsis: "..."
|
||||
isCheckingUpdates: false,
|
||||
isUpdateAvailable: false,
|
||||
wasErrorCheckingUpdates: false,
|
||||
checkUpdatesEllipsis: "..."
|
||||
};
|
||||
|
||||
this.onCheckUpdates = this.onCheckUpdates.bind(this);
|
||||
@@ -96,97 +102,123 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
||||
}
|
||||
|
||||
public render() {
|
||||
const [ backupMessageStart, backupMessageEnd ] =
|
||||
_("optionsBridgeBackupEnabled", "\0").split("\0");
|
||||
const [backupMessageStart, backupMessageEnd] = _(
|
||||
"optionsBridgeBackupEnabled",
|
||||
"\0"
|
||||
).split("\0");
|
||||
|
||||
return (
|
||||
<div className="bridge">
|
||||
{ this.props.loading
|
||||
? ( <div className="bridge__loading">
|
||||
{ _("optionsBridgeLoading") }
|
||||
<progress></progress>
|
||||
</div> )
|
||||
: this.renderStatus() }
|
||||
{this.props.loading ? (
|
||||
<div className="bridge__loading">
|
||||
{_("optionsBridgeLoading")}
|
||||
<progress></progress>
|
||||
</div>
|
||||
) : (
|
||||
this.renderStatus()
|
||||
)}
|
||||
|
||||
{ !this.props.loading && this.props.options &&
|
||||
{!this.props.loading && this.props.options && (
|
||||
<div className="bridge__options">
|
||||
<label className="option option--inline">
|
||||
<div className="option__control">
|
||||
<input name="bridgeBackupEnabled"
|
||||
type="checkbox"
|
||||
checked={ this.props.options.bridgeBackupEnabled }
|
||||
onChange={ this.props.onChange } />
|
||||
<input
|
||||
name="bridgeBackupEnabled"
|
||||
type="checkbox"
|
||||
checked={
|
||||
this.props.options.bridgeBackupEnabled
|
||||
}
|
||||
onChange={this.props.onChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="option__label">
|
||||
{ backupMessageStart }
|
||||
<input className="bridge__backup-host"
|
||||
name="bridgeBackupHost"
|
||||
type="text"
|
||||
required
|
||||
value={ this.props.options.bridgeBackupHost }
|
||||
onChange={ this.props.onChange } />
|
||||
{backupMessageStart}
|
||||
<input
|
||||
className="bridge__backup-host"
|
||||
name="bridgeBackupHost"
|
||||
type="text"
|
||||
required
|
||||
value={this.props.options.bridgeBackupHost}
|
||||
onChange={this.props.onChange}
|
||||
/>
|
||||
:
|
||||
<input className="bridge__backup-port"
|
||||
name="bridgeBackupPort"
|
||||
type="number"
|
||||
required
|
||||
min="1025"
|
||||
max="65535"
|
||||
value={ this.props.options.bridgeBackupPort }
|
||||
onChange={ this.props.onChange } />
|
||||
{ backupMessageEnd }
|
||||
<input
|
||||
className="bridge__backup-port"
|
||||
name="bridgeBackupPort"
|
||||
type="number"
|
||||
required
|
||||
min="1025"
|
||||
max="65535"
|
||||
value={this.props.options.bridgeBackupPort}
|
||||
onChange={this.props.onChange}
|
||||
/>
|
||||
{backupMessageEnd}
|
||||
</div>
|
||||
<div className="option__description">
|
||||
{ _("optionsBridgeBackupEnabledDescription") }
|
||||
{_("optionsBridgeBackupEnabledDescription")}
|
||||
</div>
|
||||
</label>
|
||||
</div> }
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ !this.props.loading &&
|
||||
{!this.props.loading && (
|
||||
<div className="bridge__update-info">
|
||||
{ this.state.isUpdateAvailable
|
||||
? ( <div className="bridge__update">
|
||||
<p className="bridge__update-label">
|
||||
{ _("optionsBridgeUpdateAvailable") }
|
||||
</p>
|
||||
<div className="bridge__update-options">
|
||||
<button className="bridge__update-start"
|
||||
type="button"
|
||||
onClick={ this.onUpdate }>
|
||||
{ _("optionsBridgeUpdate") }
|
||||
</button>
|
||||
</div>
|
||||
</div> )
|
||||
: ( <button className="bridge__update-check"
|
||||
{this.state.isUpdateAvailable ? (
|
||||
<div className="bridge__update">
|
||||
<p className="bridge__update-label">
|
||||
{_("optionsBridgeUpdateAvailable")}
|
||||
</p>
|
||||
<div className="bridge__update-options">
|
||||
<button
|
||||
className="bridge__update-start"
|
||||
type="button"
|
||||
disabled={ this.state.isCheckingUpdates }
|
||||
onClick={ this.onCheckUpdates }>
|
||||
|
||||
{ this.state.isCheckingUpdates
|
||||
? _("optionsBridgeUpdateChecking"
|
||||
, getNextEllipsis(this.state.checkUpdatesEllipsis))
|
||||
: _("optionsBridgeUpdateCheck") }
|
||||
</button> )}
|
||||
onClick={this.onUpdate}
|
||||
>
|
||||
{_("optionsBridgeUpdate")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<button
|
||||
className="bridge__update-check"
|
||||
type="button"
|
||||
disabled={this.state.isCheckingUpdates}
|
||||
onClick={this.onCheckUpdates}
|
||||
>
|
||||
{this.state.isCheckingUpdates
|
||||
? _(
|
||||
"optionsBridgeUpdateChecking",
|
||||
getNextEllipsis(
|
||||
this.state.checkUpdatesEllipsis
|
||||
)
|
||||
)
|
||||
: _("optionsBridgeUpdateCheck")}
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div className="bridge--update-status">
|
||||
{ this.state.updateStatus && !this.state.isUpdateAvailable
|
||||
&& this.state.updateStatus }
|
||||
{this.state.updateStatus &&
|
||||
!this.state.isUpdateAvailable &&
|
||||
this.state.updateStatus}
|
||||
</div>
|
||||
</div> }
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private renderStatus() {
|
||||
const infoClasses = `bridge__info ${!this.props.info
|
||||
? this.props.loadingTimedOut
|
||||
? "bridge__info--timed-out"
|
||||
: "bridge__info--not-found"
|
||||
: "bridge__info--found"}`;
|
||||
const infoClasses = `bridge__info ${
|
||||
!this.props.info
|
||||
? this.props.loadingTimedOut
|
||||
? "bridge__info--timed-out"
|
||||
: "bridge__info--not-found"
|
||||
: "bridge__info--found"
|
||||
}`;
|
||||
|
||||
let statusIcon: string;
|
||||
let statusTitle: string;
|
||||
let statusText: (string | null) = null;
|
||||
let statusText: string | null = null;
|
||||
|
||||
if (this.props.loadingTimedOut) {
|
||||
statusIcon = "assets/icons8-warn-120.png";
|
||||
@@ -208,22 +240,21 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
||||
return (
|
||||
<div className={infoClasses}>
|
||||
<div className="bridge__status">
|
||||
<img className="bridge__status-icon"
|
||||
width="60" height="60"
|
||||
src={ statusIcon } />
|
||||
<img
|
||||
className="bridge__status-icon"
|
||||
width="60"
|
||||
height="60"
|
||||
src={statusIcon}
|
||||
/>
|
||||
|
||||
<h2 className="bridge__status-title">
|
||||
{ statusTitle }
|
||||
</h2>
|
||||
<h2 className="bridge__status-title">{statusTitle}</h2>
|
||||
|
||||
{ statusText &&
|
||||
<p className="bridge__status-text">
|
||||
{ statusText }
|
||||
</p> }
|
||||
{statusText && (
|
||||
<p className="bridge__status-text">{statusText}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{ this.props.info &&
|
||||
<BridgeStats info={ this.props.info }/> }
|
||||
{this.props.info && <BridgeStats info={this.props.info} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -236,7 +267,8 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
||||
const timeout = window.setInterval(() => {
|
||||
this.setState(state => ({
|
||||
checkUpdatesEllipsis: getNextEllipsis(
|
||||
state.checkUpdatesEllipsis)
|
||||
state.checkUpdatesEllipsis
|
||||
)
|
||||
}));
|
||||
}, 500);
|
||||
|
||||
@@ -249,52 +281,58 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
||||
.catch(this.onCheckUpdatesError);
|
||||
}
|
||||
|
||||
private async onCheckUpdatesResponse(res: any) {
|
||||
private async onCheckUpdatesResponse(res: Release[]) {
|
||||
if (!Array.isArray(res)) {
|
||||
throw logger.error("Check update response is not array.", res);
|
||||
}
|
||||
|
||||
let latestBridgeRelease;
|
||||
for (const release of res) {
|
||||
if (release.assets.find((asset: any) =>
|
||||
asset.content_type !== "application/x-xpinstall")) {
|
||||
if (
|
||||
release.assets.find(
|
||||
asset => asset.content_type !== "application/x-xpinstall"
|
||||
)
|
||||
) {
|
||||
latestBridgeRelease = release;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!latestBridgeRelease) {
|
||||
this.setState({
|
||||
isCheckingUpdates: false
|
||||
, wasErrorCheckingUpdates: true
|
||||
, updateStatus: _("optionsBridgeUpdateStatusError")
|
||||
});
|
||||
|
||||
return;
|
||||
throw logger.error(
|
||||
"Check update response does not contain release info."
|
||||
);
|
||||
}
|
||||
|
||||
const isUpdateAvailable = !this.props.info || semver.lt(
|
||||
this.props.info.version, latestBridgeRelease.tag_name);
|
||||
/**
|
||||
* Update available if no bridge found or bridge version lower
|
||||
* than fetched release version.
|
||||
*/
|
||||
const isUpdateAvailable =
|
||||
!this.props.info ||
|
||||
semver.lt(this.props.info.version, latestBridgeRelease.tag_name);
|
||||
|
||||
if (isUpdateAvailable) {
|
||||
this.updateData = latestBridgeRelease;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isCheckingUpdates: false
|
||||
, isUpdateAvailable
|
||||
});
|
||||
|
||||
if (!isUpdateAvailable) {
|
||||
} else {
|
||||
this.setState({
|
||||
updateStatus: _("optionsBridgeUpdateStatusNoUpdates")
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isCheckingUpdates: false,
|
||||
isUpdateAvailable
|
||||
});
|
||||
|
||||
this.showUpdateStatus();
|
||||
}
|
||||
|
||||
private onCheckUpdatesError() {
|
||||
this.setState({
|
||||
isCheckingUpdates: false
|
||||
, wasErrorCheckingUpdates: true
|
||||
, updateStatus: _("optionsBridgeUpdateStatusError")
|
||||
isCheckingUpdates: false,
|
||||
wasErrorCheckingUpdates: true,
|
||||
updateStatus: _("optionsBridgeUpdateStatusError")
|
||||
});
|
||||
|
||||
this.showUpdateStatus();
|
||||
@@ -313,7 +351,7 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
||||
|
||||
private async onUpdate() {
|
||||
// Open downloads page
|
||||
if (this.updateData.html_url) {
|
||||
if (this.updateData?.html_url) {
|
||||
browser.tabs.create({
|
||||
url: this.updateData.html_url
|
||||
});
|
||||
|
||||
@@ -565,8 +565,6 @@ class ReceiverEntry extends Component<ReceiverEntryProps, ReceiverEntryState> {
|
||||
return;
|
||||
}
|
||||
|
||||
const application = status.applications?.[0];
|
||||
|
||||
if (this.state.showAlternateAction) {
|
||||
this.props.onStop(this.props.receiverDevice);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user