Convert ext updater to typescript

This commit is contained in:
hensm
2019-02-27 19:00:29 +00:00
parent 06044d9460
commit 076c8ce699
4 changed files with 91 additions and 35 deletions

12
ext/src/global.d.ts vendored
View File

@@ -1,3 +1,4 @@
// Define replacement types
declare const EXTENSION_NAME: string;
declare const EXTENSION_ID: string;
declare const EXTENSION_VERSION: string;
@@ -5,12 +6,19 @@ declare const MIRRORING_APP_ID: string;
declare const APPLICATION_NAME: string;
declare const APPLICATION_VERSION: string;
// Fix issues with @types/firefox-webext-browser
declare namespace browser.events {
/**
* Shouldn't enforce limited function signature across all
* event types.
*/
interface Event {
addListener (...args: any[]): void;
addListener (...args: any[]): void | Promise<void>;
removeListener (...args: any[]): void | Promise<void>;
}
}
declare namespace browser.runtime {
interface Port {
error: { message: string };
@@ -22,12 +30,14 @@ declare namespace browser.runtime {
}): browser.runtime.Port;
}
// Allow default attribute on <button>
declare namespace React {
interface ButtonHTMLAttributes<T> {
default?: boolean;
}
}
declare namespace JSX {
interface IntrinsicElements {
button: React.DetailedHTMLProps<

View File

@@ -11,3 +11,20 @@ export interface Receiver {
port: number;
currentApp: string;
}
export interface DownloadDelta {
id: number;
url?: browser.downloads.StringDelta;
filename?: browser.downloads.StringDelta;
danger?: browser.downloads.StringDelta;
mime?: browser.downloads.StringDelta;
startTime?: browser.downloads.StringDelta;
endTime?: browser.downloads.StringDelta;
state?: browser.downloads.StringDelta;
canResume?: browser.downloads.BooleanDelta;
paused?: browser.downloads.BooleanDelta;
error?: browser.downloads.StringDelta;
totalBytes?: browser.downloads.DoubleDelta;
fileSize?: browser.downloads.DoubleDelta;
exists?: browser.downloads.BooleanDelta;
}

View File

@@ -1,9 +1,10 @@
"use strict";
import React, { Component } from "react";
import ReactDOM from "react-dom";
import ReactDOM from "react-dom";
import { getNextEllipsis } from "../lib/utils";
import { DownloadDelta, Message } from "../types";
const _ = browser.i18n.getMessage;
@@ -19,7 +20,17 @@ browser.runtime.getPlatformInfo()
});
const Updater = (props) => (
interface UpdaterProps {
description: string;
additionalDescription: string;
downloadTotal: number;
downloadCurrent: number;
isDownloading: boolean;
onCancel (): void;
onInstall (): void;
}
const Updater = (props: UpdaterProps) => (
<div className="updater">
<div className="updater__description">
{ props.description }
@@ -44,8 +55,25 @@ const Updater = (props) => (
</div>
);
class App extends Component {
constructor (props) {
interface UpdaterAppState {
hasLoaded: boolean;
isDownloading: boolean;
description: string;
additionalDescription: string;
downloadTotal: number;
downloadCurrent: number;
}
class UpdaterApp extends Component<{}, UpdaterAppState> {
private downloadId: number;
private downloadProgressInterval: number;
private port: browser.runtime.Port;
private frameWidth: number;
private frameHeight: number;
private win: browser.windows.Window;
constructor (props: {}) {
super(props);
this.downloadId = null;
@@ -84,14 +112,23 @@ class App extends Component {
});
}
closeWindow () {
window.clearInterval(this.downloadProgressInterval);
browser.downloads.onChanged.removeListener(this.onDownloadChanged);
this.port.onMessage.removeListener(this.onMessage);
this.port.disconnect();
render () {
if (!this.state.hasLoaded) {
return;
}
return (
<Updater description={ this.state.description }
additionalDescription={ this.state.additionalDescription }
downloadTotal={ this.state.downloadTotal }
downloadCurrent={ this.state.downloadCurrent }
isDownloading={ this.state.isDownloading }
onCancel={ this.onCancel }
onInstall={ this.onInstall } />
);
}
async onMessage (message) {
private async onMessage (message: Message) {
switch (message.subject) {
case "updater:/updateData": {
// Only run once
@@ -127,11 +164,18 @@ class App extends Component {
});
break;
};
}
}
}
onDownloadChanged (downloadItem) {
private closeWindow () {
window.clearInterval(this.downloadProgressInterval);
browser.downloads.onChanged.removeListener(this.onDownloadChanged);
this.port.onMessage.removeListener(this.onMessage);
this.port.disconnect();
}
private onDownloadChanged (downloadItem: DownloadDelta) {
if (downloadItem.id !== this.downloadId) {
return;
}
@@ -162,12 +206,13 @@ class App extends Component {
, downloadTotal: 1
, downloadCurrent: 1
, description: _("updaterDescriptionInstallReady")
, additionalDescription: _("updaterAdditionalDescriptionInstallReady")
, additionalDescription:
_("updaterAdditionalDescriptionInstallReady")
});
}
}
async updateDownloadProgress () {
private async updateDownloadProgress () {
const [ download ] = await browser.downloads.search({
id: this.downloadId
});
@@ -178,7 +223,7 @@ class App extends Component {
});
}
async onCancel () {
private async onCancel () {
try {
await browser.downloads.cancel(this.downloadId);
this.closeWindow();
@@ -187,7 +232,7 @@ class App extends Component {
}
}
async onInstall () {
private async onInstall () {
try {
await browser.downloads.open(this.downloadId);
this.closeWindow();
@@ -195,24 +240,8 @@ class App extends Component {
// Cancelled or not finished
}
}
render () {
if (!this.state.hasLoaded) {
return;
}
return (
<Updater description={ this.state.description }
additionalDescription={ this.state.additionalDescription }
downloadTotal={ this.state.downloadTotal }
downloadCurrent={ this.state.downloadCurrent }
isDownloading={ this.state.isDownloading }
onCancel={ this.onCancel }
onInstall={ this.onInstall } />
);
}
}
ReactDOM.render(
<App />
<UpdaterApp />
, document.querySelector("#root"));

View File

@@ -9,7 +9,7 @@ module.exports = (env) => ({
"main" : `${env.includePath}/main.ts`
, "popup/bundle" : `${env.includePath}/popup/index.tsx`
, "options/bundle" : `${env.includePath}/options/index.tsx`
, "updater/bundle" : `${env.includePath}/updater/index.jsx`
, "updater/bundle" : `${env.includePath}/updater/index.tsx`
, "mediaCast" : `${env.includePath}/mediaCast.js`
, "mirroringCast" : `${env.includePath}/mirroringCast.js`
, "compat/youtube" : `${env.includePath}/compat/youtube.js`