mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-11 18:19:58 +00:00
Add stop action to receiver selectors
This commit is contained in:
@@ -2,6 +2,7 @@ import Cocoa
|
||||
|
||||
protocol ReceiverViewDelegate : AnyObject {
|
||||
func didCast (_ receiver: Receiver)
|
||||
func didStop (_ receiver: Receiver)
|
||||
}
|
||||
|
||||
class ReceiverView : NSStackView {
|
||||
@@ -74,6 +75,23 @@ class ReceiverView : NSStackView {
|
||||
self.addArrangedSubview(self.castButton)
|
||||
|
||||
self.distribution = .fill
|
||||
|
||||
NSEvent.addLocalMonitorForEvents(
|
||||
matching: .flagsChanged) { event in
|
||||
|
||||
if !self.receiver.status.application.isIdleScreen &&
|
||||
event.modifierFlags.contains(.option) {
|
||||
self.castButton.title =
|
||||
InitDataProvider.shared.data.i18n_stopButtonTitle
|
||||
self.castButton.action = #selector(ReceiverView.onStop)
|
||||
} else {
|
||||
self.castButton.title =
|
||||
InitDataProvider.shared.data.i18n_castButtonTitle
|
||||
self.castButton.action = #selector(ReceiverView.onCast)
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
}
|
||||
|
||||
override func updateConstraints () {
|
||||
@@ -103,4 +121,9 @@ class ReceiverView : NSStackView {
|
||||
self.castingSpinner.isHidden = false
|
||||
self.castingSpinner.startAnimation(nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
func onStop () {
|
||||
self.receiverViewDelegate?.didStop(self.receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,4 +197,20 @@ extension ViewController : ReceiverViewDelegate {
|
||||
fatalError("Error: Failed to encode output data")
|
||||
}
|
||||
}
|
||||
|
||||
func didStop (_ receiver: Receiver) {
|
||||
// TODO: Use separate type and do proper JSON encoding
|
||||
let selection = ReceiverSelection(
|
||||
receiver: receiver
|
||||
, mediaType: nil
|
||||
, filePath: nil)
|
||||
|
||||
if let jsonData = try? JSONEncoder().encode(selection)
|
||||
, let jsonString = String(data: jsonData, encoding: .utf8) {
|
||||
print(jsonString)
|
||||
fflush(stdout)
|
||||
} else {
|
||||
fatalError("Error: Failed to encode output data")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct InitData : Decodable {
|
||||
|
||||
let i18n_extensionName: String
|
||||
let i18n_castButtonTitle: String
|
||||
let i18n_stopButtonTitle: String
|
||||
let i18n_mediaTypeApp: String
|
||||
let i18n_mediaTypeTab: String
|
||||
let i18n_mediaTypeScreen: String
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
struct ReceiverSelection : Codable {
|
||||
let receiver: Receiver
|
||||
let mediaType: MediaType
|
||||
let mediaType: MediaType?
|
||||
let filePath: String?
|
||||
}
|
||||
|
||||
@@ -6,13 +6,16 @@ import { Message
|
||||
, SendMessageCallback } from "./types";
|
||||
|
||||
|
||||
const NS_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
|
||||
const NS_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
|
||||
const NS_RECEIVER = "urn:x-cast:com.google.cast.receiver";
|
||||
export const NS_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
|
||||
export const NS_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
|
||||
export const NS_RECEIVER = "urn:x-cast:com.google.cast.receiver";
|
||||
|
||||
export default class Session {
|
||||
public channelMap = new Map<string, Channel>();
|
||||
|
||||
public host: string;
|
||||
public port: number;
|
||||
|
||||
private sendMessageCallback: SendMessageCallback;
|
||||
private sessionId: number;
|
||||
private referenceId: string;
|
||||
@@ -38,6 +41,9 @@ export default class Session {
|
||||
, referenceId: string
|
||||
, sendMessageCallback: SendMessageCallback) {
|
||||
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
this.sessionId = sessionId;
|
||||
this.referenceId = referenceId;
|
||||
this.sendMessageCallback = sendMessageCallback;
|
||||
@@ -176,6 +182,10 @@ export default class Session {
|
||||
}
|
||||
}
|
||||
|
||||
public stop () {
|
||||
this.clientConnection!.send({ type: "STOP" });
|
||||
}
|
||||
|
||||
private sendMessage (subject: string, data: any = {}) {
|
||||
this.sendMessageCallback({
|
||||
subject
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import { Channel, Client } from "castv2";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
const NS_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
|
||||
const NS_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
|
||||
const NS_RECEIVER = "urn:x-cast:com.google.cast.receiver";
|
||||
import { NS_CONNECTION
|
||||
, NS_HEARTBEAT
|
||||
, NS_RECEIVER } from "./Session";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,11 +16,16 @@ import { DecodeTransform
|
||||
|
||||
import { ReceiverStatus } from "./castTypes";
|
||||
|
||||
import { Message } from "./types";
|
||||
import { Message, Receiver } from "./types";
|
||||
|
||||
import { __applicationName
|
||||
, __applicationVersion } from "../../package.json";
|
||||
|
||||
import { Channel, Client } from "castv2";
|
||||
import { NS_CONNECTION
|
||||
, NS_HEARTBEAT
|
||||
, NS_RECEIVER } from "./Session";
|
||||
|
||||
|
||||
// Increase listener limit
|
||||
events.EventEmitter.defaultMaxListeners = 50;
|
||||
@@ -86,7 +91,9 @@ process.on("SIGTERM", () => {
|
||||
receiverSelectorApp.kill();
|
||||
}
|
||||
|
||||
browser.stop();
|
||||
if (browser) {
|
||||
browser.stop();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -175,6 +182,24 @@ async function handleMessage (message: Message) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "bridge:/stopReceiverApp": {
|
||||
const receiver: Receiver = message.data.receiver;
|
||||
const client = new Client();
|
||||
|
||||
client.connect({ host: receiver.host, port: receiver.port }, () => {
|
||||
const sourceId = "sender-0";
|
||||
const destinationId = "receiver-0";
|
||||
|
||||
const clientConnection = client.createChannel(
|
||||
sourceId, destinationId, NS_CONNECTION, "JSON");
|
||||
const clientReceiver = client.createChannel(
|
||||
sourceId, destinationId, NS_RECEIVER, "JSON");
|
||||
|
||||
clientConnection.send({ type: "CONNECT" });
|
||||
clientReceiver.send({ type: "STOP", requestId: 1 });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +240,13 @@ function handleReceiverSelectorMessage (message: Message) {
|
||||
|
||||
receiverSelectorApp.stdout!.setEncoding("utf8");
|
||||
receiverSelectorApp.stdout!.on("data", data => {
|
||||
const parsedData = JSON.parse(data);
|
||||
|
||||
sendMessage({
|
||||
subject: "main:/receiverSelector/selected"
|
||||
, data: JSON.parse(data)
|
||||
subject: !parsedData.mediaType
|
||||
? "main:/receiverSelector/stop"
|
||||
: "main:/receiverSelector/selected"
|
||||
, data: parsedData
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
import { ReceiverStatus } from "./castTypes";
|
||||
|
||||
export interface Message {
|
||||
subject: string;
|
||||
data?: any;
|
||||
_id?: string;
|
||||
}
|
||||
|
||||
export interface Receiver {
|
||||
host: string;
|
||||
friendlyName: string;
|
||||
id: string;
|
||||
port: number;
|
||||
status?: ReceiverStatus;
|
||||
}
|
||||
|
||||
export type SendMessageCallback = (message: Message) => void;
|
||||
|
||||
Reference in New Issue
Block a user