From ab00bcdd6a0f29ce78a22f1c9953d10757ead837 Mon Sep 17 00:00:00 2001 From: hensm Date: Wed, 26 May 2021 17:39:12 +0100 Subject: [PATCH] Remove native receiver selector --- app/bin/build.js | 29 -- app/bin/lib/paths.js | 1 - app/selector/mac/.gitignore | 4 - .../project.pbxproj | 374 ------------------ .../mac/fx_cast_selector/AppDelegate.swift | 18 - .../AppIcon.appiconset/Contents.json | 58 --- .../Assets.xcassets/Contents.json | 6 - .../Base.lproj/Main.storyboard | 206 ---------- app/selector/mac/fx_cast_selector/Info.plist | 32 -- .../fx_cast_selector/InitDataProvider.swift | 20 - .../mac/fx_cast_selector/ReceiverView.swift | 140 ------- .../mac/fx_cast_selector/ViewController.swift | 216 ---------- .../fx_cast_selector/WindowController.swift | 25 -- .../fx_cast_selector.entitlements | 10 - .../fx_cast_selector/models/InitData.swift | 21 - .../fx_cast_selector/models/MediaType.swift | 6 - .../fx_cast_selector/models/Receiver.swift | 23 -- .../models/ReceiverSelection.swift | 5 - app/selector/mac/fx_cast_selector/util.swift | 19 - .../NativeReceiverSelector.ts | 145 ------- .../receiverSelector/PopupReceiverSelector.ts | 250 ------------ .../receiverSelector/ReceiverSelector.ts | 264 +++++++++++-- .../ReceiverSelectorManager.ts | 17 +- ext/src/background/receiverSelector/index.ts | 35 +- ext/src/defaultOptions.ts | 1 - ext/src/lib/options.ts | 1 - ext/src/messaging.ts | 3 +- ext/src/ui/options/index.html | 15 + ext/src/ui/options/index.tsx | 39 -- ext/src/ui/popup/index.html | 15 + 30 files changed, 294 insertions(+), 1704 deletions(-) delete mode 100644 app/selector/mac/.gitignore delete mode 100644 app/selector/mac/fx_cast_selector.xcodeproj/project.pbxproj delete mode 100644 app/selector/mac/fx_cast_selector/AppDelegate.swift delete mode 100644 app/selector/mac/fx_cast_selector/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 app/selector/mac/fx_cast_selector/Assets.xcassets/Contents.json delete mode 100644 app/selector/mac/fx_cast_selector/Base.lproj/Main.storyboard delete mode 100644 app/selector/mac/fx_cast_selector/Info.plist delete mode 100644 app/selector/mac/fx_cast_selector/InitDataProvider.swift delete mode 100644 app/selector/mac/fx_cast_selector/ReceiverView.swift delete mode 100644 app/selector/mac/fx_cast_selector/ViewController.swift delete mode 100644 app/selector/mac/fx_cast_selector/WindowController.swift delete mode 100644 app/selector/mac/fx_cast_selector/fx_cast_selector.entitlements delete mode 100644 app/selector/mac/fx_cast_selector/models/InitData.swift delete mode 100644 app/selector/mac/fx_cast_selector/models/MediaType.swift delete mode 100644 app/selector/mac/fx_cast_selector/models/Receiver.swift delete mode 100644 app/selector/mac/fx_cast_selector/models/ReceiverSelection.swift delete mode 100644 app/selector/mac/fx_cast_selector/util.swift delete mode 100644 ext/src/background/receiverSelector/NativeReceiverSelector.ts delete mode 100644 ext/src/background/receiverSelector/PopupReceiverSelector.ts create mode 100644 ext/src/ui/options/index.html create mode 100644 ext/src/ui/popup/index.html diff --git a/app/bin/build.js b/app/bin/build.js index d6d35aa..16a4d8d 100644 --- a/app/bin/build.js +++ b/app/bin/build.js @@ -182,29 +182,6 @@ NODE_PATH="${modulesDir}" node $(dirname $0)/src/main.js --__name $(basename $0) fs.chmodSync(path.resolve(BUILD_PATH, file), 0o755); } - - // Build NativeMacReceiverSelector - if (process.platform === "darwin" && !argv.skipNativeBuilds) { - const selectorPath = path.join(__dirname, "../selector/mac/"); - const derivedDataPath = path.join(__dirname, "../selector/mac/build/"); - - spawnSync(` - xcodebuild -project ${selectorPath}/fx_cast_selector.xcodeproj \ - -configuration Release \ - -scheme fx_cast_selector \ - -derivedDataPath ${derivedDataPath} \ - build` - , spawnOptions); - - const selectorBundlePath = path.join(derivedDataPath - , "Build/Products/Release/", paths.SELECTOR_EXECUTABLE_NAME); - - fs.moveSync(selectorBundlePath - , path.join(BUILD_PATH, paths.SELECTOR_EXECUTABLE_NAME)); - fs.removeSync(derivedDataPath); - } - - /** * If packaging, create an installer package and move it to * dist, otherwise move the built executable and app manifest @@ -313,12 +290,6 @@ function packageDarwin ( fs.moveSync(path.join(BUILD_PATH, paths.MANIFEST_NAME) , path.join(rootManifestPath, paths.MANIFEST_NAME)); - if (process.platform === "darwin" && !argv.skipNativeBuilds) { - // Move selector executable alongside main executable - fs.moveSync(path.join(BUILD_PATH, paths.SELECTOR_EXECUTABLE_NAME) - , path.join(rootExecutablePath, paths.SELECTOR_EXECUTABLE_NAME)); - } - // Copy static files to be processed fs.copySync(packagingDir, packagingOutputDir); diff --git a/app/bin/lib/paths.js b/app/bin/lib/paths.js index a21430b..8daf6c6 100644 --- a/app/bin/lib/paths.js +++ b/app/bin/lib/paths.js @@ -21,7 +21,6 @@ exports.pkgPlatformMap = { }; exports.MANIFEST_NAME = `${__applicationName}.json`; -exports.SELECTOR_EXECUTABLE_NAME = "fx_cast_selector.app"; exports.getExecutableName = platform => { switch (platform) { diff --git a/app/selector/mac/.gitignore b/app/selector/mac/.gitignore deleted file mode 100644 index 0817d00..0000000 --- a/app/selector/mac/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore contents of xcodeproj, besides main project file -*.xcodeproj/* -!*.xcodeproj/project.pbxproj -build/ diff --git a/app/selector/mac/fx_cast_selector.xcodeproj/project.pbxproj b/app/selector/mac/fx_cast_selector.xcodeproj/project.pbxproj deleted file mode 100644 index 31f1c3d..0000000 --- a/app/selector/mac/fx_cast_selector.xcodeproj/project.pbxproj +++ /dev/null @@ -1,374 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - C9667DF32329C6900008D030 /* ReceiverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9667DF22329C68F0008D030 /* ReceiverView.swift */; }; - C9667DF52329C6A10008D030 /* util.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9667DF42329C6A10008D030 /* util.swift */; }; - C9EF71522314055C00EBDE93 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF71512314055C00EBDE93 /* AppDelegate.swift */; }; - C9EF71542314055C00EBDE93 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF71532314055C00EBDE93 /* ViewController.swift */; }; - C9EF71562314055E00EBDE93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C9EF71552314055E00EBDE93 /* Assets.xcassets */; }; - C9EF71592314055E00EBDE93 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9EF71572314055E00EBDE93 /* Main.storyboard */; }; - C9EF71622314062500EBDE93 /* InitDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF71612314062500EBDE93 /* InitDataProvider.swift */; }; - C9EF71682314075900EBDE93 /* InitData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF71672314075900EBDE93 /* InitData.swift */; }; - C9EF716A2314077E00EBDE93 /* MediaType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF71692314077E00EBDE93 /* MediaType.swift */; }; - C9EF716C2314079600EBDE93 /* Receiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF716B2314079600EBDE93 /* Receiver.swift */; }; - C9EF716E231407DC00EBDE93 /* ReceiverSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF716D231407DC00EBDE93 /* ReceiverSelection.swift */; }; - C9EF717023140B3800EBDE93 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EF716F23140B3800EBDE93 /* WindowController.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - C9667DF22329C68F0008D030 /* ReceiverView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiverView.swift; sourceTree = ""; }; - C9667DF42329C6A10008D030 /* util.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = util.swift; sourceTree = ""; }; - C9EF714E2314055C00EBDE93 /* fx_cast_selector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fx_cast_selector.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C9EF71512314055C00EBDE93 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - C9EF71532314055C00EBDE93 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - C9EF71552314055E00EBDE93 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C9EF71582314055E00EBDE93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - C9EF715A2314055E00EBDE93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C9EF715B2314055E00EBDE93 /* fx_cast_selector.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = fx_cast_selector.entitlements; sourceTree = ""; }; - C9EF71612314062500EBDE93 /* InitDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitDataProvider.swift; sourceTree = ""; }; - C9EF71672314075900EBDE93 /* InitData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitData.swift; sourceTree = ""; }; - C9EF71692314077E00EBDE93 /* MediaType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaType.swift; sourceTree = ""; }; - C9EF716B2314079600EBDE93 /* Receiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Receiver.swift; sourceTree = ""; }; - C9EF716D231407DC00EBDE93 /* ReceiverSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiverSelection.swift; sourceTree = ""; }; - C9EF716F23140B3800EBDE93 /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - C9EF714B2314055C00EBDE93 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - C9EF71452314055C00EBDE93 = { - isa = PBXGroup; - children = ( - C9EF71502314055C00EBDE93 /* fx_cast_selector */, - C9EF714F2314055C00EBDE93 /* Products */, - ); - sourceTree = ""; - }; - C9EF714F2314055C00EBDE93 /* Products */ = { - isa = PBXGroup; - children = ( - C9EF714E2314055C00EBDE93 /* fx_cast_selector.app */, - ); - name = Products; - sourceTree = ""; - }; - C9EF71502314055C00EBDE93 /* fx_cast_selector */ = { - isa = PBXGroup; - children = ( - C9EF71662314073800EBDE93 /* models */, - C9EF71612314062500EBDE93 /* InitDataProvider.swift */, - C9EF71512314055C00EBDE93 /* AppDelegate.swift */, - C9EF71532314055C00EBDE93 /* ViewController.swift */, - C9667DF22329C68F0008D030 /* ReceiverView.swift */, - C9667DF42329C6A10008D030 /* util.swift */, - C9EF716F23140B3800EBDE93 /* WindowController.swift */, - C9EF71552314055E00EBDE93 /* Assets.xcassets */, - C9EF71572314055E00EBDE93 /* Main.storyboard */, - C9EF715A2314055E00EBDE93 /* Info.plist */, - C9EF715B2314055E00EBDE93 /* fx_cast_selector.entitlements */, - ); - path = fx_cast_selector; - sourceTree = ""; - }; - C9EF71662314073800EBDE93 /* models */ = { - isa = PBXGroup; - children = ( - C9EF71672314075900EBDE93 /* InitData.swift */, - C9EF71692314077E00EBDE93 /* MediaType.swift */, - C9EF716B2314079600EBDE93 /* Receiver.swift */, - C9EF716D231407DC00EBDE93 /* ReceiverSelection.swift */, - ); - path = models; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - C9EF714D2314055C00EBDE93 /* fx_cast_selector */ = { - isa = PBXNativeTarget; - buildConfigurationList = C9EF715E2314055E00EBDE93 /* Build configuration list for PBXNativeTarget "fx_cast_selector" */; - buildPhases = ( - C9EF714A2314055C00EBDE93 /* Sources */, - C9EF714B2314055C00EBDE93 /* Frameworks */, - C9EF714C2314055C00EBDE93 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = fx_cast_selector; - productName = fx_cast_selector; - productReference = C9EF714E2314055C00EBDE93 /* fx_cast_selector.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - C9EF71462314055C00EBDE93 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1030; - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = "Matt Hensman"; - TargetAttributes = { - C9EF714D2314055C00EBDE93 = { - CreatedOnToolsVersion = 10.3; - }; - }; - }; - buildConfigurationList = C9EF71492314055C00EBDE93 /* Build configuration list for PBXProject "fx_cast_selector" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = C9EF71452314055C00EBDE93; - productRefGroup = C9EF714F2314055C00EBDE93 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - C9EF714D2314055C00EBDE93 /* fx_cast_selector */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - C9EF714C2314055C00EBDE93 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C9EF71562314055E00EBDE93 /* Assets.xcassets in Resources */, - C9EF71592314055E00EBDE93 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - C9EF714A2314055C00EBDE93 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C9EF716A2314077E00EBDE93 /* MediaType.swift in Sources */, - C9EF716C2314079600EBDE93 /* Receiver.swift in Sources */, - C9EF71622314062500EBDE93 /* InitDataProvider.swift in Sources */, - C9667DF52329C6A10008D030 /* util.swift in Sources */, - C9EF71542314055C00EBDE93 /* ViewController.swift in Sources */, - C9EF71682314075900EBDE93 /* InitData.swift in Sources */, - C9EF717023140B3800EBDE93 /* WindowController.swift in Sources */, - C9EF716E231407DC00EBDE93 /* ReceiverSelection.swift in Sources */, - C9667DF32329C6900008D030 /* ReceiverView.swift in Sources */, - C9EF71522314055C00EBDE93 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - C9EF71572314055E00EBDE93 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - C9EF71582314055E00EBDE93 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - C9EF715C2314055E00EBDE93 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - C9EF715D2314055E00EBDE93 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - C9EF715F2314055E00EBDE93 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = fx_cast_selector/fx_cast_selector.entitlements; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 7NS3H2Z7RF; - INFOPLIST_FILE = fx_cast_selector/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "tf.matt.fx-cast-selector"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - C9EF71602314055E00EBDE93 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = fx_cast_selector/fx_cast_selector.entitlements; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 7NS3H2Z7RF; - INFOPLIST_FILE = fx_cast_selector/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "tf.matt.fx-cast-selector"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C9EF71492314055C00EBDE93 /* Build configuration list for PBXProject "fx_cast_selector" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C9EF715C2314055E00EBDE93 /* Debug */, - C9EF715D2314055E00EBDE93 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C9EF715E2314055E00EBDE93 /* Build configuration list for PBXNativeTarget "fx_cast_selector" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C9EF715F2314055E00EBDE93 /* Debug */, - C9EF71602314055E00EBDE93 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = C9EF71462314055C00EBDE93 /* Project object */; -} diff --git a/app/selector/mac/fx_cast_selector/AppDelegate.swift b/app/selector/mac/fx_cast_selector/AppDelegate.swift deleted file mode 100644 index 6cc3a2e..0000000 --- a/app/selector/mac/fx_cast_selector/AppDelegate.swift +++ /dev/null @@ -1,18 +0,0 @@ -import Cocoa - -@NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate { - weak var mainWindow: NSWindow! - - func applicationDidResignActive (_ aNotification: Notification) { - if InitDataProvider.shared.data.closeIfFocusLost { - self.mainWindow?.performClose(aNotification) - } - } - - func applicationShouldTerminateAfterLastWindowClosed( - _ sender: NSApplication) -> Bool { - return true - } -} - diff --git a/app/selector/mac/fx_cast_selector/Assets.xcassets/AppIcon.appiconset/Contents.json b/app/selector/mac/fx_cast_selector/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 2db2b1c..0000000 --- a/app/selector/mac/fx_cast_selector/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "images" : [ - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/app/selector/mac/fx_cast_selector/Assets.xcassets/Contents.json b/app/selector/mac/fx_cast_selector/Assets.xcassets/Contents.json deleted file mode 100644 index da4a164..0000000 --- a/app/selector/mac/fx_cast_selector/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/app/selector/mac/fx_cast_selector/Base.lproj/Main.storyboard b/app/selector/mac/fx_cast_selector/Base.lproj/Main.storyboard deleted file mode 100644 index f778058..0000000 --- a/app/selector/mac/fx_cast_selector/Base.lproj/Main.storyboard +++ /dev/null @@ -1,206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/selector/mac/fx_cast_selector/Info.plist b/app/selector/mac/fx_cast_selector/Info.plist deleted file mode 100644 index 24b2272..0000000 --- a/app/selector/mac/fx_cast_selector/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.0.2 - CFBundleVersion - 1 - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - Copyright © 2019 Matt Hensman. All rights reserved. - NSMainStoryboardFile - Main - NSPrincipalClass - NSApplication - - diff --git a/app/selector/mac/fx_cast_selector/InitDataProvider.swift b/app/selector/mac/fx_cast_selector/InitDataProvider.swift deleted file mode 100644 index 4034edf..0000000 --- a/app/selector/mac/fx_cast_selector/InitDataProvider.swift +++ /dev/null @@ -1,20 +0,0 @@ -import Cocoa - -class InitDataProvider { - static let shared = InitDataProvider() - - let data: InitData - - private init() { - if CommandLine.argc < 2 { - fatalError("Missing init data") - } - - if let input = CommandLine.arguments[1].data(using: .utf8) - , let parsed = try? JSONDecoder().decode(InitData.self, from: input) { - self.data = parsed - } else { - fatalError("Failed to convert and parse init data") - } - } -} diff --git a/app/selector/mac/fx_cast_selector/ReceiverView.swift b/app/selector/mac/fx_cast_selector/ReceiverView.swift deleted file mode 100644 index 3176aa4..0000000 --- a/app/selector/mac/fx_cast_selector/ReceiverView.swift +++ /dev/null @@ -1,140 +0,0 @@ -import Cocoa - -protocol ReceiverViewDelegate : AnyObject { - func didCast (_ receiver: Receiver) - func didStop (_ receiver: Receiver) -} - -class ReceiverView : NSStackView { - weak var receiverViewDelegate: ReceiverViewDelegate? - - var receiver: Receiver! - var constraintsSet = false - - var castButton: NSButton! - var castingSpinner: NSProgressIndicator! - - var isEnabled: Bool { - get { return self.castButton.isEnabled } - set { self.castButton.isEnabled = newValue } - } - - override init (frame: CGRect) { - super.init(frame: frame) - } - required init? (coder: NSCoder) { - super.init(coder: coder) - } - - init (receiver: Receiver) { - super.init(frame: NSZeroRect) - - self.receiver = receiver - - - let statusText = receiver.status.application.isIdleScreen - ? "\(receiver.host):\(receiver.port)" - : receiver.status.application.statusText - - let addressLabel = makeLabel(statusText - , size: NSFont.smallSystemFontSize - , color: .secondaryLabelColor) - - // Truncate long status text - addressLabel.toolTip = statusText - addressLabel.cell?.lineBreakMode = .byTruncatingTail - addressLabel.setContentCompressionResistancePriority( - .defaultLow, for: .horizontal) - - let metaStackView = NSStackView(views: [ - makeLabel(receiver.friendlyName, size: 14) - , addressLabel - ]) - - metaStackView.alignment = .leading - metaStackView.orientation = .vertical - metaStackView.spacing = 4 - - - self.castButton = NSButton( - title: InitDataProvider.shared.data.i18n_castButtonTitle - , target: self - , action: #selector(ReceiverView.onCast)) - - self.castButton.bezelStyle = .rounded - self.castButton.widthAnchor.constraint( - equalToConstant: 100).isActive = true - - self.castingSpinner = NSProgressIndicator() - self.castingSpinner.style = .spinning - self.castingSpinner.controlSize = .small - self.castingSpinner.isHidden = true - - self.addArrangedSubview(metaStackView) - self.addArrangedSubview(self.castingSpinner) - self.addArrangedSubview(self.castButton) - - self.distribution = .fill - - - var wasDisabled = false - - NSEvent.addLocalMonitorForEvents( - matching: .flagsChanged) { event in - - if wasDisabled { - self.castButton.isEnabled = false - } - - if event.modifierFlags.contains(.option) { - self.castButton.title = - InitDataProvider.shared.data.i18n_stopButtonTitle - self.castButton.action = #selector(ReceiverView.onStop) - if !self.castButton.isEnabled { - self.castButton.isEnabled = - !self.receiver.status.application.isIdleScreen - wasDisabled = self.castButton.isEnabled - } - } else { - self.castButton.title = - InitDataProvider.shared.data.i18n_castButtonTitle - self.castButton.action = #selector(ReceiverView.onCast) - } - - return event - } - } - - override func updateConstraints () { - super.updateConstraints() - - if !constraintsSet { - self.translatesAutoresizingMaskIntoConstraints = false - - if let superview = self.superview { - self.leadingAnchor.constraint( - equalTo: superview.leadingAnchor - , constant: 8).isActive = true - self.trailingAnchor.constraint( - equalTo: superview.trailingAnchor - , constant: -8).isActive = true - } - - constraintsSet = true - } - } - - - @objc - func onCast () { - self.receiverViewDelegate?.didCast(self.receiver) - - self.castingSpinner.isHidden = false - self.castingSpinner.startAnimation(nil) - } - - @objc - func onStop () { - self.receiverViewDelegate?.didStop(self.receiver); - } -} diff --git a/app/selector/mac/fx_cast_selector/ViewController.swift b/app/selector/mac/fx_cast_selector/ViewController.swift deleted file mode 100644 index 8a36c56..0000000 --- a/app/selector/mac/fx_cast_selector/ViewController.swift +++ /dev/null @@ -1,216 +0,0 @@ -import Cocoa - -class ViewController: NSViewController { - @IBOutlet weak var labelCast: NSTextField! - @IBOutlet weak var labelTo: NSTextField! - @IBOutlet weak var mediaTypePopUpButton: NSPopUpButton! - - @IBOutlet weak var mainStackView: NSStackView! - - - var receiverViews = [ReceiverView]() - var filePath: String? - - override func viewDidLoad() { - super.viewDidLoad() - - let initData = InitDataProvider.shared.data - - self.mediaTypePopUpButton.addItems(withTitles: [ - initData.i18n_mediaTypeApp - , initData.i18n_mediaTypeTab - , initData.i18n_mediaTypeScreen - , initData.i18n_mediaTypeFile - ]) - - if let appItem = self.mediaTypePopUpButton - .item(withTitle: initData.i18n_mediaTypeApp) - , let tabItem = self.mediaTypePopUpButton - .item(withTitle: initData.i18n_mediaTypeTab) - , let screenItem = self.mediaTypePopUpButton - .item(withTitle: initData.i18n_mediaTypeScreen) - , let fileItem = self.mediaTypePopUpButton - .item(withTitle: initData.i18n_mediaTypeFile) { - - if let menu = self.mediaTypePopUpButton.menu { - menu.delegate = self - menu.insertItem(NSMenuItem.separator() - , at: self.mediaTypePopUpButton.index(of: fileItem)) - } - - appItem.tag = MediaType.app.rawValue - tabItem.tag = MediaType.tab.rawValue - screenItem.tag = MediaType.screen.rawValue - fileItem.tag = MediaType.file.rawValue - } - - for item in self.mediaTypePopUpButton.itemArray { - if (initData.availableMediaTypes & item.tag) == 0 { - item.isEnabled = false - } - } - - self.mediaTypePopUpButton.selectItem( - withTag: initData.defaultMediaType.rawValue) - - if initData.i18n_mediaSelectCastLabel != "" { - labelCast.stringValue = initData.i18n_mediaSelectCastLabel - labelCast.isHidden = false - } - if initData.i18n_mediaSelectToLabel != "" { - labelTo.stringValue = initData.i18n_mediaSelectToLabel - labelTo.isHidden = false - } - - if initData.receivers.count == 0 { - let separator = NSBox() - separator.boxType = .separator - - let notFoundPlaceholder = NSStackView(views: [ - makeLabel(initData.i18n_noReceiversFound) - ]) - - notFoundPlaceholder.alignment = .centerX - notFoundPlaceholder.edgeInsets = NSEdgeInsetsMake(18, 0, 18, 0) - - self.mainStackView.addArrangedSubview(separator) - self.mainStackView.addArrangedSubview(notFoundPlaceholder) - } else { - for receiver in initData.receivers { - let receiverSeparator = NSBox() - receiverSeparator.boxType = .separator - - let receiverView = ReceiverView(receiver: receiver) - receiverView.receiverViewDelegate = self - - if UInt(initData.availableMediaTypes) == 0 - || (initData.availableMediaTypes - & initData.defaultMediaType.rawValue) == 0 { - receiverView.isEnabled = false - } - - self.receiverViews.append(receiverView) - - self.mainStackView.addArrangedSubview(receiverSeparator) - self.mainStackView.addArrangedSubview(receiverView) - } - } - - self.view.frame.size.height = 0 - self.view.frame.size.width = 350 - } -} - -extension ViewController: NSMenuDelegate { - func menuDidClose (_ menu: NSMenu) { - let initData = InitDataProvider.shared.data - - guard let selectedItem = self.mediaTypePopUpButton.selectedItem - , let mediaType = MediaType(rawValue: selectedItem.tag) else { - return - } - - if initData.availableMediaTypes & mediaType.rawValue != 0 { - for receiverView in self.receiverViews { - receiverView.isEnabled = true - } - } - - guard let fileItem = self.mediaTypePopUpButton - .item(at: self.mediaTypePopUpButton.indexOfItem( - withTag: MediaType.file.rawValue)) else { - return - } - - if (mediaType == .file) { - let panel = NSOpenPanel() - panel.allowsMultipleSelection = false - panel.allowedFileTypes = [ "aac", "mp3", "mp4", "wav", "webm" ] - panel.canChooseDirectories = false - panel.canCreateDirectories = false - panel.canChooseFiles = true - - guard let window = self.view.window else { return } - - panel.beginSheetModal(for: window) { (result) in - if (result == .OK) { - let url = panel.urls[0] - let fileName = url.lastPathComponent - - // Truncate file name and set as title - fileItem.title = fileName.count > 12 - ? "\(fileName.prefix(12))..." - : fileName - - self.filePath = url.path - - return - } else { - // Re-select the default media type item - self.mediaTypePopUpButton.selectItem( - withTag: initData.defaultMediaType.rawValue) - - let defaultMediaTypeAvailable = initData.availableMediaTypes - & initData.defaultMediaType.rawValue != 0 - - for receiverView in self.receiverViews { - receiverView.isEnabled = defaultMediaTypeAvailable - } - } - } - } - - - // Reset file item - fileItem.title = initData.i18n_mediaTypeFile - self.filePath = nil - } -} - -extension ViewController : ReceiverViewDelegate { - func didCast (_ receiver: Receiver) { - - // Disable media type UI - self.mediaTypePopUpButton.isEnabled = false - - // Disable cast buttons - for receiverView in self.receiverViews { - receiverView.isEnabled = false - } - - - guard let selectedItem = self.mediaTypePopUpButton.selectedItem - , let mediaType = MediaType(rawValue: selectedItem.tag) else { - return - } - - let selection = ReceiverSelection( - receiver: receiver - , mediaType: mediaType - , filePath: self.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") - } - } - - 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") - } - } -} diff --git a/app/selector/mac/fx_cast_selector/WindowController.swift b/app/selector/mac/fx_cast_selector/WindowController.swift deleted file mode 100644 index 554f8d9..0000000 --- a/app/selector/mac/fx_cast_selector/WindowController.swift +++ /dev/null @@ -1,25 +0,0 @@ -import Cocoa - -class WindowController: NSWindowController { - override func windowDidLoad() { - super.windowDidLoad() - - if let appDelegate = NSApplication.shared.delegate as? AppDelegate { - appDelegate.mainWindow = self.window - } - - if let window = self.window - , let screen = window.screen { - let windowX = InitDataProvider.shared.data.windowPositionX - let windowY = Int(screen.frame.height - CGFloat( - InitDataProvider.shared.data.windowPositionY)) - - window.setFrameTopLeftPoint(NSPoint(x: windowX, y: windowY)) - - window.title = InitDataProvider.shared.data.i18n_extensionName - window.titleVisibility = .visible - - NSApp.activate(ignoringOtherApps: true) - } - } -} diff --git a/app/selector/mac/fx_cast_selector/fx_cast_selector.entitlements b/app/selector/mac/fx_cast_selector/fx_cast_selector.entitlements deleted file mode 100644 index f2ef3ae..0000000 --- a/app/selector/mac/fx_cast_selector/fx_cast_selector.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - - - diff --git a/app/selector/mac/fx_cast_selector/models/InitData.swift b/app/selector/mac/fx_cast_selector/models/InitData.swift deleted file mode 100644 index c643918..0000000 --- a/app/selector/mac/fx_cast_selector/models/InitData.swift +++ /dev/null @@ -1,21 +0,0 @@ -struct InitData : Decodable { - let receivers: [Receiver] - let defaultMediaType: MediaType - let availableMediaTypes: Int - - let closeIfFocusLost: Bool - - let windowPositionX: Int - let windowPositionY: Int - - let i18n_extensionName: String - let i18n_castButtonTitle: String - let i18n_stopButtonTitle: String - let i18n_mediaTypeApp: String - let i18n_mediaTypeTab: String - let i18n_mediaTypeScreen: String - let i18n_mediaTypeFile: String - let i18n_mediaSelectCastLabel: String - let i18n_mediaSelectToLabel: String - let i18n_noReceiversFound: String -} diff --git a/app/selector/mac/fx_cast_selector/models/MediaType.swift b/app/selector/mac/fx_cast_selector/models/MediaType.swift deleted file mode 100644 index 7bb6ba5..0000000 --- a/app/selector/mac/fx_cast_selector/models/MediaType.swift +++ /dev/null @@ -1,6 +0,0 @@ -enum MediaType: Int, Codable { - case app = 1 - case tab = 2 - case screen = 4 - case file = 8 -} diff --git a/app/selector/mac/fx_cast_selector/models/Receiver.swift b/app/selector/mac/fx_cast_selector/models/Receiver.swift deleted file mode 100644 index 3de9c68..0000000 --- a/app/selector/mac/fx_cast_selector/models/Receiver.swift +++ /dev/null @@ -1,23 +0,0 @@ -struct Receiver : Codable { - struct Status: Codable { - struct Application: Codable { - let displayName: String - let isIdleScreen: Bool - let statusText: String - } - - struct Volume: Codable { - let level: Double - let muted: Bool - } - - let application: Application - let volume: Volume - } - - let friendlyName: String - let host: String - let id: String - let port: Int - let status: Status -} diff --git a/app/selector/mac/fx_cast_selector/models/ReceiverSelection.swift b/app/selector/mac/fx_cast_selector/models/ReceiverSelection.swift deleted file mode 100644 index e672f02..0000000 --- a/app/selector/mac/fx_cast_selector/models/ReceiverSelection.swift +++ /dev/null @@ -1,5 +0,0 @@ -struct ReceiverSelection : Codable { - let receiver: Receiver - let mediaType: MediaType? - let filePath: String? -} diff --git a/app/selector/mac/fx_cast_selector/util.swift b/app/selector/mac/fx_cast_selector/util.swift deleted file mode 100644 index e2bdda8..0000000 --- a/app/selector/mac/fx_cast_selector/util.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Cocoa - -func makeLabel(_ text: String, - size: CGFloat = 0, - color: NSColor = NSColor.textColor) -> NSTextField { - - let textField = NSTextField() - textField.stringValue = text - textField.backgroundColor = .clear - textField.isEditable = false - textField.isBezeled = false - textField.sizeToFit() - - // Text - textField.font = NSFont.systemFont(ofSize: size) - textField.textColor = color - - return textField -} diff --git a/ext/src/background/receiverSelector/NativeReceiverSelector.ts b/ext/src/background/receiverSelector/NativeReceiverSelector.ts deleted file mode 100644 index 7e91364..0000000 --- a/ext/src/background/receiverSelector/NativeReceiverSelector.ts +++ /dev/null @@ -1,145 +0,0 @@ -"use strict"; - -import bridge from "../../lib/bridge"; -import knownApps from "../../lib/knownApps"; -import logger from "../../lib/logger"; -import { Message, Port } from "../../messaging"; -import options from "../../lib/options"; - -import { TypedEventTarget } from "../../lib/TypedEventTarget"; -import { getWindowCenteredProps } from "../../lib/utils"; -import { ReceiverDevice } from "../../types"; - -import ReceiverSelector, { - ReceiverSelection - , ReceiverSelectorMediaType } from "./ReceiverSelector"; - - -const _ = browser.i18n.getMessage; - -// TODO: Figure out lifetime properly -export default class NativeReceiverSelector extends ReceiverSelector { - private bridgePort: (Port | null) = null; - private wasReceiverSelected = false; - - #isOpen = false; - - constructor() { - super(); - this.onBridgePortMessage = this.onBridgePortMessage.bind(this); - } - - get isOpen() { - return this.#isOpen; - } - - public async open( - receivers: ReceiverDevice[] - , defaultMediaType: ReceiverSelectorMediaType - , availableMediaTypes: ReceiverSelectorMediaType - , appId?: string): Promise { - - this.bridgePort = await bridge.connect(); - - this.bridgePort.onMessage.addListener(this.onBridgePortMessage); - this.bridgePort.onDisconnect.addListener(() => { - this.bridgePort = null; - this.wasReceiverSelected = false; - this.#isOpen = false; - }); - - - // Current window to base centered position on - const openerWindow = await browser.windows.getCurrent(); - const centeredProps = getWindowCenteredProps(openerWindow, 350, 0); - - const closeIfFocusLost = await options.get( - "receiverSelectorCloseIfFocusLost"); - - this.bridgePort.postMessage({ - subject: "bridge:openReceiverSelector" - , data: JSON.stringify({ - receivers - , defaultMediaType - , availableMediaTypes - - , closeIfFocusLost - - , windowPositionX: centeredProps.left - , windowPositionY: centeredProps.top - - , i18n_extensionName: _("extensionName") - , i18n_castButtonTitle: _("popupCastButtonTitle") - , i18n_stopButtonTitle: _("popupStopButtonTitle") - , i18n_mediaTypeApp: - (appId && knownApps[appId]?.name) - ?? _("popupMediaTypeApp") - , i18n_mediaTypeTab: _("popupMediaTypeTab") - , i18n_mediaTypeScreen: _("popupMediaTypeScreen") - , i18n_mediaTypeFile: _("popupMediaTypeFile") - , i18n_mediaSelectCastLabel: _("popupMediaSelectCastLabel") - , i18n_mediaSelectToLabel: _("popupMediaSelectToLabel") - , i18n_noReceiversFound: _("popupNoReceiversFound") - }) - }); - - this.#isOpen = true; - } - - public update(): void { - // TODO: Implement this - } - - public close(): void { - if (this.bridgePort) { - this.bridgePort.postMessage({ - subject: "bridge:closeReceiverSelector" - }); - } - - this.#isOpen = false; - } - - private async onBridgePortMessage(message: Message) { - switch (message.subject) { - case "main:receiverSelector/selected": { - this.wasReceiverSelected = true; - this.dispatchEvent(new CustomEvent("selected", { - detail: message.data - })); - - if (!(await options.get("receiverSelectorWaitForConnection"))) { - this.close(); - } - - break; - } - case "main:receiverSelector/cancelled": { - if (!this.wasReceiverSelected) { - this.dispatchEvent(new CustomEvent("cancelled")); - } - - if (this.bridgePort) { - this.bridgePort.disconnect(); - } - - this.bridgePort = null; - this.wasReceiverSelected = false; - this.#isOpen = false; - - break; - } - case "main:receiverSelector/stopped": { - this.dispatchEvent(new CustomEvent("stop", { - detail: message.data - })); - break; - } - case "main:receiverSelector/error": { - logger.error("Native receiver selector error", message.data); - this.dispatchEvent(new CustomEvent("error")); - break; - } - } - } -} diff --git a/ext/src/background/receiverSelector/PopupReceiverSelector.ts b/ext/src/background/receiverSelector/PopupReceiverSelector.ts deleted file mode 100644 index 47a2bde..0000000 --- a/ext/src/background/receiverSelector/PopupReceiverSelector.ts +++ /dev/null @@ -1,250 +0,0 @@ -"use strict"; - -import ReceiverSelector, { - ReceiverSelectorMediaType } from "./ReceiverSelector"; - -import logger from "../../lib/logger"; -import messaging, { Port, Message } from "../../messaging"; -import options from "../../lib/options"; - -import { TypedEventTarget } from "../../lib/TypedEventTarget"; -import { getWindowCenteredProps, WindowCenteredProps } from "../../lib/utils"; -import { ReceiverDevice } from "../../types"; - - -const POPUP_URL = browser.runtime.getURL("ui/popup/index.html"); - -export default class PopupReceiverSelector extends ReceiverSelector { - private windowId?: number; - - private messagePort?: Port; - private messagePortDisconnected?: boolean; - - private receivers?: ReceiverDevice[]; - private defaultMediaType?: ReceiverSelectorMediaType; - private availableMediaTypes?: ReceiverSelectorMediaType; - - private wasReceiverSelected = false; - - private appId?: string; - - #isOpen = false; - - constructor() { - super(); - - // Bind methods to pass to addListener - this.onConnect = this.onConnect.bind(this); - 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. - */ - messaging.onConnect.addListener(this.onConnect); - } - - get isOpen() { - return this.#isOpen; - } - - public async open( - receivers: ReceiverDevice[] - , defaultMediaType: ReceiverSelectorMediaType - , availableMediaTypes: ReceiverSelectorMediaType - , appId?: string): Promise { - - this.appId = appId; - - // If popup already exists, close it - if (this.windowId) { - await browser.windows.remove(this.windowId); - } - - this.receivers = receivers; - this.defaultMediaType = defaultMediaType; - this.availableMediaTypes = availableMediaTypes; - - - let centeredProps: WindowCenteredProps = { - left: 100 - , top: 100 - , width: 350 - , height: 200 - }; - - try { - // Calculate centered size/position based on current window - centeredProps = getWindowCenteredProps( - await browser.windows.getCurrent() - , centeredProps.width, centeredProps.height); - } catch { - // Shouldn't ever hit this, but defaults are provided in case - } - - const popup = await browser.windows.create({ - url: POPUP_URL - , type: "popup" - , ...centeredProps - }); - - if (popup?.id === undefined) { - throw logger.error("Failed to create receiver selector popup."); - } - - this.#isOpen = true; - this.windowId = popup.id; - - // Size/position not set correctly on creation (bug?) - await browser.windows.update(this.windowId, { - ...centeredProps - }); - - - const closeIfFocusLost = await options.get( - "receiverSelectorCloseIfFocusLost"); - - if (closeIfFocusLost) { - // Add focus listener - browser.windows.onFocusChanged.addListener( - this.onWindowsFocusChanged); - } - } - - public update(receivers: ReceiverDevice[]) { - this.receivers = receivers; - this.messagePort?.postMessage({ - subject: "popup:update" - , data: { - receivers: this.receivers - } - }); - } - - public async close(): Promise { - if (this.windowId) { - await browser.windows.remove(this.windowId); - } - - this.#isOpen = false; - this.appId = undefined; - - if (this.messagePort && !this.messagePortDisconnected) { - this.messagePort.disconnect(); - } - } - - private onConnect(port: Port) { - browser.history.deleteUrl({ url: POPUP_URL }); - - if (port.name !== "popup") { - return; - } - - if (this.messagePort) { - this.messagePort.disconnect(); - } - - this.messagePort = port; - this.messagePort.onMessage.addListener(this.onPopupMessage); - this.messagePort.onDisconnect.addListener(() => { - this.messagePortDisconnected = true; - }); - - if (!this.receivers - || !this.defaultMediaType - || !this.availableMediaTypes) { - throw logger.error("Popup receiver data not found."); - } - - this.messagePort.postMessage({ - subject: "popup:init" - , data: { appId: this.appId } - }); - - this.messagePort.postMessage({ - subject: "popup:update" - , data: { - receivers: this.receivers - , defaultMediaType: this.defaultMediaType - , availableMediaTypes: this.availableMediaTypes - } - }); - - messaging.onConnect.removeListener(this.onConnect); - } - - /** - * Handles popup messages. - */ - private onPopupMessage(message: Message) { - switch (message.subject) { - case "receiverSelector:selected": { - this.wasReceiverSelected = true; - this.dispatchEvent(new CustomEvent("selected", { - detail: message.data - })); - - break; - } - - case "receiverSelector:stop": { - this.dispatchEvent(new CustomEvent("stop", { - detail: message.data - })); - - 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.onRemoved.removeListener(this.onWindowsRemoved); - browser.windows.onFocusChanged.removeListener( - this.onWindowsFocusChanged); - - if (!this.wasReceiverSelected) { - this.dispatchEvent(new CustomEvent("cancelled")); - } - - // Cleanup - this.windowId = undefined; - this.messagePort = undefined; - this.receivers = undefined; - this.defaultMediaType = undefined; - this.availableMediaTypes = undefined; - 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); - - if (this.windowId) { - browser.windows.remove(this.windowId); - } - } - } -} diff --git a/ext/src/background/receiverSelector/ReceiverSelector.ts b/ext/src/background/receiverSelector/ReceiverSelector.ts index 98a5eeb..1c2cde8 100644 --- a/ext/src/background/receiverSelector/ReceiverSelector.ts +++ b/ext/src/background/receiverSelector/ReceiverSelector.ts @@ -1,33 +1,20 @@ "use strict"; +import logger from "../../lib/logger"; +import messaging, { Port, Message } from "../../messaging"; +import options from "../../lib/options"; + import { TypedEventTarget } from "../../lib/TypedEventTarget"; +import { getWindowCenteredProps, WindowCenteredProps } from "../../lib/utils"; import { ReceiverDevice } from "../../types"; +import { ReceiverSelectionCast + , ReceiverSelectionStop + , ReceiverSelectorMediaType } from "./index"; -export enum ReceiverSelectorMediaType { - App = 1 - , Tab = 2 - , Screen = 4 - , File = 8 -} -export enum ReceiverSelectionActionType { - Cast = 1 - , Stop = 2 -} -export interface ReceiverSelectionCast { - actionType: ReceiverSelectionActionType.Cast; - receiver: ReceiverDevice; - mediaType: ReceiverSelectorMediaType; - filePath?: string; -} -export interface ReceiverSelectionStop { - actionType: ReceiverSelectionActionType.Stop; - receiver: ReceiverDevice; -} - -export type ReceiverSelection = ReceiverSelectionCast | ReceiverSelectionStop; +const POPUP_URL = browser.runtime.getURL("ui/popup/index.html"); interface ReceiverSelectorEvents { @@ -37,18 +24,239 @@ interface ReceiverSelectorEvents { "stop": ReceiverSelectionStop; } -export default abstract class ReceiverSelector +export default class ReceiverSelector extends TypedEventTarget { - abstract readonly isOpen: boolean; + private windowId?: number; - abstract open ( + private messagePort?: Port; + private messagePortDisconnected?: boolean; + + private receivers?: ReceiverDevice[]; + private defaultMediaType?: ReceiverSelectorMediaType; + private availableMediaTypes?: ReceiverSelectorMediaType; + + private wasReceiverSelected = false; + + private appId?: string; + + #isOpen = false; + + constructor() { + super(); + + // Bind methods to pass to addListener + this.onConnect = this.onConnect.bind(this); + 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. + */ + messaging.onConnect.addListener(this.onConnect); + } + + get isOpen() { + return this.#isOpen; + } + + public async open( receivers: ReceiverDevice[] , defaultMediaType: ReceiverSelectorMediaType , availableMediaTypes: ReceiverSelectorMediaType - , appId?: string): void; + , appId?: string): Promise { - abstract update (receivers: ReceiverDevice[]): void; + this.appId = appId; - abstract close (): void; + // If popup already exists, close it + if (this.windowId) { + await browser.windows.remove(this.windowId); + } + + this.receivers = receivers; + this.defaultMediaType = defaultMediaType; + this.availableMediaTypes = availableMediaTypes; + + + let centeredProps: WindowCenteredProps = { + left: 100 + , top: 100 + , width: 350 + , height: 200 + }; + + try { + // Calculate centered size/position based on current window + centeredProps = getWindowCenteredProps( + await browser.windows.getCurrent() + , centeredProps.width, centeredProps.height); + } catch { + // Shouldn't ever hit this, but defaults are provided in case + } + + const popup = await browser.windows.create({ + url: POPUP_URL + , type: "popup" + , ...centeredProps + }); + + if (popup?.id === undefined) { + throw logger.error("Failed to create receiver selector popup."); + } + + this.#isOpen = true; + this.windowId = popup.id; + + // Size/position not set correctly on creation (bug?) + await browser.windows.update(this.windowId, { + ...centeredProps + }); + + + const closeIfFocusLost = await options.get( + "receiverSelectorCloseIfFocusLost"); + + if (closeIfFocusLost) { + // Add focus listener + browser.windows.onFocusChanged.addListener( + this.onWindowsFocusChanged); + } + } + + public update(receivers: ReceiverDevice[]) { + this.receivers = receivers; + this.messagePort?.postMessage({ + subject: "popup:update" + , data: { + receivers: this.receivers + } + }); + } + + public async close(): Promise { + if (this.windowId) { + await browser.windows.remove(this.windowId); + } + + this.#isOpen = false; + this.appId = undefined; + + if (this.messagePort && !this.messagePortDisconnected) { + this.messagePort.disconnect(); + } + } + + private onConnect(port: Port) { + browser.history.deleteUrl({ url: POPUP_URL }); + + if (port.name !== "popup") { + return; + } + + if (this.messagePort) { + this.messagePort.disconnect(); + } + + this.messagePort = port; + this.messagePort.onMessage.addListener(this.onPopupMessage); + this.messagePort.onDisconnect.addListener(() => { + this.messagePortDisconnected = true; + }); + + if (!this.receivers + || !this.defaultMediaType + || !this.availableMediaTypes) { + throw logger.error("Popup receiver data not found."); + } + + this.messagePort.postMessage({ + subject: "popup:init" + , data: { appId: this.appId } + }); + + this.messagePort.postMessage({ + subject: "popup:update" + , data: { + receivers: this.receivers + , defaultMediaType: this.defaultMediaType + , availableMediaTypes: this.availableMediaTypes + } + }); + + messaging.onConnect.removeListener(this.onConnect); + } + + /** + * Handles popup messages. + */ + private onPopupMessage(message: Message) { + switch (message.subject) { + case "receiverSelector:selected": { + this.wasReceiverSelected = true; + this.dispatchEvent(new CustomEvent("selected", { + detail: message.data + })); + + break; + } + + case "receiverSelector:stop": { + this.dispatchEvent(new CustomEvent("stop", { + detail: message.data + })); + + 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.onRemoved.removeListener(this.onWindowsRemoved); + browser.windows.onFocusChanged.removeListener( + this.onWindowsFocusChanged); + + if (!this.wasReceiverSelected) { + this.dispatchEvent(new CustomEvent("cancelled")); + } + + // Cleanup + this.windowId = undefined; + this.messagePort = undefined; + this.receivers = undefined; + this.defaultMediaType = undefined; + this.availableMediaTypes = undefined; + 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); + + if (this.windowId) { + browser.windows.remove(this.windowId); + } + } + } } diff --git a/ext/src/background/receiverSelector/ReceiverSelectorManager.ts b/ext/src/background/receiverSelector/ReceiverSelectorManager.ts index 1f7c3f4..76f842d 100644 --- a/ext/src/background/receiverSelector/ReceiverSelectorManager.ts +++ b/ext/src/background/receiverSelector/ReceiverSelectorManager.ts @@ -8,26 +8,15 @@ import receiverDevices from "../receiverDevices"; import { getMediaTypesForPageUrl } from "../../lib/utils"; -import { ReceiverSelector - , ReceiverSelectorType } from "./"; import { ReceiverSelection , ReceiverSelectionActionType - , ReceiverSelectorMediaType } from "./ReceiverSelector"; + , ReceiverSelectorMediaType } from "./index"; -import NativeReceiverSelector from "./NativeReceiverSelector"; -import PopupReceiverSelector from "./PopupReceiverSelector"; +import ReceiverSelector from "./ReceiverSelector"; async function createSelector() { - const type = await options.get("receiverSelectorType"); - const platformInfo = await browser.runtime.getPlatformInfo(); - - if (platformInfo.os === "mac" - && type === ReceiverSelectorType.Native) { - return new NativeReceiverSelector(); - } - - return new PopupReceiverSelector(); + return new ReceiverSelector(); } diff --git a/ext/src/background/receiverSelector/index.ts b/ext/src/background/receiverSelector/index.ts index 4d6f912..0a9bc11 100644 --- a/ext/src/background/receiverSelector/index.ts +++ b/ext/src/background/receiverSelector/index.ts @@ -1,18 +1,31 @@ "use strict"; -import NativeReceiverSelector from "./NativeReceiverSelector"; -import PopupReceiverSelector from "./PopupReceiverSelector"; - - -export type ReceiverSelector = - NativeReceiverSelector - | PopupReceiverSelector; - export enum ReceiverSelectorType { Popup , Native } -export { ReceiverSelection - , ReceiverSelectionActionType - , ReceiverSelectorMediaType } from "./ReceiverSelector"; +export enum ReceiverSelectorMediaType { + App = 1 + , Tab = 2 + , Screen = 4 + , File = 8 +} + +export enum ReceiverSelectionActionType { + Cast = 1 + , Stop = 2 +} + +export interface ReceiverSelectionCast { + actionType: ReceiverSelectionActionType.Cast; + receiver: ReceiverDevice; + mediaType: ReceiverSelectorMediaType; + filePath?: string; +} +export interface ReceiverSelectionStop { + actionType: ReceiverSelectionActionType.Stop; + receiver: ReceiverDevice; +} + +export type ReceiverSelection = ReceiverSelectionCast | ReceiverSelectionStop; diff --git a/ext/src/defaultOptions.ts b/ext/src/defaultOptions.ts index 0e285ec..077b1d5 100644 --- a/ext/src/defaultOptions.ts +++ b/ext/src/defaultOptions.ts @@ -17,7 +17,6 @@ export default { , localMediaServerPort: 9555 , mirroringEnabled: false , mirroringAppId: MIRRORING_APP_ID - , receiverSelectorType: ReceiverSelectorType.Popup , receiverSelectorCloseIfFocusLost: true , receiverSelectorWaitForConnection: true , userAgentWhitelistEnabled: true diff --git a/ext/src/lib/options.ts b/ext/src/lib/options.ts index 9809196..5ad0369 100644 --- a/ext/src/lib/options.ts +++ b/ext/src/lib/options.ts @@ -26,7 +26,6 @@ export interface Options { localMediaServerPort: number; mirroringEnabled: boolean; mirroringAppId: string; - receiverSelectorType: ReceiverSelectorType; receiverSelectorCloseIfFocusLost: boolean; receiverSelectorWaitForConnection: boolean; userAgentWhitelistEnabled: boolean; diff --git a/ext/src/messaging.ts b/ext/src/messaging.ts index e3191f1..f5e3574 100644 --- a/ext/src/messaging.ts +++ b/ext/src/messaging.ts @@ -6,8 +6,7 @@ import { BridgeInfo } from "./lib/bridge"; import { ReceiverSelectorMediaType } from "./background/receiverSelector"; import { ReceiverSelection , ReceiverSelectionCast - , ReceiverSelectionStop } - from "./background/receiverSelector/ReceiverSelector"; + , ReceiverSelectionStop } from "./background/receiverSelector"; import { CastSessionCreated , CastSessionUpdated diff --git a/ext/src/ui/options/index.html b/ext/src/ui/options/index.html new file mode 100644 index 0000000..c7ef117 --- /dev/null +++ b/ext/src/ui/options/index.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + +
+ + diff --git a/ext/src/ui/options/index.tsx b/ext/src/ui/options/index.tsx index f255dcd..efdcc5d 100644 --- a/ext/src/ui/options/index.tsx +++ b/ext/src/ui/options/index.tsx @@ -14,8 +14,6 @@ import logger from "../../lib/logger"; import options, { Options } from "../../lib/options"; import { REMOTE_MATCH_PATTERN_REGEX } from "../../lib/utils"; -import { ReceiverSelectorType } from "../../background/receiverSelector"; - const _ = browser.i18n.getMessage; @@ -86,9 +84,6 @@ class OptionsApp extends Component< this.handleInputChange = this.handleInputChange.bind(this); this.handleWhitelistChange = this.handleWhitelistChange.bind(this); - this.handleReceiverSelectorTypeChange = - this.handleReceiverSelectorTypeChange.bind(this); - this.getWhitelistItemPatternError = this.getWhitelistItemPatternError.bind(this); } @@ -287,27 +282,6 @@ class OptionsApp extends Component< { _("optionsReceiverSelectorCategoryDescription") }

- { this.state.platform === "mac" && - } -