/* tslint:disable:max-line-length */ "use strict"; import React, { Component } from "react"; import ReactDOM from "react-dom"; import { getNextEllipsis } from "../lib/utils"; import * as types from "../types"; const _ = browser.i18n.getMessage; // macOS styles browser.runtime.getPlatformInfo() .then(platformInfo => { if (platformInfo.os === "mac") { const link = document.createElement("link"); link.rel = "stylesheet"; link.href = "styles/mac.css"; document.head.appendChild(link); } }); const winWidth = 350; let winHeight = 200; let frameHeight: number; let frameWidth: number; interface PopupAppState { receivers: types.Receiver[]; selectedMedia: string; isLoading: boolean; } class PopupApp extends Component<{}, PopupAppState> { private port: browser.runtime.Port; private win: browser.windows.Window; constructor (props: {}) { super(props); this.state = { receivers: [] , selectedMedia: "app" , isLoading: false }; // Store window ref browser.windows.getCurrent().then(win => { this.win = win; frameHeight = win.height - window.innerHeight; frameWidth = win.width - window.innerWidth; }); this.onSelectChange = this.onSelectChange.bind(this); this.onCast = this.onCast.bind(this); } componentDidMount () { const backgroundPort = browser.runtime.connect({ name: "popup" }); backgroundPort.onMessage.addListener((message: types.Message) => { if (message.subject === "popup:/assignShim") { this.setPort(message.data.tabId , message.data.frameId); } }); } render () { const shareMedia = this.state.selectedMedia === "tab" || this.state.selectedMedia === "screen"; return (
Cast to:
); } private async setPort (shimTabId: number, shimFrameId: number) { if (this.port) { this.port.disconnect(); } this.port = browser.tabs.connect(shimTabId, { name: "popup" , frameId: shimFrameId }); this.port.postMessage({ subject: "shim:/popupReady" }); this.port.onMessage.addListener((message: types.Message) => { switch (message.subject) { case "popup:/populateReceiverList": { this.setState({ receivers: message.data.receivers , selectedMedia: message.data.selectedMedia }, () => { // Get height of content without window decoration winHeight = document.body.clientHeight + frameHeight; // Adjust height to fit content browser.windows.update(this.win.id, { height: winHeight }); }); break; } case "popup:/close": { window.close(); break; } } }); } private onCast (receiver: types.Receiver) { this.setState({ isLoading: true }); this.port.postMessage({ subject: "shim:/selectReceiver" , data: { receiver , selectedMedia: this.state.selectedMedia , a: 5 } }); } private onSelectChange (ev: React.ChangeEvent) { this.setState({ selectedMedia: ev.target.value }); } } interface ReceiverProps { receiver: types.Receiver; isLoading: boolean; onCast (receiver: types.Receiver): void; } interface ReceiverState { ellipsis: string; isLoading: boolean; } class Receiver extends Component { constructor (props: ReceiverProps) { super(props); this.state = { isLoading: false , ellipsis: "" }; this.onClick = this.onClick.bind(this); } onClick () { this.props.onCast(this.props.receiver); this.setState({ isLoading: true }); setInterval(() => { this.setState(state => ({ ellipsis: getNextEllipsis(state.ellipsis) })); }, 500); } render () { return (
  • { this.props.receiver.friendlyName }
    { `${this.props.receiver.address}:${this.props.receiver.port}` }
    { this.props.receiver.currentApp && `- ${this.props.receiver.currentApp}` }
  • ); } } ReactDOM.render( , document.querySelector("#root"));