mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-10 01:29:58 +00:00
Add initial ReceiverSelectorManager implementations
This commit is contained in:
22
ext/src/receiverSelectorManager/ReceiverSelectorManager.ts
Normal file
22
ext/src/receiverSelectorManager/ReceiverSelectorManager.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
import { Receiver } from "../types"
|
||||
|
||||
|
||||
export type ReceiverSelectorSelectedEvent = CustomEvent<Receiver>;
|
||||
export type ReceiverSelectorErrorEvent = CustomEvent;
|
||||
export type ReceiverSelectorCancelledEvent = CustomEvent;
|
||||
|
||||
export enum ReceiverSelectorCastType {
|
||||
App
|
||||
, Tab
|
||||
, Screen
|
||||
}
|
||||
|
||||
export default interface ReceiverSelectorManager extends EventTarget {
|
||||
open (
|
||||
receivers: Receiver[]
|
||||
, defaultCastType: ReceiverSelectorCastType): void;
|
||||
|
||||
close (): void;
|
||||
}
|
||||
7
ext/src/receiverSelectorManager/index.ts
Normal file
7
ext/src/receiverSelectorManager/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
export { default as NativeMacReceiverSelectorManager }
|
||||
from "./selectorManagers/NativeMacReceiverSelectorManager";
|
||||
|
||||
export { default as PopupReceiverSelectorManager }
|
||||
from "./selectorManagers/PopupReceiverSelectorManager";
|
||||
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
|
||||
import ReceiverSelectorManager, {
|
||||
ReceiverSelectorCastType } from "../ReceiverSelectorManager";
|
||||
|
||||
import { Receiver, Message } from "../../types";
|
||||
|
||||
|
||||
class NativeMacReceiverSelectorManager
|
||||
extends EventTarget
|
||||
implements ReceiverSelectorManager {
|
||||
|
||||
public async open (
|
||||
receivers: Receiver[]
|
||||
, defaultCastType: ReceiverSelectorCastType): Promise<void> {
|
||||
console.info("STUB :: NativeMacReceiverSelectorManager.open");
|
||||
}
|
||||
|
||||
public close (): void {
|
||||
console.info("STUB :: NativeMacReceiverSelectorManager.close");
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
export default new NativeMacReceiverSelectorManager();
|
||||
@@ -0,0 +1,152 @@
|
||||
"use strict";
|
||||
|
||||
import ReceiverSelectorManager, {
|
||||
ReceiverSelectorCastType } from "../ReceiverSelectorManager";
|
||||
|
||||
import { Receiver, Message } from "../../types";
|
||||
import { getWindowCenteredProps } from "../../lib/utils";
|
||||
|
||||
|
||||
class PopupReceiverSelectorManager
|
||||
extends EventTarget
|
||||
implements ReceiverSelectorManager {
|
||||
|
||||
private windowId: number;
|
||||
private openerWindowId: number;
|
||||
private messagePort: browser.runtime.Port;
|
||||
|
||||
private receivers: Receiver[];
|
||||
private defaultCastType: ReceiverSelectorCastType;
|
||||
|
||||
private wasReceiverSelected: boolean = false;
|
||||
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
|
||||
// Bind methods to pass to addListener
|
||||
this.onPopupMessage = this.onPopupMessage.bind(this);
|
||||
this.onWindowsRemoved = this.onWindowsRemoved.bind(this);
|
||||
this.onWindowsFocusChanged = this.onWindowsFocusChanged.bind(this);
|
||||
|
||||
browser.windows.onRemoved.addListener(this.onWindowsRemoved);
|
||||
|
||||
/**
|
||||
* Handle incoming message channel connection from popup
|
||||
* window script.
|
||||
*/
|
||||
browser.runtime.onConnect.addListener(port => {
|
||||
if (port.name !== "popup") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disconnect existing port
|
||||
if (this.messagePort) {
|
||||
this.messagePort.disconnect();
|
||||
}
|
||||
|
||||
this.messagePort = port;
|
||||
this.messagePort.onMessage.addListener(this.onPopupMessage);
|
||||
|
||||
// TODO: Send initial data
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public async open (
|
||||
receivers: Receiver[]
|
||||
, defaultCastType: ReceiverSelectorCastType): Promise<void> {
|
||||
|
||||
// If popup already exists, close it
|
||||
if (this.windowId) {
|
||||
await browser.windows.remove(this.windowId);
|
||||
}
|
||||
|
||||
this.receivers = receivers;
|
||||
this.defaultCastType = defaultCastType;
|
||||
|
||||
// Current window to base centered position on
|
||||
const openerWindow = await browser.windows.getCurrent();
|
||||
const centeredProps = getWindowCenteredProps(openerWindow, 350, 200);
|
||||
|
||||
const popup = await browser.windows.create({
|
||||
url: "ui/popup/index.html"
|
||||
, type: "popup"
|
||||
, ...centeredProps
|
||||
});
|
||||
|
||||
this.windowId = popup.id;
|
||||
this.openerWindowId = openerWindow.id;
|
||||
|
||||
// Size/position not set correctly on creation (bug?)
|
||||
await browser.windows.update(this.windowId, {
|
||||
...centeredProps
|
||||
});
|
||||
|
||||
// Add focus listener
|
||||
browser.windows.onFocusChanged.addListener(
|
||||
this.onWindowsFocusChanged);
|
||||
}
|
||||
|
||||
public close (): void {
|
||||
browser.windows.remove(this.windowId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles popup messages.
|
||||
*/
|
||||
private onPopupMessage (message: Message) {
|
||||
switch (message.subject) {
|
||||
case "selected": {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles cancellation state where the popup window is closed
|
||||
* before a receiver is selected.
|
||||
*/
|
||||
private onWindowsRemoved (windowId: number) {
|
||||
// Only care about popup window
|
||||
if (windowId !== this.windowId) {
|
||||
return;
|
||||
}
|
||||
|
||||
browser.windows.onFocusChanged.removeListener(
|
||||
this.onWindowsFocusChanged);
|
||||
|
||||
if (!this.wasReceiverSelected) {
|
||||
this.dispatchEvent(new CustomEvent("cancelled"));
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
this.windowId = null;
|
||||
this.openerWindowId = null;
|
||||
this.messagePort = null;
|
||||
this.receivers = null;
|
||||
this.defaultCastType = null;
|
||||
this.wasReceiverSelected = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes popup window if another browser window is brought
|
||||
* into focus. Doesn't apply if no window is focused
|
||||
* `WINDOW_ID_NONE` or if the popup window is re-focused.
|
||||
*/
|
||||
private onWindowsFocusChanged (windowId: number) {
|
||||
if (windowId !== browser.windows.WINDOW_ID_NONE
|
||||
&& windowId !== this.windowId) {
|
||||
|
||||
// Only run once
|
||||
browser.windows.onFocusChanged.removeListener(
|
||||
this.onWindowsFocusChanged);
|
||||
|
||||
browser.windows.remove(this.windowId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
export default new PopupReceiverSelectorManager();
|
||||
@@ -7,10 +7,11 @@ export interface Message {
|
||||
}
|
||||
|
||||
export interface Receiver {
|
||||
friendlyName: string;
|
||||
address: string;
|
||||
port: number;
|
||||
currentApp: string;
|
||||
friendlyName: string;
|
||||
id: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface DownloadDelta {
|
||||
|
||||
Reference in New Issue
Block a user